Pourquoi les jeux rechargent-ils apparemment tout le niveau lors du redémarrage d'un niveau?

47

Les données sont-elles vraiment modifiées pendant le jeu?

Je suppose que la pause la plus longue entre le redémarrage d'un niveau est le rechargement complet du niveau. Mais il me semble qu'un système bien implémenté devrait juste être capable de "cingler" jusqu'au début du niveau.

C'est plus visible sur les consoles, mais ce n'est pas imperceptible sur les jeux PC.

Engrener
la source
8
La réponse à cette question dépend beaucoup du jeu, des développeurs, de leurs habitudes et de leur expérience, ainsi que de nombreux autres facteurs. La seule réponse correcte au niveau général serait: parfois, il est beaucoup modifié, parfois pas, parfois des trucs sont importés et ainsi le début n’est plus en mémoire, et parfois les jeux font déjà un "ping" au début du niveau, et des jeux qui n'ont parfois pas de bonnes raisons pour lesquelles ils ne peuvent pas le faire et parfois c'est simplement parce que ce n'est pas assez bien implémenté.
Christian
4
De manière générale, il est beaucoup plus facile de recharger le niveau (ce qui place tout à son état initial) plutôt que d'annuler tout ce que le joueur a fait. C'est le cas dans mon expérience de toute façon.
Benjamin Danger Johnson
La question n'est pas en noir et blanc. Combien d'état est rechargé? De nombreux jeux rechargent des ensembles de textures entiers sans raison valable. Bien sûr, passer du niveau 5 au niveau 6 peut signifier charger de nouvelles textures, mais cela ne signifie pas que vous devriez le faire chaque fois que vous (re) commencez le niveau 6.
MSalters
@ MSalters Il s’agira principalement d’état du jeu plutôt que de ressources, vous n’aurez peut-être pas besoin de recharger un texte d’utilisation commun, mais plutôt l’ennemi que vous avez déjà tué - l’objet pour lequel il a été tué doit être détruit et rechargé si sa texture est toujours bien stockée dans la mémoire.)
Tom 'Blue' Piddock
Je pense que quelqu'un joue à Wing Commander III sur un système hérité.
Erik Reppen le

Réponses:

54

Eh bien maintenant - quelle question simple mais intéressante à aborder.

Lors du rechargement d'un niveau, il y a tellement de facteurs à prendre en compte que la réponse peut aller de plusieurs manières.

Si votre état de niveau contient une longue liste d'actifs, il peut être plus pratique de partir d'une page blanche lors du rechargement d'un niveau dans un état de sauvegarde / mission, car cela maintient l'état exact du niveau lors du rechargement mais ne prend pas beaucoup. de traitement. Cependant, il est plus efficace de ne réinitialiser que les actifs s'il n'y en a que quelques-uns à prendre en compte, afin de pouvoir redémarrer l'action rapidement à ces niveaux plus petits. C'est particulièrement le cas lorsque vous n'avez pas besoin de conserver quoi que ce soit dans la scène ou que vos choix de jeu ne vous affectent pas - si vous n'aviez pas besoin que des cadavres soient préservés dès votre première course dans un village, ils ne le seraient pas. doivent être rechargés sur votre chemin de retour à ce niveau, économisant ainsi le temps du processeur et le temps d'accès de l'état de sauvegarde / mission.

Un bon exemple à prendre en considération serait un tireur à la première personne utilisant des décalcomanies de destruction de terrain / de balles ayant un état persistant pendant la partie mais ne restant pas si vous redémarriez ce point de contrôle ou ce niveau .

Si vous deviez rembobiner le niveau au lieu de le détruire et de le recharger, il vous faudrait retracer chaque état modifié. Si vous tirez un trou dans le mur avec une fusée, vous générez des traces de terrain à partir des morceaux qui tombent du mur, le modèle du mur change pour produire le trou et vous obtenez des effets de particules qui ont été générés pour le rendre joli. . Pour nettoyer cela en le renvoyant à un état "redémarrable", vous devez:

  • Supprimez les gibs générés dynamiquement pour ce mur (mais pas ceux de l'état que vous avez chargé)
  • Supprimer l'effet de particules pour la poussière du trou de balle
  • Remplacez / réparez le mur pour éliminer les trous que vous avez créés
  • Réinitialiser les munitions du joueur
  • Etc...

Avec autant de ressources à suivre pour remonter un niveau, il est souvent moins gourmand en ressources informatiques de simplement détruire tout le niveau et de recharger à nouveau tous les actifs dans leurs états par défaut ou spécifiques à la mission. Devoir réinitialiser des objets spécifiques implique de rechercher une liste des objets dans la scène, puis d'accéder à leurs propriétés pour les réinitialiser. Au lieu de réparer ce trou de balle dans le mur en nettoyant, vous n'avez pas besoin de justifier des actions de nettoyage, supprimez simplement le niveau entier de la mémoire et rechargez-le à partir de zéro.

Cela signifie que le rechargement d'un niveau est effectué à partir d'un objet d'état (un fichier de sauvegarde ou un script de mission) et ne nécessite pas de calculs dynamiques. Pour les consoles, ceci est exacerbé par les temps de chargement des disques. Il aide également les jeux sur PC car il peut prendre en compte des ordinateurs qui n’ont pas la puissance de traitement nécessaire pour rendre les temps de chargement acceptables.

Donc, pour les niveaux de contenu importants - Charger un seul état au lieu de calculer et d'en "rembobiner" un:

  • Est moins gourmand en ressources processeur
  • Est plus efficace sur les machines de niveau inférieur
  • Permet à un script de mission et à un fichier de sauvegarde d'être utilisés de la même manière (utilisez éventuellement le même système de chargement pour charger un état de sauvegarde ou un état de point de contrôle de mission lors du redémarrage du niveau)
  • Cela signifie que vous avez moins de travail en tant que développeur pour réinitialiser un niveau - Il est beaucoup plus facile de programmer un rechargement complet à partir de données de session que de suivre et de revenir en arrière. C'est probablement le point le plus influent

Cependant, à titre d’exemple contraire, un jeu de combat (le grand exemple réel de la vie étant Street Fighter 4) peut ne pas nécessiter de recharger autant d’actifs pour pouvoir relancer un niveau. Les 2 joueurs, l’état de l’environnement pour le niveau et les niveaux simples sont généralement statiques et non dynamiques (la santé des joueurs réapparaîtra à 100% à chaque tour, les chronomètres sont réinitialisés à 90 secondes et le niveau n’a pas de trous [ou le fait!] ) et donc rétablir le niveau consiste à remettre les combattants en pleine santé et à remettre l'environnement dans ses positions initiales (comme les spectateurs à certains niveaux).

Donc, pour un jeu de combat lors d'une revanche, vous ne devez pas aller d'un round à l'autre:

  • Réinitialiser Santé et énergie sur Max ou valeurs par défaut (toujours les mêmes par caractère)
  • Réinitialiser la minuterie
  • Réinitialiser les positions de départ du personnage
  • Réinitialiser le terrain à l'état par défaut (aucun problème de balle à réparer ou à recharger!)

Et c’est essentiellement la totalité de la liste, ce qui signifie qu’une réinitialisation rapide de l’état au lieu d’un rechargement complet est plus réalisable. Cela peut également être indiqué par le temps de chargement lorsque vous démarrez le match pour la première fois. Il faut beaucoup de temps pour charger tous les modèles de personnages et de niveaux, mais seuls quelques tics de processeur permettent de réinitialiser les positions de départ des personnages entre les correspondances avec un modèle déjà chargé.

Il est important de noter qu'il s'agit également d'une exigence plus fréquente des jeux de combat, car leurs joueurs ont tendance à vouloir revenir dans l'action incroyablement rapidement, car les matches ne durent généralement qu'une minute - soulignant que cette réponse dépend beaucoup du jeu. et genre. Les FPS exigent des ressources plus dynamiques tandis que les combattants demandent des actions rapides et répétables.

J'espère que cela a permis de mieux comprendre votre question.

Tom 'Blue' Piddock
la source
7
Excellente réponse ... mon côté cynique mettrait votre: "moins de travail pour les développeurs" en haut de la liste ... mais peut-être que la mise en oeuvre du moteur pourrait être meilleure.
Mesh
3
Aussi, qu'en est-il de la récupération de bogues? Un NPC ne bouge pas à cause d'un bogue dans le système physique, d'une fuite de mémoire, etc. Même si le jeu est minutieusement testé, de telles choses se produisent et il doit y avoir un moyen de réinitialiser le jeu dans un état connu et opérationnel.
Sulthan
9
Moins de travail est un objectif enviable à atteindre, pas un sujet de honte. Vous pourriez passer une semaine à construire un système de rembobinage et un mois à éliminer tous les bugs, ou à recharger et à accéder à d'autres fonctionnalités =)
Patrick Hughes
1
Je pense que le coût est l'argument le plus important ici. À moins que le rechargement d'un niveau ne se produise souvent et devienne un inconvénient majeur pour l'utilisateur, rien ne l'incite à écrire du code optimisé pour accélérer le rechargement. Cela coûte moins cher de réutiliser le code pour une charge normale.
Orlp
1
+1 Je veux juste préciser que le rechargement d'un niveau et le chargement d'un niveau - si le rechargement lance tout et commence par un nouveau chargement - ne nécessite aucun nouveau code à écrire pour atteindre l'objectif du jeu. Un système de rembobinage est un ensemble de code entièrement nouveau qui n’est pas trivial et qui dépend d’un état variable, il est extrêmement difficile à déboguer. Exemple: "Correction du bug: Le redémarrage d'un niveau après la chute d'un casque au dessus d'une bombe après l'explosion d'un missile à moins de 200 pixels d'eau ne provoque plus un crash du bureau." En bref, vous auriez une VRAIMENT bonne raison de vous embêter.
BrianH
14

Pour clarifier les réponses existantes par rapport à votre question sur les consoles: elles n’ont pas assez de mémoire pour stocker à la fois l’état de départ et l’état actuel pour les jeux plus complexes.

Un jeu peut stocker le niveau et l’état initial séparément, de sorte que seul l’État puisse être redéfini, et c’est très probablement ce que font de nombreux jeux. Cependant, même le streaming sera un peu plus lent que s'il avait été gardé en mémoire.

La "meilleure" console actuelle ne dispose que de 512 Mo de mémoire partagée entre les données de la CPU et les graphiques. C'est minuscule. L’un des casse-tête actuels du développement de la console consiste à essayer d’intégrer des jeux qui répondent aux niveaux de qualité actuels avec une telle quantité de mémoire. Le comptage en kilo-octets peut devenir important, en particulier à l'approche de la date d'expédition. Stocker une copie de l'état initial d'un niveau est une quantité de données qui pourrait être utilisée sans ressources, permettant à plus de mémoire d'être utilisée pour des choses qui rendent le jeu plus intéressant pendant le jeu plutôt que de simplement accélérer le rechargement de niveaux.

Dans l’idéal, le joueur passe plus de temps à jouer qu’à mourir et à redémarrer, il est donc plus judicieux d’optimiser pour une meilleure expérience de jeu.

Les choses pourraient changer radicalement avec les consoles de nouvelle génération et leurs 8 Go de mémoire. Ils peuvent également rester les mêmes, avec simplement des modèles et des matériaux de résolution supérieure et un grand nombre d’objets actifs dans le jeu. Le temps nous le dira. Étant donné que les jeux sur PC ciblent généralement des machines dotées de 2 Go de RAM et de 512 Mo de mémoire VRAM (bien que de nombreuses valeurs atteignent des valeurs bien plus grandes), les 8 Go des nouvelles consoles sont assez luxueux en ce qui concerne les lignes de base minimales. Nous verrons probablement une transition vers des jeux nécessitant un processeur / système d'exploitation 64 bits et 4 à 8 Go de RAM avec 1 à 2 Go de mémoire VRAM dans les années à venir. Stocker plusieurs états en mémoire pour une prise de vue rapide devrait alors être beaucoup plus facile.

Sean Middleditch
la source
+1 Des informations fantastiques et une bonne explication sur la raison pour laquelle les consoles ralentissent considérablement le rechargement.
Tom 'Blue' Piddock le
7

Je suis en désaccord avec une grande partie de la réponse de Blue. Je ne crois pas qu'il existe un argument technique pour ne pas réinitialiser les niveaux - je ne l'ai certainement jamais rencontré. Le chargement de niveau est presque toujours plus lent que la réinitialisation de niveau. En fait, je trouve difficile de concevoir une occasion où ce ne serait pas le cas. Dans la plupart des cas, les jeux pourraient offrir un chargement de niveau instantané efficace si les développeurs le voulaient.

La vraie réponse est, comme suggéré, c'est plus facile et plus rapide. Le chargement répété de niveaux est de toute façon nécessaire à un jeu. Il est donc relativement simple de le réutiliser pour un redémarrage de niveau. La réinitialisation nécessite de nouvelles voies complexes avec un fort potentiel de nouvelles anomalies et de fuites de mémoire, ainsi qu'un investissement décent en temps de développement. Dans certains cas, cela peut également repousser les limites de la mémoire. Étant donné que les jeux sont rarement développés avec une surabondance de temps de développement, des éléments tels que la réinitialisation de niveau ont une tendance regrettable à être abandonnés en cours de route, en particulier si l’architecture du jeu n’est pas la meilleure qui soit.

Bien que je suppose que l'on puisse arriver à une situation dans laquelle le "rembobinage" était nécessaire pour réinitialiser, la plupart des jeux n'ont en fait besoin que de stocker l'état d'origine, de fournir un moyen efficace de réinitialiser complètement cet état pour les objets conservés et de marquer les objets abandonner à la réinitialisation. Les informations sur l'état du jeu doivent également être stockées et restaurables. Ce type d’information est généralement relativement léger en mémoire par rapport aux exigences d’un niveau entier, ce qui évite le chargement lent et coûteux des données à partir du disque (y compris les gros éléments tels que les textures et les modèles) et le remplace par une -Passe mémoire de la scène.

Jack Aidley
la source
3
Vous voudrez peut-être consulter la réponse de Sean pour un exemple de cas technique dans lequel vous voudrez peut-être recharger un niveau avant de le "réinitialiser"
SpartanDonut
2

Pour permettre des niveaux de jeu élevés ou homogènes, même avec une mémoire limitée (la mémoire est toujours trop petite, la question est de savoir si vous atteignez d'abord la limite en RAM ou sur la carte graphique), il existe une autre stratégie:

N'a que la partie du niveau en mémoire, dont le joueur a besoin ou aura besoin dans quelques secondes. Les modèles, les textures, les échantillons sonores, ... qui ne sont probablement plus nécessaires sont supprimés de la mémoire.

On pense à Dungeon Siege (les développeurs affirmaient autrefois que la gestion de la mémoire prenait plus de puissance de traitement que le jeu réel), la plupart des MMORPGS le font, les tireurs avec un environnement ouvert doivent le faire, ... Dans ces cas, le début de la level (ou même un point de respawn il y a 30 secondes) pourrait ne plus être (complètement) en mémoire.

Une nouvelle recharge est souvent le moyen le plus simple, le moins cher et peut-être le plus rapide.

Edit: Voici un article sur les mécanismes de chargement de Dungeon Siege: Le monde continu du siège de donjon

linac
la source
Bon point, je n'ai pas pensé aux niveaux continus ou sans soudure. Cela nécessiterait un système de chargement de niveau complètement différent.
Tom 'Blue' Piddock le
2

Avec les excellentes réponses de Sean et Blue concernant les limitations de la plate-forme physique et les décisions favorables, je vais développer un commentaire dans une approche différente:

Pourquoi devriez-vous simplement recharger complètement le niveau

Donc, votre appel de loadLevel () fonctionne parfaitement, yay! Vous diffusez dans un fichier de niveau des informations et vous construisez un monde basé sur celui-ci, en créant des objets et en chargeant des textures et des sons au fur et à mesure. Ensuite, lorsque tout est terminé - ou que vous avez "suffisamment" de laisser la lecture commencer, vous appelez startPlay (), votre monde est révélé et votre musique commence à jouer.

Maintenant, lorsque vous avez terminé avec le niveau, ou que vous vous échappez dans le menu, ou quittez le jeu, vous appelez unloadLevel () pour libérer toutes les ressources et la mémoire que vous avez conservées afin de permettre une expérience fluide.

Maintenant, que se passe-t-il lorsque vous souhaitez ajouter une fonctionnalité "Niveau de redémarrage"? Bien...

unloadLevel(currentLevel);
loadLevel(currentLevel);
startPlay();

Et vous avez terminé! Pas de nouveau code, juste quelques appels de fonction simples au plus, et vous avez déjà écrit et débogué tout cela. Votre nouvelle fonction de redémarrage est rayée de votre liste et ne sera probablement plus jamais retrouvée - code cruel et sans rouille est le meilleur genre! Déplacez le code dans une fonction restartCurrentLevel () et vous pouvez le plier et ne plus le regarder - peut-être après vous être assuré qu'il existe un niveau pour redémarrer, bien sûr :)

Mais vous vous demandez alors s'il ne s'agit pas d'un gaspillage, de décharger des choses que vous êtes sur le point de recharger de toute façon. Eh bien, si vos niveaux et vos ressources sont réduits, vous ne gagnerez au maximum que quelques secondes de temps de chargement à chaque fois que "Redémarrer" est appelé, même sur des systèmes lents (et peut-être même des smartphones plus anciens). "Optimisation prématurée", vous avez mieux à faire avec votre temps.

Mais maintenant, vos niveaux augmentent et vos textures sont de plus en plus détaillées et la bande son est déchirée à 512kbps avec des canaux séparés pour chaque voix et couche musicale (cela semblait une bonne idée à l'époque, bien que vous ne puissiez pas vous souvenir pourquoi. ..) et quelque chose à propos de "matrices de transformée de Fourier multidimensionnelles dépendant du traçage du rayon voxel dépendant de l’état" qui, selon vous, est totalement inventé et non réel, et le chargement de niveau prend un certain temps maintenant et commence à vous ennuyer. Vous avez même testé avec de vraies personnes et elles affichent un dégoût pour les temps d'attente car c'est pire que des jeux similaires (vous ne vous attendez pas à une capitale de MMORPG avec 100 joueurs à charger complètement en moins de 2 secondes, n'est-ce pas?), et c'est un problème.

Alors, comment optimisez-vous? Eh bien, si le rechargement de niveau pose un problème, le chargement de niveau ne pose-t-il pas un problème? Si vous pensez que c'est juste un rechargement, pourquoi diable les gens rechargent-ils votre niveau beaucoup plus souvent qu'ils ne le chargent au départ? Cela ressemble à un problème de jeu, pas à un problème d'ingénierie de code. Qui pense que c'est amusant de recharger un niveau encore et encore, et souhaite juste que ce soit plus rapide au lieu d'être entièrement évitable ?

Fixez le vrai problème en premier!

Mais disons que votre jeu est conçu pour vous permettre de redémarrer au moins de temps en temps, et le temps de chargement est suffisamment long pour que vous puissiez le faire une fois et absolument inévitable, mais vous ne voulez pas avoir à le refaire. Quel genre de jeu est-ce, de toute façon? Cela semble être un problème un peu étrange ... Peut-être un jeu haute résolution semblable à un portail où il est supposé que vous allez gâcher le puzzle à plusieurs reprises?

Tout d'abord, vous devez réaliser que cela ne va pas être trivial. Vous allez devoir écrire du code entièrement nouveau, non testé, et il est "dépendant de l'état" afin que vous ne sachiez même pas ce qui est réutilisé ou non entre les jeux de niveaux. Y a-t-il des éléments aléatoires, des spawns, des textures variables (vos squelettes ne portent-ils parfois qu'une armure?) Ou d'autres éléments changeants de votre niveau? Y a-t-il des choses qui varient avec le joueur, comme une tenue ou un modèle personnalisé ou des couleurs / portes / pièges?

Vous allez faire des comparaisons, et beaucoup d'entre elles. Vous allez parcourir les éléments de niveau, en comparant ce qui sera nécessaire par rapport à ce qui est chargé en ce moment (que faites-vous avec des éléments chargés pour le dernier niveau mais pas pour celui-ci - relâchez-les ou conservez-les pour éviter un avenir charge?). Si c'est vraiment un gros problème pour votre jeu, vous allez probablement vouloir changer votre code de chargement / déchargement pour voir si quelque chose est déjà chargé avant de le charger (ce qui le rend polyvalent mais introduit potentiellement de nouveaux bogues dans des fonctions et fonctions qui fonctionnaient auparavant. libérer soigneusement les ressources qui ne seront pas utilisées dans un avenir proche). Soupir.

Quoi que vous fassiez, même si votre jeu est simple, vous allez tomber dans des bugs obscurs qui sont basés sur le niveau / l'état du joueur lors du redémarrage d'un niveau qui ne vous arrive pas, chargez le niveau la première fois. Vous pouvez donc écrire des mises à jour du jeu avec du texte comme:

"Laisser tomber un casque sur une bombe sur une tuile sur laquelle un missile a explosé près de celle-ci et qui se trouvait également à moins de 200 pixels d’eau n’altérera plus vos données de jeu ni ne provoquera le crash de celui-ci."

La vraie raison la plupart des jeux ne vous dérange pas

Avez-vous déjà remarqué que la plupart des gens peignent ou appliquent une cloison sèche sur leurs murs existants au lieu de se décoller pour former une couche de base ou de poser un tapis directement sur le plancher de bois franc au lieu de le tirer vers le haut?

Le fait est que tout est plus de travail pour une récompense minimale. Peindre sur vos murs existants fonctionne bien la plupart du temps , et la valeur de déchirer des planchers de bois franc est souvent minime, voire inexistante.

Il en va de même pour les logiciels, des jeux aux présentations multimédia Power Point. Si tout ce que vous faites est de passer quelques secondes sur un écran de chargement, les gens passent 1% de leur temps à regarder. un très mauvais retour sur votre temps investi.

Et donc la plupart des jeux ne dérangent pas, et j'ai du mal à penser à de très nombreux jeux où le chargement d'écrans rendait un bon jeu autrement moins intéressant, à l'exception de quelques exemples extrêmes; les exemples extrêmes sont ceux où l'optimisation pour un chargement de niveau plus rapide a du sens, et c'est une fraction minuscule de jeux accessible au public, et probablement même une fraction plus petite de jeux que personne ne voit jamais car ils ne sont jamais sortis.

BrianH
la source
0

Parce qu'il est plus difficile de développer le comportement opposé qui consiste à garder en mémoire les données de jeu statiques (telles que les textures, les informations géologiques, les monstres non affectés) et à ne recharger que les données dynamiques (telles que la position du joueur, les statistiques du joueur, le statut de la quête, l'inventaire). .

Comme cela coûte plus d’argent et de temps, les développeurs de jeux ne le font généralement pas.

Xtro
la source
Cela ne couvre pas les situations dans lesquelles le contraire doit se produire en raison du genre de jeu ou des demandes individuelles. Comme Prince of Persia devant enregistrer l’état du jeu pour pouvoir utiliser un mécanisme de jeu particulier et les exemples de jeu de combat que j’ai donnés, qui doivent pouvoir recharger des états d'objet / niveau / personnage individuels afin de pouvoir effectuer une réinitialisation à mi-parcours d'un match. au prochain tour ou recommencez le match pour commencer le prochain match. Celles-ci sont nécessaires pour répondre aux exigences du jeu. Il est donc nécessaire que les développeurs de jeux dépensent plus de temps et d’argent.
Tom 'Blue' Piddock
Si l'inverse se produit dans un jeu spécifique, la question ci-dessus n'est pas valide pour ce jeu. Parce que le temps de chargement sera rapide dans le jeu dans lequel le contraire se produit. Je viens de répondre à la question à laquelle elle s'applique (qui est le jeu qui charge tout le niveau à partir de zéro)
Xtro
Si le contraire se produit là où la prémisse de la question aurait pu se poser, il est toujours utile de la noter et pourquoi. Omettre des informations ou omettre des détails sur les raisons pour lesquelles une situation ou une solution a été créée n'est jamais bénéfique. Dire qu'il n'y a pas besoin de détail est un peu contre-intuitif, car il ne serait pas question en premier lieu si la personne ne cherchait pas le détail. Si vous êtes en mesure de fournir plus de détails, efforcez-vous toujours de le faire, car cela aide les autres à en apprendre davantage sur un sujet dans son ensemble et à répondre aux besoins les plus pressants.
Tom 'Blue' Piddock
alors, votre réaction est pour ma première ligne de réponse qui parle de "pas besoin de détails", non? si je supprime cette ligne, prendriez-vous -1 point en arrière?
Xtro
Curieusement, oui. Ne découragez jamais les détails où il est possible de les donner et vous constaterez généralement que vos réponses sont beaucoup mieux appréciées.
Tom 'Blue' Piddock