Con quale frequenza salvare lo stato del giocatore nei giochi online persistenti?


9

Nei giochi online, le persone preferiscono accedere e disconnettersi quando vogliono. Di solito, i loro risultati di gioco vengono salvati senza problemi sul server. Non è difficile da raggiungere, ma mi chiedo come si possa fare in modo efficiente che abbia senso e si ridimensionerà.

Ha senso salvare le coordinate e lo stato del giocatore ogni volta che lo inviano? Il mio server node.js può farlo facilmente senza bloccare una risposta e voglio utilizzare un database Mongo, ma forse è più appropriato farlo una volta al secondo e in un evento a livello di server, raccogliendo tutto in una volta?


Salvo lo stato del gioco ogni 10 secondi. Penso che sia abbastanza, passa inosservato (e sto eseguendo il mio server MMORPG sul mio netbook che ha 512 MB di RAM).
jcora,

Risposte:


10

Ho in mente un MMORPG tradizionale come World of Warcraft.

Salva dopo ogni comando da ogni giocatore e cosa autonoma (es. NPC)

  • Backup costante. Il server potrebbe scendere in qualsiasi momento e lo stato del gioco viene salvato fino a quel momento (o il più recente possibile, comunque).
  • Impatto sulle prestazioni del server; anche se non è bloccante (cioè su un altro thread), anche se il database si trova su un altro server, sta elaborando che altrimenti non si farebbe. Se non si blocca come dici tu, allora un altro thread deve gestirlo, ed è un thread che potrebbe essere occupato con qualcos'altro.
  • Aumento dell'I / O del disco, aumentando così il rischio / tasso di errore. Ciò è particolarmente preoccupante se si utilizzano SSD per l'archiviazione, data la loro durata inferiore.
  • Se si scarica il database su un altro server, si aumenta la larghezza di banda; questo potrebbe essere un problema se stai pagando per la larghezza di banda e se non si trova su una scheda di rete separata, sta occupando risorse che potrebbero essere meglio utilizzate per gestire il traffico dei giocatori.
  • Cosa succede se il server diventa sempre più indietro nel salvare lo stato di questi comandi? Vale a dire se arrivano più comandi di quanti possano essere salvati, quindi si accumulano in una coda? Questa coda trabocca e causa un errore? Interrompi tutto in modo che la coda possa recuperare?
  • Mi sembra che questo approccio, sebbene sembri semplice, debba essere pianificato con cura. Ad esempio, i comandi consecutivi che si basano l'uno sull'altro dovranno essere salvati insieme; in caso contrario potrebbe verificarsi un errore nel mezzo dei comandi e solo uno verrà salvato ma non l'altro. Considera se due giocatori eseguono uno scambio e due comandi vengono salvati su disco: "aggiungi 1 oggetto al destinatario" e "sottrai 1 oggetto dal mittente". Se si verifica un errore dopo il primo comando ma prima che il secondo comando venga salvato, si ottiene una duplicazione degli articoli. (se l'ordine è invertito, allora hai un oggetto perso)

Salva tutto periodicamente

  • In caso di guasto, il server sarà in qualche modo obsoleto. Spero che tu usi qualcosa come un approccio journaled, quindi l'istantanea più recente sarà almeno intera e coerente e tutti i giocatori attivi saranno arretrati dello stesso periodo di tempo.
  • Qualunque sia il sistema di database che usi potrebbe avere un'ottimizzazione per l'aggiornamento batch, che è più efficiente (meno sovraccarico) rispetto all'aggiornamento uno alla volta.
  • Se invece opti per un file system binario, questo metodo è semplicissimo. Crea un nuovo file, scarica la memoria al suo interno, lancia un marker all'estremità che segnala che il backup è stato completamente completato. Una volta completato un backup, eliminare il backup precedente (o non farlo).
  • Il processo di backup potrebbe anche dover tenere conto delle cose menzionate nell'ultimo punto elenco dell'altra sezione, come il salvataggio nel mezzo di comandi consecutivi che non devono essere interrotti. Potresti scegliere di bloccare l'intero set di dati, scaricarlo su disco e sbloccarlo, ma a seconda di quanto tempo può richiedere una pausa o un rallentamento piuttosto intenso nel gioco.

Salva un personaggio al logout (non salvare nient'altro)

  • La cosa più importante per un giocatore è il suo personaggio, che include gli oggetti che ha, le abilità che ha guadagnato, la sua lista di amici e così via. Se uccidono un mostro e il bottino è a terra di fronte a loro e poi il server fallisce, si spezzeranno il cuore per non avere la possibilità di raccogliere il bottino, ma lo supereranno. Quindi salva solo le cose importanti e non sudare quelle piccole. Non salvare le posizioni degli NPC, ad esempio; se il server si arresta, al suo ritorno, si genereranno nell'area generale in cui dovrebbero trovarsi. L'eccezione, ovviamente, è per tutti gli NPC "intelligenti" che per qualche motivo devono rimanere nel posto in cui si trovano erano quando il server si è spento.
  • Inoltre, un giocatore non dovrebbe essere loggato per troppe ore alla volta (nota che qui sto considerando "tornare in una lobby" come disconnettersi). Alla fine dovranno fare una pausa bagno o procurarsi il cibo o essere interrotti dal loro genitore / amico / qualunque cosa o dormire. Quindi, in realtà, non dovrebbero realisticamente essere registrati senza sosta più di, diciamo, 8 ore anche per il giocatore più hardcore. Se un "giocatore" è connesso per un periodo di tempo davvero lungo, ci sono buone probabilità che si tratti di più persone o di un bot e nessuno dei due è desiderabile o normale.
  • Inoltre, il processo di disconnessione dovrebbe già verificare cose come i comandi consecutivi sopra menzionati. Dovrebbe essenzialmente già impacchettare il personaggio, quindi è ovviamente il momento migliore per scaricarlo su disco.

Pensieri conclusivi

  • Chiaramente sono a favore dell'ultimo approccio, ma ho cercato di essere imparziale su tutti e tre.
  • È difficile dire quale dei due primi metodi sia più dispendioso. Con il primo metodo, se il personaggio invia diversi comandi di spostamento, questi verranno salvati su disco e sovrascritti, quando chiaramente potrebbero essere raggruppati in uno solo. Ma con il secondo metodo, se hai metà della popolazione in piedi, le loro posizioni vengono salvate su disco anche se sono esattamente le stesse dall'ultima operazione di backup. Nel terzo caso, è molto probabile che qualcuno possa accedere e disconnettersi immediatamente, ma il più delle volte molte cose sul giocatore saranno cambiate, quindi lo spreco sembra essere minimo.
  • Tieni presente che questo è interamente per il backup in caso di errore e un errore dovrebbe essere assolutamente ridotto al minimo. È utile gestire questo caso eccezionale, ma alla fine, se il server non funziona, alcuni dati andranno persi e alcuni giocatori saranno sconvolti. Quindi implementa qualunque metodo tu possa, qualunque cosa tu pensi sia più semplice o migliore, e continua.
  • Non fare affidamento su questo come salvataggio predefinito; inserire un bel pulsante di spegnimento sull'applicazione server, che chiude con garbo le connessioni e scrive tutto nel database. Usalo su base normale.

Infine, non prendere questo consiglio come verità assoluta. Non ho scritto un sistema di backup multiplayer. Io sto lavorando su un "gioco" online, che è il motivo per cui ho pensato di questo e ha scritto i miei pensieri sopra, ma non ho ottenuto alla fase di attuazione del presente ancora. Quindi questo è scritto senza esperienza reale, ma dopo molte letture e raccolte conoscenze sull'argomento.


4
Da quello che ho osservato personalmente gli MMO commerciali usano una combinazione di tutti e tre questi. I salvataggi si verificano dopo eventi e azioni importanti come uccisioni / saccheggi / scambi di boss, periodicamente per prevenire la perdita di azioni non critiche (e per non punire coloro che hanno effettuato l'accesso per lunghi periodi di tempo) e sempre al logout. Un singolo metodo non è generalmente sufficiente. Quasi tutti questi metodi si basano su un database in stile SQL sottostante di cui è stato eseguito il backup e il ripristino trasparenti in caso di malfunzionamento dell'hardware.
NtscCobalt,

@NtscCobalt - Sono stato con te fino al "database SQL style". SQL è davvero un requisito? Che dire di NoSQL?
beatgammit

@tjameson Beh, il mio commento è stato scritto prima di toccare NoSQL. Stavo solo cercando di dire che non dovresti arrotolare il tuo formato, ma comunque consiglierei comunque SQL poiché dovresti conoscere lo schema prima (o essere pigro e usare Entity-Key-Value) e la coerenza è più importante del capacità di partizionare quei dati. Vedi stackoverflow.com/questions/7339374/… per maggiori informazioni.
Ntsc Cobalt,

1

Suppongo che dipenda dal tipo di gioco e dalla quantità di traffico tra giocatori e server.

In un MMORPG, non avrebbe senso salvare la posizione dei giocatori ogni volta che inviano le informazioni al server. Avrebbe più senso aggiornare quando i dati attuali del giocatore sono "non aggiornati", per così dire. Potrebbe anche essere utile salvare lo stato del giocatore in eventi importanti come attraversare un nuovo territorio, sconfiggere un boss o lasciare un negozio.

In una partita a turni, avrebbe sicuramente senso salvare lo stato del giocatore ogni volta che termina il proprio turno e dopo il turno di un giocatore avversario (salva la perdita di salute, gli effetti degli incantesimi, ecc.).

Ancora una volta, la risposta dipende interamente dalla scala e dalle capacità del tuo server. Si tratta di trovare il miglior equilibrio e ottimizzare il più possibile senza sacrificare la qualità.


1

Se la tua unica preoccupazione è quando si disconnettono, una semplice risposta è quella di salvare la loro posizione quando si verificano le condizioni per loro non più esistenti nel mondo del gioco (a causa della disconnessione o della disconnessione).

Tuttavia, sarei un po 'diffidente nei confronti del client che riporta al server la sua posizione, o almeno senza una qualche forma di controllo di integrità sul lato server. Se hai già questo, tuttavia, puoi probabilmente salvare quella posizione quando ti disconnetti o disconnettiti poiché non devi preoccuparti di ottenere direttamente i dati dal client.


Sì, da qui la necessità di inviare aggiornamenti regolari al server su valori come position e XP. Più a lungo lo lasci, più diventa discutibile se il giocatore abbia effettivamente accumulato i delta segnalati o meno. Se limiti questi periodi di "check-in" è molto più facile da monitorare / controllare.
Ingegnere

Il problema di dire quando esattamente un giocatore si è disconnesso in un browser game di lunga durata non è in realtà banale.
Lanbo,

Sono d'accordo che non è banale, ma è comunque un problema che devi affrontare in un modo o nell'altro nella maggior parte dei giochi, anche se solo per decidere quando il loro avatar non appare più. Una volta fatto ciò, dovrebbe essere una questione relativamente semplice agganciarsi a quello scenario e salvare la loro ultima posizione valida.
Lunin
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.