¿Por qué los juegos aparentemente recargan todo el nivel al reiniciar un nivel?

47

¿Los datos realmente se modifican tanto durante el juego?

Supongo que la pausa larga entre reiniciar un nivel es la recarga completa del nivel. Pero me parece que un sistema bien implementado debería ser capaz de 'hacer ping' al inicio del nivel.

Es más notable en las consolas, pero no es imperceptible en los juegos de PC.

Malla
fuente
8
La respuesta a eso depende mucho del juego, de los desarrolladores, sus hábitos y experiencia y muchos más factores. La única respuesta correcta en un nivel general sería: a veces se modifica mucho, a veces no, a veces las cosas se transmiten y, por lo tanto, el comienzo ya no está en la memoria, y a veces los juegos ya hacen "ping" al inicio del nivel, y juegos que a veces no tienen buenas razones por las que no pueden hacerlo y a veces es solo porque no se implementa lo suficientemente bien.
Christian
44
En términos generales, es mucho más fácil recargar el nivel (que pone todo en su estado inicial) en lugar de deshacer todo lo que hizo el jugador. Ese es el caso en mi experiencia de todos modos.
Benjamin Johnson Peligro
La pregunta no es en blanco y negro. ¿Cuánto estado se recarga? Muchos juegos recargan conjuntos completos de texturas sin una buena razón. Claro, pasar del nivel 5 al nivel 6 puede significar cargar nuevas texturas, pero eso no significa que deba hacerlo cada vez que (re) comience el nivel 6.
MSalters
@MSalters Se tratará principalmente del estado del juego en lugar de los recursos, es posible que no necesite volver a cargar un texto de uso común, sino más al enemigo que ya mató: el objeto para él debe ser destruido y recargado en su estado inicial (incluso si su textura todavía está bien guardada en la memoria.)
Tom 'Blue' Piddock
Creo que alguien ha estado jugando Wing Commander III en un sistema heredado.
Erik Reppen

Respuestas:

54

Bueno, ahora, qué pregunta simple pero interesante de abordar.

Al recargar un nivel, hay tantos factores que deben tenerse en cuenta que la respuesta puede ser de muchas maneras.

Si su estado de nivel contiene una lista grande de activos, puede ser más práctico comenzar desde una pizarra limpia al volver a cargar un nivel a un estado de salvar / misión, ya que esto mantiene el estado exacto del nivel después de la recarga, pero no toma mucho de procesamiento. Sin embargo, es más eficiente restablecer los activos solo si solo hay unos pocos a tener en cuenta, asegurándose de que puede reiniciar la acción rápidamente en estos niveles más pequeños. Esto último es especialmente cierto cuando no necesitas preservar nada en la escena o no se ve afectado por tus elecciones en el juego; si no necesitaras los cadáveres para ser preservado de tu primer recorrido por una aldea, no lo harían debe volver a cargarse en su camino de regreso a través de ese nivel, conservando así el tiempo del procesador y el tiempo de acceso al estado de ahorro / misión.

Un buen ejemplo para pensar sería un Shooter en primera persona que usara calcomanías de destrucción de terreno / bala que tenían un estado persistente durante ese juego, pero que no se quedarían si reiniciaras ese punto de control o nivel .

Si tuviera que rebobinar el nivel en lugar de destruirlo y volverlo a cargar, tendría que rastrear cada estado cambiado. Si disparaste un agujero en la pared con un cohete, generarías gibs de terreno a partir de las piezas que caen de la pared, el modelo de la pared cambiaría para producir el agujero y tendrías efectos de partículas que se han generado para que se vea bonito . Para limpiar esto volviéndolo a un estado "reiniciable", tendría que:

  • Elimine cualquier gib generado dinámicamente para ese muro (pero no elimine los del estado que cargó)
  • Elimina el efecto de partículas del polvo del agujero de bala
  • Reemplace / repare la pared para deshacerse de los agujeros que creó
  • Restablecer la munición del jugador
  • Etc ...

Con tantos recursos para rastrear para rebobinar un nivel, a menudo es menos intensivo para el procesador simplemente destruir todo el nivel y volver a cargar todos los activos nuevamente en sus estados predeterminados o específicos de la misión. Tener que restablecer objetos específicos implica buscar una lista de los objetos en la escena y luego acceder a sus propiedades para restablecerlos. En lugar de reparar el agujero de bala en la pared limpiando, no es necesario que haga ninguna acción de limpieza, simplemente elimine todo el nivel de la memoria y vuelva a cargarlo desde cero.

Esto significa que la recarga de un nivel se realiza desde un objeto de estado (un archivo de juego guardado o un script de misión) y no necesita concatenaciones dinámicas. Para las consolas, esto se ve exacerbado por los tiempos de carga relacionados con los discos. También ayuda a los juegos de PC, ya que puede tener en cuenta las computadoras que no tendrán el poder de procesamiento para hacer que los tiempos de carga sean aceptables.

Entonces, para niveles de contenido grandes: cargar un solo estado en lugar de calcular y "rebobinar" uno:

  • Requiere menos procesador
  • Es más eficiente en máquinas de nivel inferior
  • Permite que un script de misión y un archivo guardado se usen de la misma manera (potencialmente use el mismo sistema de carga para cargar un estado de guardado o un estado de punto de control de misión al reiniciar el nivel)
  • Significa que tiene menos trabajo como desarrollador para restablecer un nivel : es mucho más fácil programar una recarga completa de los datos de la sesión que rastrear y rebobinar. Este es probablemente el punto más influyente

Sin embargo, como ejemplo contrario, es posible que un juego de lucha (un gran ejemplo de la vida real sea Street Fighter 4) no necesite recargar tantos recursos para reiniciar un nivel. Los 2 jugadores, el estado del entorno para el nivel y los temporizadores de nivel simple son en su mayoría estáticos y no dinámicos (la salud de los jugadores siempre reaparecerá al 100% en cada ronda, los temporizadores se restablecen a 90 segundos y el nivel no tiene agujeros de bala [¡o lo hace!] ) y, por lo tanto, restablecer el nivel es cuestión de poner a los luchadores en perfecto estado de salud y devolver el entorno a sus posiciones originales (como los espectadores en algunos de los niveles).

Entonces, para un juego de lucha cuando se realiza una revancha (que no va de ronda en ronda) necesitas:

  • Restablece la salud y la energía a Máx. O valores predeterminados (siempre lo mismo por personaje)
  • Restablecer temporizador
  • Restablecer posiciones iniciales del personaje
  • Restablece el terreno al estado predeterminado (¡sin agujeros de bala para arreglar o recargar!)

Y esa es la lista completa esencialmente, lo que significa que un restablecimiento rápido del estado en lugar de una recarga de nivel completo es más factible. Esto también se puede mostrar por el tiempo de carga cuando comienzas el partido inicialmente. Se tarda mucho tiempo en cargar todos los modelos de personajes y niveles, pero solo unos pocos pasos del procesador para restablecer las posiciones iniciales de los personajes entre partidos con un modelo ya cargado.

Es importante tener en cuenta que este es también un requisito más demandado de los juegos de lucha, ya que sus jugadores tienden a querer volver a la acción increíblemente rápido, ya que los partidos generalmente solo duran un minuto, enfatizando que esta respuesta depende mucho del juego y genero. Los FPS exigen activos más dinámicos, mientras que los Fighters exigen acciones repetibles rápidas.

Espero que esto haya arrojado algo de luz sobre su pregunta.

Tom 'Blue' Piddock
fuente
77
Gran respuesta ... el lado cínico de mí, sería poner su: "menos trabajo para desarrolladores punto más alto en la lista ... pero tal vez su puesta en práctica del motor que podría ser mejor.
Malla
3
Además, ¿qué pasa con la recuperación de errores? Un NPC no se mueve debido a un error en el sistema físico, una pérdida de memoria, etc. Incluso si el juego se prueba a fondo, estas cosas aún suceden y debe haber una manera de restablecer el juego a un estado conocido y funcional.
Sulthan
99
Menos trabajo es un objetivo envidiable para lograr, no un tema de vergüenza. Podría pasar una semana para construir un sistema de rebobinado y un mes para eliminar todos los errores, o recargar y acceder a otras funciones =)
Patrick Hughes
1
Creo que el costo es el argumento más importante aquí. A menos que la recarga de un nivel ocurra mucho y se convierta en una molestia importante para el usuario, no hay ningún incentivo para escribir código optimizado para acelerar la recarga. Simplemente cuesta menos reutilizar el código para una carga normal.
orlp
1
+1 Solo quiero aclarar que recargar un nivel y cargar un nivel, si la recarga arroja todo y comienza con una nueva carga, no requiere que se escriba un código nuevo para lograr el objetivo del juego. Un sistema de rebobinado es un conjunto de código completamente nuevo que no es trivial y, debido a que depende de un estado variable, es extremadamente difícil de depurar. Ejemplo: "Solución de error: reiniciar un nivel después de dejar caer un casco encima de una bomba después de que un misil explota dentro de 200 píxeles de agua ya no causa un bloqueo en el escritorio" En resumen, tendrías que tener una MUY buena razón para molestarte.
BrianH
14

Para aclarar las respuestas existentes contra su pregunta sobre las consolas: no tienen suficiente memoria para almacenar tanto el estado inicial como el estado actual para juegos complejos más grandes.

Un juego puede almacenar el nivel y el estado inicial por separado para que solo se pueda transmitir el estado, y esto es muy probablemente lo que hacen muchos juegos. Sin embargo, incluso transmitir solo eso será un poco más lento que si se hubiera guardado en la memoria.

La "mejor" consola de la generación actual tiene solo 512 MB de memoria compartida entre los datos de la CPU y los gráficos. Eso es minúsculo. Uno de los dolores de cabeza actuales del desarrollo de la consola es tratar de encajar en juegos que cumplan con los niveles de calidad actuales con cantidades tan pequeñas de memoria. El conteo de kilobytes puede volverse importante, especialmente cerca de la fecha de envío. Almacenar una copia del estado inicial de un nivel es una cierta cantidad de datos que se podrían realizar sin ella, lo que permite utilizar más memoria para cosas que hacen que el juego sea más interesante durante el juego en lugar de simplemente hacer que la recarga de nivel sea más rápida.

Idealmente, el jugador pasa más tiempo jugando que muriendo y reiniciando, por lo que la optimización para una mejor experiencia durante el juego tiene más sentido.

Las cosas podrían cambiar drásticamente con las consolas de próxima generación y sus 8 GB de memoria. O podrían permanecer igual, simplemente con modelos y materiales de mayor resolución y gran cantidad de objetos activos en el juego. El tiempo dirá. Dado que los juegos de PC generalmente se dirigen a máquinas con 2 GB de RAM y 512 MB de VRAM (aunque muchos escalan a valores mucho más grandes), los 8 GB de las nuevas consolas son bastante lujosas en lo que respecta a las líneas de base mínimas. Es probable que veamos una transición a los juegos que exigen una CPU / OS de 64 bits y 4-8GB de RAM con 1-2GB de VRAM en los próximos años. Almacenar múltiples estados en la memoria para una instantánea rápida debería ser mucho más fácil.

Sean Middleditch
fuente
+1 Información fantástica y una gran explicación de por qué las consolas son mucho más lentas en la recarga.
Tom 'Blue' Piddock
7

No estoy de acuerdo con gran parte de la respuesta de Blue, no creo que haya un caso técnico para no restablecer los niveles; ciertamente, nunca encontré uno. La carga de nivel es casi siempre más lenta que el restablecimiento de nivel, de hecho, me resulta difícil concebir una ocasión en la que no sea así. En la mayoría de los casos, los juegos podrían ofrecer una carga de nivel instantánea efectiva si los desarrolladores lo eligen.

La respuesta real es, como se sugiere, es más fácil y más rápido. La carga repetida de niveles es algo que un juego requiere de todos modos, por lo que reutilizar esto en un reinicio de nivel es relativamente sencillo. El restablecimiento requiere nuevas vías complejas con un gran potencial para nuevos errores y pérdidas de memoria y requiere una inversión decente de tiempo del desarrollador. En algunos casos, también puede superar los límites de memoria. Dado que los juegos rara vez se desarrollan con un exceso de tiempo de desarrollo, los elementos como el restablecimiento de nivel tienen una tendencia lamentable a caerse en el camino, particularmente si la arquitectura del juego no es la mejor construida en primer lugar.

Si bien supongo que se podría llegar a una situación en la que era necesario "rebobinar" para restablecer, de hecho, la mayoría de los juegos solo necesitan almacenar el estado original, proporcionar un medio efectivo para restablecer completamente ese estado para los objetos retenidos y un medio para marcar objetos abandonar al reiniciar. La información del estado del juego también debe almacenarse y restaurarse. Este tipo de información suele tener poca memoria en comparación con los requisitos para un nivel completo, por lo que esto elimina la necesidad de una carga lenta y costosa de datos desde el disco (incluidos elementos grandes como texturas y modelos) y la sustituye por una rápida. -Pase de memoria de la escena.

Jack Aidley
fuente
3
Es posible que desee consultar la respuesta de Sean para obtener un ejemplo de un caso técnico en el que desee recargar un nivel sobre "restablecerlo"
SpartanDonut
2

Para permitir grandes niveles o niveles de juego sin problemas, incluso con memoria limitada (la memoria siempre es demasiado pequeña, la pregunta es si primero alcanza el límite en RAM o en la tarjeta gráfica) hay otra estrategia:

Solo tiene la parte del nivel en la memoria que el jugador necesita actualmente o necesitará en unos segundos. Modelos, texturas, muestras de sonido, ... que probablemente ya no se necesitan, se eliminan de la memoria.

Dungeon Siege viene a la mente (los desarrolladores afirmaron que la administración de memoria requería más poder de procesamiento que el juego real), la mayoría de los MMORPGS lo hacen, los Shooters con un entorno abierto tienen que hacerlo, ... En estos casos, el comienzo del Es posible que el nivel (o incluso un punto de reaparición hace 30 segundos) ya no esté (completamente) en la memoria.

A menudo, una nueva recarga es la forma más fácil, la más barata y quizás la más rápida.

Editar: Aquí hay un documento sobre los mecanismos de carga de Dungeon Siege: The Continuous World of Dungeon Siege

linac
fuente
Buen punto, no pensé en niveles continuos o ininterrumpidos. Eso necesitaría un sistema de carga de nivel completamente diferente.
Tom 'Blue' Piddock
2

Con las excelentes respuestas de Sean y Blue con respecto a las limitaciones de la plataforma física y las decisiones favorables, voy a ampliar un comentario a un enfoque diferente:

Por qué probablemente deberías recargar completamente el nivel

Así que tienes tu llamada loadLevel () funcionando perfectamente, ¡yay! Transmite información de un archivo de nivel y avanza construyendo el mundo basándose en él, creando objetos y cargando texturas y sonidos a medida que avanza. Luego, cuando todo está hecho, o "hecho" lo suficiente como para permitir que comience la reproducción, llamas a startPlay () y tu mundo se revela y tu música comienza a reproducirse.

Ahora, cuando haya terminado con el nivel, o escape al menú, o salga del juego, llame a unloadLevel () para liberar todos los recursos y la memoria que ha estado sosteniendo para permitir una experiencia fluida.

Ahora, ¿qué sucede cuando desea agregar una función de "Nivel de reinicio"? Bien...

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

Y ya está! Sin código nuevo, solo algunas llamadas a funciones simples como máximo, y ya ha escrito y depurado todo eso, así que su nueva y brillante función de reinicio se tacha de su lista, y probablemente nunca se la vuelva a encontrar: código crujiente y sin oxidación es el mejor tipo! Mueva el código a una función restartCurrentLevel () y puede doblar ese código y nunca volver a mirarlo, tal vez después de asegurarse de que haya un nivel para reiniciar, por supuesto :)

Pero luego te preguntas si esto no es un desperdicio, descargando cosas que estás a punto de volver a cargar de todos modos. Bueno, si sus niveles y recursos son pequeños, lo máximo que tiene que ganar es unos segundos de tiempo de carga cada vez que se llama "Reiniciar" incluso en sistemas lentos (y tal vez en teléfonos inteligentes más antiguos), ¿a quién le importa? "Optimización prematura", tiene mejores cosas que hacer con su tiempo.

Ah, pero ahora tus niveles están creciendo y tus texturas se están volviendo más detalladas y la banda sonora se rasgó en 512 kbps con canales separados para cada voz y capa musical (parecía una buena idea en ese momento, aunque no puedes recordar por qué. ..) y algo sobre "matrices de transformadas de Fourier multidimensionales dependientes del estado del rayo de voxel que cree que está totalmente formado y no es algo real, y la carga de nivel en realidad lleva un tiempo y comienza a molestarlo. Incluso has probado con personas reales y en realidad muestran disgusto por los tiempos de espera, ya que es peor que juegos similares (no esperas que una ciudad capital de MMORPG con 100 jugadores se cargue por completo en <2 segundos, ¿verdad?), Y es un problema.

Entonces, ¿cómo optimizas? Bueno, si el nivel de re -loading es un problema, entonces no es el nivel de carga es un problema? Si crees que solo se está recargando, ¿por qué demonios las personas están recargando tu nivel con mucha más frecuencia que simplemente cargar el nivel en primer lugar? Suena como un problema de juego, no un problema de ingeniería de código. ¿Quién cree que es divertido recargar un nivel una y otra vez, y solo desea que sea más rápido en lugar de evitarlo por completo ?

¡Solucione el problema real primero!

Pero digamos que su juego está diseñado para que deba reiniciar al menos ocasionalmente, y el tiempo de carga es lo suficientemente largo como para que sea correcto hacerlo una vez y completamente inevitable, pero no desea tener que volver a hacerlo. ¿Qué tipo de juego es este, de todos modos? Parece un problema un poco extraño ... ¿tal vez un juego tipo Portal de alta resolución donde se supone que vas a estropear el rompecabezas repetidamente?

En primer lugar, debes darte cuenta de que esto no va a ser trivial. Tendrá que escribir código completamente nuevo y no probado, y es "dependiente del estado", de modo que es posible que ni siquiera sepa qué se reutilizará o no entre las jugadas de nivel. ¿Hay elementos aleatorios, engendros, texturas variables (¿tus esqueletos solo a veces usan armadura?) U otros elementos cambiantes en tu nivel? ¿Hay cosas que varían con el jugador, como un atuendo o modelo personalizado o colores / puertas / trampas?

Vas a hacer comparaciones, y muchas de ellas. Vas a recorrer los elementos de nivel, comparando lo que se necesitará con lo que está cargado en este momento (¿qué haces con cosas que se cargaron para el último nivel pero no para este? Libéralos o espera para evitar un futuro ¿carga?). Si esto es realmente un gran problema para su juego, es probable que desee cambiar su código de carga / descarga para ver si algo ya está cargado antes de cargarlo (haciendo que el código sea multipropósito pero potencialmente introduciendo nuevos errores en las características y funciones que funcionaban anteriormente) que liberan cuidadosamente recursos que no se utilizarán en el futuro cercano). Suspiro.

No importa lo que hagas, incluso si tu juego es simple, te encontrarás con errores oscuros que se basan en el estado del nivel / jugador cuando se reinició un nivel que no te sucede cargar el nivel la primera vez. Así que puedes escribir actualizaciones de juegos con texto como:

"Dejar caer un casco sobre una bomba sobre una baldosa que tenía un misil explotado cerca de él, que también estaba a 200 píxeles de agua, ya no corromperá los datos del juego ni hará que el juego se bloquee".

La verdadera razón La mayoría de los juegos no molestan

¿Alguna vez has notado que la mayoría de las personas simplemente pintan o pintan sobre sus paredes existentes en lugar de pelarlas a una capa base, o colocan la alfombra justo encima de los pisos de madera en lugar de levantarlas?

El simple hecho es que todo es más trabajo por una recompensa mínima. Pintar sobre las paredes existentes funciona bien la mayor parte del tiempo , y el valor de rasgar los pisos de madera dura es a menudo mínimo o inexistente.

Lo mismo ocurre con el software, desde juegos hasta presentaciones multimedia de Power Point: si todo lo que hace es quitarse unos segundos de una pantalla de carga, la gente pasa el 1% de su tiempo mirando, entonces será mejor que sea increíblemente trivial o que esté obteniendo Un rendimiento muy bajo de su tiempo invertido.

Y así, la mayoría de los juegos no se molestan, y tengo problemas para pensar en muchos juegos en los que las pantallas de carga hacían que un juego, por lo demás bueno, no valiera la pena, excepto algunos ejemplos extremos; los ejemplos extremos son donde la optimización para una carga de nivel más rápida tiene sentido, y esa es una pequeña fracción de los juegos que llegan al público, y probablemente incluso una fracción más pequeña de juegos que nadie ve porque nunca se lanzan.

BrianH
fuente
0

Porque es más difícil desarrollar el comportamiento opuesto que consiste en mantener los datos estáticos del juego (como texturas, información geológica, mobs no afectados) en la memoria y volver a cargar solo los datos dinámicos (como la posición del jugador, las estadísticas del jugador, el estado de la búsqueda, el inventario) .

Como cuesta más dinero y tiempo, los desarrolladores de juegos generalmente no hacen eso.

Xtro
fuente
Esto no cubre las situaciones en las que debe ocurrir lo contrario debido al género del juego o las demandas individuales. Como Prince of Persia necesita registrar el estado del juego para usar una mecánica de juego en particular y los ejemplos de juegos de lucha que di que necesitan poder recargar los elementos individuales / nivel / personaje para reiniciar durante la mitad de un partido para comenzar la próxima ronda o reinicie el partido para comenzar el próximo juego. Estos son necesarios para satisfacer las demandas del juego en cuestión y, por lo tanto, es necesario que los desarrolladores de juegos gasten más tiempo y dinero.
Tom 'Blue' Piddock
Si ocurre lo contrario en un juego específico, la pregunta anterior no es válida para ese juego. Debido a que el tiempo de carga será rápido en el juego en el que ocurre lo contrario. Acabo de responder la pregunta sobre la situación a la que se aplica (que es el juego que carga todo el nivel desde cero)
Xtro
Si ocurre lo contrario donde la premisa de la pregunta podría haber sucedido, siempre vale la pena señalarlo y por qué. Perder información o dejar de lado los detalles de por qué ha surgido una situación o solución nunca es beneficioso. Decir que no hay necesidad de detalles es un poco contrario a la intuición, ya que no habría una pregunta en primer lugar si la persona no buscara detalles. Si puede proporcionar más detalles, siempre trate de hacerlo, ya que ayuda a otros a aprender más sobre un tema en su conjunto y a tomar lo que necesita del detalle.
Tom 'Blue' Piddock
entonces, su reacción es para mi primera línea de respuesta que trata sobre "no hay necesidad de detalles" ¿verdad? si elimino esa línea, ¿recuperarías -1 punto?
Xtro
Curiosamente, sí. Nunca desaliente los detalles donde es posible darlos y generalmente encontrará que sus respuestas son mucho más apreciadas.
Tom 'Blue' Piddock