Salvataggio dello stato del gioco roguelike?


11

Sto lavorando su un roguelike di base usando HTML5 e jQuery e ho riscontrato un problema.

Allo stato attuale del gioco, il sistema salva lo stato del gioco solo ogni volta che l'utente si sposta da un piano all'altro per ridurre al minimo le spese generali. Il pericolo è che, se l'utente si trova in difficoltà, può semplicemente chiudere la finestra e tornare al gioco all'inizio del piano attuale. Ciò riduce drasticamente la difficoltà del gioco (e quasi sconfigge lo scopo di un roguelike) - ma è irragionevole salvare lo stato del gioco con ogni singolo movimento o attacco del giocatore.

Ho cercato dei modi per salvare lo stato del gioco nella finestra del browser, ma non ne sono soddisfatto. La mia domanda è questa: supponendo che "salvare uno stato di gioco" significhi una richiesta ajax / post moderatamente pesante, come posso contrastare questo comportamento ingannevole? Esiste una metodologia nota per quantificare le modifiche incrementali / procedurali a una mappa 2d, anziché salvare l'intero stato della mappa? Nota, non sto chiedendo "il modo più efficiente": sto cercando metodologie esistenti per correggere la mia inesperienza.


Domanda di programmazione JavaScript molto generica e generale. Ho votato verso il basso, ma poi ho ripensato poiché è un po 'interessante se consideri come lo faresti se non riuscissi a innescare un evento durante lo scaricamento.
Tim Holt,

Forse lo riformulerò per risolvere direttamente quel problema =)
CodeMoose

@TimHolt - modificato secondo il tuo suggerimento
CodeMoose

Risposte:


8

La soluzione ovvia è inviare ogni comando del giocatore al server mentre viene creato e fare in modo che il server li registri; in questo modo, se il gioco viene interrotto per qualsiasi motivo, i comandi registrati possono essere riprodotti per ripristinare il gioco nel punto in cui era stato interrotto.

Naturalmente, quando viene effettuato un salvataggio corretto, il vecchio registro dei comandi può essere eliminato (anche se potresti anche salvarlo per consentire la riproduzione di vecchi giochi; in tal caso, potresti voler includere timestamp nel registro per la riproduzione in tempo reale ). Potresti anche voler effettuare automaticamente un salvataggio completo dopo che sono stati eseguiti n comandi dall'ultimo salvataggio (dove, diciamo, n = 1000) per evitare replay eccessivamente lunghi se il giocatore rimane sullo stesso livello troppo a lungo prima di chiudere o arrestare il gioco .

Se il tuo gioco prevede numeri casuali (e, essendo un roguelike, probabilmente lo fa), dovrai anche assicurarti che possano essere ricreati correttamente durante un replay. Una soluzione è quella di includere ogni numero casuale nel registro di riproduzione; un altro è usare un generatore di numeri pseudocasuale deterministico e salvare il seme quando il gioco viene salvato.

Nota che tutti questi metodi possono essere sfruttati manomettendo il client, ma ciò è davvero inevitabile ogni volta che hai una logica di gioco sul client. In alternativa, è possibile eseguire il gioco reale sul server e fare in modo che il client invii tutti i comandi del giocatore al server e riceva gli aggiornamenti del display. Per un roguelike, questo potrebbe essere fattibile. Ovviamente, questo risolverebbe anche il tuo problema di salvataggio dello stato (anche se potresti comunque voler implementare una qualche forma di registrazione dei comandi sul server, sia per la funzionalità di riproduzione che per consentire il ripristino da arresti anomali del server). Il rovescio della medaglia è che ciò renderebbe impossibile il gioco off-line (a meno che, ovviamente, non si renda disponibile anche il codice lato server per i giocatori che possano eseguire localmente se lo desiderano).


1
AFAIK tutti gli RGN sono pseudocasuali .. hai bisogno di hardware specializzato per ottenere valori casuali (senza semi).
Bobobobo,

1
@bobobobo c'è pseudorandom (seeded) e ci sono numeri casuali crittograficamente sicuri (non seminati) nella piattaforma .Net. Potrebbe / potrebbe non essere hardware casuale, ma è abbastanza vicino da non essere in grado di archiviare un seme.
Rangoric,

2

Vedi /programming/3888902/javascript-detect-browser-close-tab-close-browser per una domanda più generica della stessa domanda.

Considera anche di salvare il gioco completo sui cambi di piano e i delta incrementali su ogni mossa. Quindi puoi ripetere il gioco fino al punto dell'ultima mossa.

Supponendo che vi sia un certo uso di generatori di numeri casuali, è possibile generare e ripetere il seeding del generatore di numeri casuali all'inizio di ogni nuovo piano, quindi salvarlo insieme al piano. Quindi è possibile eseguire nuovamente il rendering al caricamento e dovrebbe essere in grado di riprodurre le mosse con la stessa sequenza fino all'ultima eseguita.


Grazie Tim: una volta entrato nella mentalità di sviluppo del gioco, è davvero facile mettere tutto ciò che lo tocca nel gioco. Puntelli per fornire comunque una risposta.
CodeMoose

Non preoccuparti, vedi anche il mio commento rivisto sulla domanda :)
Tim Holt,

Avrei detto delta incrementali anche su ogni mossa .
Bobobobo,

2

Si avvicina, non ai salvataggi incrementali, ma alla ricerca di tempo per un salvataggio completo:

  • onunload, Come precedentemente menzionato. Ho trovato questo affidabile (ma usando localStorage, non in rete, che potrebbe cambiare le cose).
  • Salva quando la finestra non è più attiva.
  • Salvataggio periodico: quando l'ultimo salvataggio non è stato in n minuti e l'utente non ha effettuato alcun input in m secondi.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.