¿Salvar el estado del juego roguelike?

11

Estoy trabajando en un roguelike básico usando HTML5 y jQuery, y me he encontrado con un problema.

Tal como está el juego actualmente, el sistema solo guarda el estado del juego cada vez que el usuario se mueve entre pisos, para minimizar los gastos generales. El peligro de esto es que, si el usuario se mete en problemas, simplemente puede cerrar la ventana y volver a su juego al comienzo del piso actual. Esto reduce drásticamente la dificultad del juego (y casi anula el propósito de un roguelike), pero no es razonable guardar el estado del juego con cada movimiento o ataque de un solo jugador.

He investigado formas de guardar el estado del juego en la ventana del navegador, pero no estoy contento con ellas. Mi pregunta es esta: suponiendo que "guardar un estado de juego" signifique una solicitud de ajax / publicación moderadamente pesada, ¿cómo puedo frustrar este comportamiento de engaño? ¿Existe una metodología conocida para cuantificar los cambios incrementales / de procedimiento en un mapa 2D, en lugar de guardar todo el estado del mapa? Tenga en cuenta que no estoy pidiendo "la forma más eficiente": estoy buscando metodologías existentes para rectificar mi inexperiencia.

CodeMoose
fuente
Pregunta de programación de JavaScript muy genérica y general. Voté en contra pero luego lo pensé nuevamente, ya que es interesante si consideras cómo lo harías si no pudieras desencadenar un evento de descarga.
Tim Holt
Tal vez lo reformule para abordar ese problema directamente =)
CodeMoose
@TimHolt - editado por su sugerencia
CodeMoose

Respuestas:

8

La solución obvia es enviar todos los comandos del jugador al servidor tal como está hecho y hacer que el servidor los registre; de esa manera, si el juego se cancela por algún motivo, los comandos registrados se pueden volver a reproducir para restaurar el juego al punto donde lo dejó.

Por supuesto, cuando se realiza un guardado adecuado, el antiguo registro de comandos puede desecharse (aunque también puede guardarlo para permitir repeticiones de juegos antiguos; si lo hace, es posible que desee incluir marcas de tiempo en el registro para la reproducción en tiempo real ) También es posible que desee realizar un guardado completo automáticamente después de haber realizado n comandos desde el último guardado (donde, por ejemplo, n = 1000) para evitar repeticiones excesivamente largas si el jugador permanece en el mismo nivel demasiado tiempo antes de cerrar o bloquear el juego .

Si su juego involucra números aleatorios (y, al ser un roguelike, probablemente lo haga), también deberá asegurarse de que puedan recrearse correctamente durante una repetición. Una solución es incluir cada número aleatorio en el registro de reproducción; otro es usar un generador de números pseudoaleatorios determinista y guardar la semilla cuando se guarda el juego.

Tenga en cuenta que todos estos métodos pueden explotarse manipulando al cliente, pero eso es realmente inevitable siempre que tenga lógica de juego en el cliente. Como alternativa a prueba de trampas, puede ejecutar el juego real en el servidor y simplemente hacer que el cliente envíe todos los comandos del jugador al servidor y reciba las actualizaciones de la pantalla. Para un roguelike, esto puede ser factible. Obviamente, esto también resolvería su problema de ahorro de estado (aunque es posible que aún desee implementar alguna forma de registro de comandos en el servidor, tanto para la funcionalidad de reproducción como para permitir la recuperación de fallas del servidor). La desventaja es que hacer esto haría imposible el juego fuera de línea (a menos que, por supuesto, también haga que el código del lado del servidor esté disponible para que los jugadores lo ejecuten localmente si lo desean).

Ilmari Karonen
fuente
1
AFAIK todos los RGN son pseudoaleatorios ... necesita hardware especializado para obtener valores aleatorios verdaderos (sin semillas).
bobobobo
1
@bobobobo hay pseudoaleatorio (sin semillas) y hay números aleatorios criptográficamente seguros (sin semillas) en la Plataforma .Net. Puede o no ser aleatorio de hardware, pero está lo suficientemente cerca como para no poder almacenar una semilla.
Rangoric
2

Consulte /programming/3888902/javascript-detect-browser-close-tab-close-browser para obtener una pregunta más genérica de la misma pregunta.

También considere guardar el juego completo en los cambios de piso y deltas incrementales en cada movimiento. Luego puedes volver a jugar el juego hasta el último movimiento.

Suponiendo que se usan algunos generadores de números aleatorios, puede generar y volver a sembrar el generador de números aleatorios al comienzo de cada piso nuevo, y luego guardarlo junto con el piso. Luego puede volver a sembrar en carga, y debería poder reproducir los movimientos con la misma secuencia hasta el último realizado.

Tim Holt
fuente
Gracias Tim: una vez que me pongo en la mentalidad de desarrollo del juego, es muy fácil agrupar cualquier cosa que lo toque en el desarrollo del juego. Accesorios para proporcionar una respuesta de todos modos.
CodeMoose
No se preocupe, vea mi comentario revisado sobre la pregunta también :)
Tim Holt
Hubiera dicho deltas incrementales en cada movimiento también.
bobobobo
2

Enfoques, no salvamentos incrementales, sino encontrar tiempo para un guardado completo:

  • onunload, como se menciono antes. He encontrado que esto es confiable (pero que usa localStorage, no la red, lo que puede cambiar las cosas).
  • Ahorre cuando su ventana pierda el foco.
  • Guardar periódicamente: cuando el último guardado no ha sido en n minutos y el usuario no ha realizado ninguna entrada en m segundos.
Kevin Reid
fuente