Serveur minecraft

Memory Matters: Une édition spéciale en RAM de Dirty Coding Tricks – Monter un serveur MineCraft

Le 13 juin 2019 - 16 minutes de lecture

Les contraintes de mémoire sont une chose du passé, non?

Il s'avère qu'ils ne le sont pas. Non seulement de nombreux moteurs disponibles dans le commerce gèrent mal la mémoire, mais de nombreuses plates-formes ont encore des besoins en mémoire assez ambitieux. Il existe également des limitations de taille basées sur les disques et les cartouches.

Nous avons ici une foule d'histoires de l'industrie (et des années / plates-formes) sur des méthodes moins que justes utilisées pour ajuster les niveaux, les textures et les jeux entiers dans leurs espaces requis. Ils ne sont peut-être pas jolis, mais ils ont des jeux expédiés, et personne n'était le plus sage… Jusqu'à présent.

Et si ces histoires vous plaisent, prenez le temps de consulter notre article du mois dernier dans lequel plusieurs de vos collègues développeurs de jeux ont partagé les astuces de codage les plus mémorables qui les ont aidés à sortir les jeux de la porte.

Le jeu en question (un jeu de tir à la première personne) avait des problèmes de déchargement des niveaux proprement sur Xbox; une partie de la mémoire ne peut pas être récupérée, donc après avoir terminé un niveau et passé au suivant, le jeu se bloque toujours. La Xbox avait une mémoire très limitée et, contrairement au PC, lorsqu'un programme manque de mémoire, il ne dispose pas d'une mémoire de stockage lente, cachée, supplémentaire à utiliser en tant que sauvegarde. C'est la mort immédiate.

L’équipe a en fait remarqué cela très tard, car elle avait la capacité de lancer directement le jeu dans un niveau. C’était une fonctionnalité de l’éditeur de jeu qui permettait aux programmeurs et aux concepteurs d’intervenir directement dans le niveau sur lequel ils travaillaient, en contournant le menu principal et les missions précédentes. C’est une caractéristique vitale des jeux en développement, si répandue que je n’ai jamais vu un jeu sans lui (même s’il est souvent vidé avant l’envoi).

"Lorsque vous terminez un niveau, le jeu redémarre la console et se redémarre avec un argument de ligne de commande (le nom du niveau à démarrer). Bien sûr, un redémarrage signifie un écran noir pendant un certain temps, un écran de fondu a donc été implémenté rapidement pour passer au noir. "

En conséquence, tout le monde a démarré le jeu directement depuis l'éditeur en passant à un niveau de commodité. À l'exception bien sûr de ceux qui développent le menu, mais ils ne feraient que démarrer le menu principal et ne jamais entrer dans un niveau. Ainsi, la plupart des développeurs participant au projet n'étaient pas immédiatement conscients du fait que les niveaux ne pouvaient pas être nettoyés rapidement.

Lorsque QA a découvert cela, il était devenu un véritable défi de nettoyer toutes les fuites à la fin du projet. Les premières fuites étaient faciles à trouver, mais il devenait de plus en plus difficile de traquer et de récupérer chaque petit morceau de mémoire avant de commencer un nouveau niveau. Après quelques travaux, on pouvait commencer 4-5 niveaux de suite, mais la console finirait par planter. Il n'était pas possible de jouer à la campagne d'un coup.

L'équipe n'a pas réussi à tout réparer à temps. Ou peut-être ont-ils abandonné assez tôt, je ne suis pas sûr … Mais ils ont utilisé leur fonctionnalité de développement et une belle API qui existait sur la Xbox. Il était alors possible (et il est encore possible sur la Xbox 360) de demander à la console de se redémarrer. Et il est possible de dire à la Xbox quoi faire une fois le redémarrage terminé.

Il était donc possible de demander à la console de redémarrer et de redémarrer le même jeu, avec un paramètre. Ainsi, le démarrage rapide des niveaux a été déplacé de l'éditeur au jeu lui-même. Lorsque vous terminez un niveau, le jeu redémarre la console et se redémarre avec un argument de ligne de commande (le nom du niveau à démarrer). Bien sûr, un redémarrage signifie un écran noir pendant un moment. Un écran de fondu a donc été implémenté rapidement pour passer au noir. La console redémarrera et passera au niveau suivant, comme le ferait l'éditeur de jeu, puis passera au niveau suivant. Voilà, le moyen (?) Idéal pour effacer toute la mémoire entre les niveaux.

Nicolas Mercier

RAM et crash

J'étais l'un des deux programmeurs (avec Andy Gavin) qui a écrit Crash Bandicoot pour la PlayStation 1.

La RAM était toujours un problème majeur, même à ce moment-là. La PS1 disposait de 2 Mo de RAM et nous devions faire des choses folles pour que le jeu s'adapte. Nous avions des niveaux avec plus de 10 Mo de données, et cela devait être repéré et renvoyé de manière dynamique, sans aucun «accrochage» – des retards de chargement où la fréquence d'images tomberait en dessous de 30 Hz.

Cela a fonctionné principalement parce qu'Andy a écrit un système de pagination incroyable qui échangerait des pages de données de 64K lorsque Crash traverserait le niveau. Il s’agit d’un tour de force "full stack", dans la mesure où il va de la gestion de la mémoire de haut niveau au codage DMA de niveau opcode. Andy a même contrôlé la disposition physique des octets sur le disque CD-ROM de sorte que, même à 300 Ko / s, la PS1 puisse charger les données de chaque élément d'un niveau donné avant que Crash ne s'y rende.

J'ai écrit l'outil d'emballage qui prenait les ressources — sons, art, code de contrôle lisp pour créatures, etc. — et les ai emballées dans des pages de 64 Ko pour le système d'Andy. (Incidemment, ce problème – produire l'emballage idéal dans des pages de taille fixe d'un ensemble d'objets de taille arbitraire – est NP-complet et donc probablement impossible à résoudre de manière optimale dans un polynôme, c'est-à-dire un temps raisonnable.)

Certains niveaux correspondaient à peine et mon conditionneur a utilisé divers algorithmes (premier ajustement, meilleur ajustement, etc.) pour essayer de trouver le meilleur emballage, y compris une recherche stochastique semblable au processus de descente de gradient utilisé dans le recuit simulé. Essentiellement, j’avais toute une série de stratégies d’emballage différentes, et je les essayais toutes pour obtenir le meilleur résultat.

Le problème avec l'utilisation d'une telle recherche guidée aléatoire, cependant, est que vous ne savez jamais si vous obtiendrez à nouveau le même résultat. Certains niveaux d’accident ne correspondent au nombre maximum de pages autorisé (je pense qu’il s’agissait de 21) uniquement en raison du fait que le packer stochastique "a de la chance". Cela signifiait qu'une fois que vous aviez le niveau emballé, vous pourriez changer le code d'une tortue et ne plus jamais être capable de retrouver un emballage de 21 pages.

Il arrivait parfois que l'un des artistes souhaitait changer quelque chose et que le décompte des pages fût annulé. Nous devions changer d'autres choses de manière semi-aléatoire jusqu'à ce que le conditionneur ait à nouveau trouvé un emballage qui fonctionnait. Essayez d'expliquer cela à un artiste crabby à 3 heures du matin.

De loin, la meilleure partie de la rétrospective – et la pire de l'époque – consistait à intégrer le code de base de l'assemblage C /. Nous étions littéralement à quelques jours de la date butoir pour le "maître d'or" – notre dernière chance de faire la saison des vacances avant de perdre toute l'année – et nous permutions au hasard le code C en des manifestations sémantiquement identiques mais syntaxiquement différentes pour obtenir le résultat souhaité. compilateur pour produire un code 200, 125, 50, puis 8 octets plus petit. Permuting as in, "for (i = 0; i <x; i ++)" – que se passera-t-il si nous réécrivions cela en tant que boucle while en utilisant une variable que nous avons déjà utilisée ci-dessus pour autre chose? C’est après que nous ayons déjà épuisé les astuces habituelles, par exemple insérer des données dans les deux bits inférieurs des pointeurs (ce qui ne fonctionne que parce que toutes les adresses de la R3000 étaient alignées sur 4 octets).

En fin de compte crash tenir dans la mémoire de la PS1 avec 4 octets à revendre. Oui, 4 octets sur 2097152. Bons moments.

– Dave Baggett
inky.com (et employé n ° 1 de Naughty Dog)
[Originally posted here!]

Un oeil pour le détail

C'est arrivé comme il y a 10 ans. À cette époque, je travaillais dans un petit studio, sur un jeu RTS expédié exclusivement sur PC. C'était une équipe de taille moyenne (environ 35 personnes) pour environ un an et demi de production.

Ce RTS était basé sur les niveaux: chaque fois que vous atteigniez un niveau, il ouvrait le suivant, et ainsi de suite. Comme pour tout jeu PC, il était conçu pour fonctionner sur plusieurs types de configuration. Nous avons donc livré le jeu avec 3 jeux de textures de résolutions différentes: basse, moyenne et haute.

Ainsi, chaque niveau est accompagné de deux packs de texture supplémentaires, un pour les textures de résolution moyenne et un autre pour les textures haute résolution (les basses sont directement conditionnées dans le fichier principal bigfile).

"Les voix enregistrées en allemand durent plus longtemps et occupent plus d'espace disque que les autres langues. Tous nos budgets ont été établis avec d'autres langues à l'esprit. Nous avons maintenant environ 10 heures pour résoudre le problème."

La production s'est bien déroulée et la clôture du jeu était presque terminée. Les performances étaient bonnes, la stabilité était là, la plupart des bugs étaient corrigés. Puis vient le dernier jour avant la date limite. Nous devons graver nos derniers CD d'or pour chaque SKU afin de les envoyer à l'usine le lendemain matin.

Nous avons donc commencé par construire ISO et à brûler l'anglais, le français et l'espagnol, puis à les tester. Tout se passait bien. Et puis vient le SKU allemand! Nous avons commencé à construire l'ISO et "Cette image ne tient pas sur le support" est apparu à l'écran.

Quoi? Comment est-ce possible? Nous venons de graver 3 autres références, et il est maintenant 20 heures. Les CD doivent être envoyés à 7h le lendemain. En regardant de plus près le problème, il arrive que les voix enregistrées en allemand durent plus longtemps et prennent plus d’espace disque que d’autres langues. Tous nos budgets ont été établis avec d'autres langues à l'esprit. Nous avons maintenant environ 10 heures pour résoudre le problème, graver ce CD et le tester pour vous assurer qu'il fonctionne réellement. Vous n'avez pas le temps de recompresser l'audio ou de faire d'autres modifications astucieuses pour économiser de l'espace disque.

Nous avons ensuite eu une idée brillante: choisissez l’un de nos niveaux, supprimez le pack de textures haute résolution et remplacez-le par une copie du pack de textures moyennes. BAM, 50 Mo sauvegardés: le format ISO convient au CD. Ainsi, nos amis allemands dotés de PC puissants ont joué l'un de nos niveaux avec les mêmes détails de texture que celui avec une configuration moyenne! Je peux vous dire que ce fut une nuit très longue et stressante!

– Rémi Quenin
Architecte de moteur,
En être loin

Ce n’est pas la taille …

Nous travaillions sur la conformité d'un titre XBLA téléchargeable en 2008. À l'époque, les disques durs étaient optionnels sur la 360; les titres téléchargeables devaient donc fonctionner lorsqu'ils étaient lancés à partir de cartes mémoire. Ce jeu en particulier était assez petit, avec une capacité d’environ 240 Mo. Nous avons donc dû tester le produit sur les cartes mémoire de 256 Mo et 512 Mo.

Le jeu a bien démarré avec la carte de 512 Mo, mais nous obtenions des blocages système incohérents périodiques lorsque nous essayions de nous lancer avec la carte de 256 Mo. Nous nous sommes mal à la tête, mais nous avons finalement décidé que nos efforts de codage seraient mieux dépensés pour rendre le jeu aussi bon que possible au lieu de pourchasser un fantôme dans la machine.

Nous avons donc inséré un fichier de musique de 20 Mo dans les données du jeu, poussant la taille totale du fichier au-delà de 260 Mo. Cela nous a totalement évité d’impliquer la carte mémoire de 256 Mo dans le processus de soumission. C'était un bon jeu que nous avons livré à temps. Microsoft et nos clients n'étaient pas les plus sages.

– Anonyme

Des tas de douleur

Dans un port de jeu d'action bien connu, allant de PC à PS2, nous avons eu beaucoup de plaisir à installer un jeu de 256 Mo très dynamique en allocation dynamique pour 32 Mo – même après de nombreuses optimisations et l'ajout de la diffusion en continu de niveaux. Il était encore surdimensionné, alors:

  • La machine de construction chargerait un niveau depuis le démarrage et suivrait chaque allocation, et verrait ceux qui restaient jusqu'au niveau – la nouvelle exécution du jeu utiliserait ensuite cette séquence pour allouer linéairement chaque allocation permanente, et heap / temp allouer le reste. Cela a permis d'économiser environ 15% (environ 5 Mo) de mémoire, d'alléger considérablement l'allocation et de réduire considérablement la fragmentation, mais il restait trop de fragmentation après environ 3 niveaux.
  • La machine de compilation a eu une seconde étape: redémarrez, chargez le niveau (avec les optimisations de (a)), puis dumpez le tas entier au niveau début. Le jeu livré vient alors de charger ces images de mémoire directement au-dessus du tas (après avoir temporairement stocké les paramètres du profil local sur la pile) à chaque niveau de chargement.

Résultat: charge de niveau très rapide et zéro fragmentation au début de chaque niveau, au prix de temps de construction plus longs pour chaque version candidate.

– Anonyme

Mienfourrer

Tout au long du développement de Minecraft Pour 3DS, nous manquions de mémoire, même sur le plus puissant Nouveau 3DS. Nous voulions donc jouer avec certains des formats de texture pris en charge par 3DS. Le format de texture interne de la 3DS est étrange. Il est basé sur des tuiles, organisé en zig-zag de motifs en zig-zag, mais ensuite organisé de manière linéaire au plus haut niveau.

Malheureusement, personne dans l'équipe n'était suffisamment familiarisé avec les formats compressés pour écrire un utilitaire de conversion. Un autre programmeur, Ian, avait déjà écrit un convertisseur de texture pour Collection Mega Man Legacy, mais il s’agissait plus de données de pixels non compressées.

Son propre convertisseur de texture prenait un fichier .png et crachait un fichier ".3dst" avec un format personnalisé qu'il avait inventé – il s'agissait essentiellement d'un en-tête minimal et de données brutes que nous pouvions simplement mettre en mémoire, prêts à l'emploi ("3dst" signifie pour "3DS Texture" – assez malin, hein?).

Nintendo fournissait son propre utilitaire de conversion, mais exportait uniquement les images dans un fichier "package" que vous deviez utiliser la bibliothèque de Nintendo pour analyser et charger au moment de l'exécution. C'était trop de frais généraux pour nous. Malheureusement, encore une fois, ce format de fichier n’était pas documenté par Nintendo, ce qui semblait être le seul moyen d’obtenir des images compressées dans le format attendu par la 3DS.

J'ai donc décidé de me salir les mains dans un éditeur hexadécimal. J'ai fourni à l'utilitaire Nintendo diverses images de différentes tailles et formats et pris note de ce qui avait changé dans l'en-tête de leurs fichiers jusqu'à ce que j'aie identifié suffisamment de champs pour extraire les données dont j'avais besoin. J'ai créé un utilitaire rapide permettant d'extraire les données brutes des fichiers de package de Nintendo, puis de mettre en place un script batch permettant d'appliquer ce processus aux textures dont nous avions besoin. Ce n'était pas rapide, et ce n'était certainement pas élégant, mais cela a fonctionné.

– Keith Kaisershot
Programmeur, Eclipse numérique

Vous le préparez

Lorsque vous travaillez sur un pilote 3D pour la plateforme d'infusion, le tas était contenu dans la section de données de l'exécutable. C'était un format exécutable semblable à un elfe appelé mod, et il contenait une énorme quantité de 0 où l'application allouait de la mémoire une fois chargée en mémoire.

En conséquence, nous manquions régulièrement de mémoire vive et plutôt que de gérer correctement la mémoire (les ressources étaient très limitées sur cette plate-forme), j'ai décidé d'écrire un outil pour insérer davantage de zéros et corriger le fichier .exe à la place. Cela a fonctionné comme une gâterie et je ne me sens même pas mal parce que c’était une plate-forme terrible et un format exécutable terrible.

– Andrew Haining

Commentaires

Laisser un commentaire

Votre commentaire sera révisé par les administrateurs si besoin.