Avvisa i giocatori ogni x secondi in una partita multiplayer

3

Sto lavorando a un gioco multiplayer in tempo reale usando Django e gevent-socketio, sto affrontando alcuni problemi:

Ho bisogno di inviare un aggiornamento dello stato del gioco ai giocatori connessi ogni X secondi (~ 4 secondi), quindi in pratica ho bisogno di eseguire una funzione ogni x secondi che esegue alcuni calcoli e invia ai giocatori connessi il nuovo stato del gioco. Qual è il modo più semplice per raggiungere questo obiettivo? sta usando cron una buona scelta qui o dovrei cercare altri strumenti come il sedano o ...?

Inoltre, la funzione deve operare su alcuni dati. interrogare il database ogni volta che la funzione viene eseguita non sembra essere una buona idea, dove posso memorizzare i dati del gioco (che viene aggiornato frequentemente durante il gioco)?

    
posta Pindexis 10.04.2013 - 06:24
fonte

4 risposte

2

Per quanto riguarda la tua prima domanda:
Se il tipo di gioco lo consente, consiglierei una strategia round-robin . Invia lo stato del gioco a intervalli uguali ottenendo dividendo il tempo massimo tra gli aggiornamenti per il numero di giocatori che sono connessi, e invia lo stato come una serie di aggiornamenti ai singoli giocatori connessi. > In questo modo si evitano problemi di prestazioni dovuti ai picchi della CPU, come menzionato in alcuni dei commenti alla risposta di @ Kolyunya.

Per inciso, questa strategia consente la seguente ottimizzazione:
Adattare il tempo massimo tra gli aggiornamenti al numero di giocatori connessi in un dato momento:
Se il numero di giocatori è basso, puoi anche impostare il tempo massimo di aggiornamento basso, in modo che i pochi giocatori possano avere aggiornamenti più rapidi.

Per l'implementazione I secondo @ consiglio di Brian per vedere se questo strategia si adatta alle tue esigenze.

Per quanto riguarda la tua seconda domanda:
Dovresti mantenere il tuo stato di gioco in memoria, redis sarebbe una scelta ovvia.

    
risposta data 15.04.2013 - 10:25
fonte
0

L'idea generale indipendente dalla lingua è di avere una sorta di oggetti 'Timer' e 'GameStateSender' che sono collegati usando un pattern di osservatore. Il timer invia eventi ogni x secondi e il mittente ascolta questi eventi e invia i dati al ricevimento.

* L'implementazione dovrebbe essere discussa su SO

    
risposta data 10.04.2013 - 07:59
fonte
0

Che cosa ti consiglierei di usare la tecnologia PUSH .. ad esempio 'long polling' connessioni. Cosa succede in queste connessioni che il client da una richiesta con always keep alive e il server lo riceve.

Ora il client attende la risposta e sul lato server, il server attende qualsiasi azione, non appena il server riceve azioni, risponde alla richiesta del client e non appena il client riceve risposta dal server, richiede nuovamente al server questo va in un ciclo.

Quindi in questa tecnica non devi inviare la richiesta in un determinato momento e non ci sarà nemmeno un ritardo.

Use frameworks like : Twisted

    
risposta data 25.07.2013 - 14:04
fonte
0

Per quanto riguarda il n. 2: l'interrogazione e l'aggiornamento di un database per ogni cambiamento di stato del gioco è un'idea estremamente buona , purché tu stia utilizzando un database corretto.

Ovviamente cose come MySQL possono essere subpotimal in questi casi (o forse no, dipende dalle dimensioni dello stato del gioco e dalla complessità del tuo modello). Se si utilizza un database NoSQL a bassa overhead che archivia le cose sul disco solo quando ha tempo, si avrà un sacco di prestazioni. La durata subirà, tuttavia; un arresto anomalo potrebbe perdere lo stato.

Naturalmente, è sciocco ricalcolare l'intero stato del gioco per ogni richiesta del cliente, se lo stato non è cambiato. Puoi memorizzare la parte comune hard-to-compute e solo ricalcolare parti dipendenti dal client, come "nebbia di guerra".

Questo ci porta all'idea di un database su più livelli. Le tue cose più importanti, come l'inventario degli utenti o il bilancio monetario, dovrebbero essere archiviate in un database durevole, come Postrges o MongoDB. (È incredibile quanto sia moderno il Postgres e quanto veloce possa essere scritto a Mongo.) Le cose che cambiano spesso, come la nebbia di guerra, le posizioni dei missili in volo, ecc., Dovrebbero vivere in un livello di cache, qualcosa come Redis o Memcached, e solo essere memorizzati nel negozio durevole quando si verifica un'azione irreversibile (colpi missilistici). I fatti più importanti dell'attuale tick del gioco dovrebbero essere calcolati una volta e memorizzati nel livello di cache, in una forma che permetta domande facili e invio immediato ai clienti.

Lo stato del livello di memorizzazione nella cache può essere perso a causa di un arresto anomalo senza conseguenze catastrofiche e può essere ricalcolato dai dati durevoli.

Questo è, naturalmente, in qualche modo complesso. Non andare fino a quando non hai un prototipo di lavoro crudo. Utilizza solo il negozio durevole (ad es. Postgres) finché non inizi a risolvere i problemi di prestazioni e hai identificato questi problemi come correlati al database. Quindi vedrai cosa memorizzare nella cache.

    
risposta data 24.09.2013 - 06:33
fonte

Leggi altre domande sui tag