2009-09-11 10 views
31

Ho un'architettura server/client implementata, in cui tutte le modifiche di stato vengono inviate alla funzione, convalidate e trasmesse a tutti i client connessi. Funziona piuttosto bene, ma il sistema non mantiene la sincronizzazione tra le istanze client del gioco al momento.Sincronizzazione gioco multigiocatore

Se ci fosse un ritardo di 5 secondi tra il server e un particolare cliente, allora avrebbe ricevuto il cambiamento di stato 5 secondi dopo che il resto dei client lo avrebbe lasciato con lo stato di gioco fuori sincrono. Ho cercato vari modi per implementare un sistema di sincronizzazione tra i client ma non ho trovato molto finora.

Sono nuovo alla programmazione di rete, e non è così ingenuo pensare di poter inventare un sistema di lavoro da solo senza dedicare molto tempo ad esso. Le idee che ho avuto, tuttavia, è di mantenere una sorta di sistema temporale, in modo che ogni cambiamento di stato sia collegato a un timestamp specifico nel gioco. In questo modo, quando un cliente riceveva un cambio di stato, avrebbe saputo esattamente in quale periodo del gioco era avvenuto il cambiamento e sarebbe stato in grado di correlare per il ritardo. Il problema con questo metodo è che in quelli n di ritardo il gioco avrebbe dovuto continuare sul lato client, e quindi il cliente avrebbe dovuto eseguire il rollback in tempo per l'aggiornamento per il cambio di stato che sicuramente sarebbe diventato disordinato.

Quindi sto cercando dei documenti che discutano i soggetti o gli algoritmi che lo risolvono. Forse il mio intero progetto su come funziona il sistema multiplayer è imperfetto, nel senso che l'istanza di gioco di un cliente non dovrebbe aggiornarsi a meno che non venga ricevuta la nozione dal server? In questo momento i client si aggiornano appena nel loro ciclo di gioco assumendo che nessuno stato non sia cambiato.

+3

Interessante domanda. – Ian

+0

Credo che dovresti riconsiderare la risposta accettata. Havenard non ha detto nulla sulla resa dei conti o su altre tecniche di occultamento del tempo. Non è il caso che i giochi dichiarino "i giocatori ritardati dovrebbero accettare le loro condizioni"; fanno uno sforzo per nascondere il ritardo al fine di rendere il gioco più giocabile. Dopotutto, se giocassi a un gioco in cui la gente stesse saltando ovunque e non potessi quasi giocare, lascerei quel gioco dannatamente veloce. – Ricket

risposta

16

L'approccio di base a questo è qualcosa chiamato Dead Reckoning e un bell'articolo su di esso può essere trovato qui. Fondamentalmente si tratta di un algoritmo di predizione per cui le posizioni delle entità saranno indovinate per gli orari tra gli aggiornamenti del server.

Ci sono metodologie più avanzate che si basano su questo concetto, ma è un buon punto di partenza.


anche una descrizione di come questo viene gestito nel motore di origine (il motore di Valve per il primo gioco Half Life) può essere trovato here, il principio è fondamentalmente la stessa - finché il server ti dice altrimenti utilizza una previsione algoritmo per spostare l'entità lungo un percorso previsto - ma questo articolo gestisce l'effetto che questo ha sul tentativo di riprendere qualcosa in modo più approfondito.

2

L'opzione migliore è quella di inviare le modifiche al cliente dal futuro, arrivando così al cliente nello stesso momento in cui lo fa per gli altri client che non hanno problemi di ritardo.

+0

Questa è una risposta ovvia, ma sicuramente apre una potenziale pecca di persone che controllano la propria macchina in modo mirato prima di accelerarlo subito dopo un aggiornamento? Avere la possibilità di svolgere azioni prima di chiunque altro ..? – Ian

+3

L'invio del pacchetto indietro nel tempo è la risposta ovvia? wow ... – Martin

+0

Downvoted, la risposta non ha senso. – CiscoIPPhone

2

Se il cliente vedere eventi che accadono al tasso il server è dargli da mangiare, che è il modo normale di farlo (ho lavorato con i protocolli di Ultima Online, KalOnline e un po 'di World of Warcraft), allora questo ritardo di 5 secondi lo farebbe solo ricevere questi 5 secondi di eventi al Ho visto subito quegli eventi passare molto velocemente o quasi all'istante, visto che gli altri giocatori lo vedevano "camminare" molto velocemente per una breve distanza se anche le sue uscite ritardavano. Dopo di che tutto scorre normalmente di nuovo.In realtà, ad eccezione della normalizzazione grafica e fisica, non riesco a vedere alcun bisogno speciale di sincronizzarlo correttamente, ma solo di sincronizzarsi.

Se hai mai giocato a giochi Valve in due computer vicini noterai che non si preoccupano molto dei dettagli minori come "il luogo esatto in cui sei morto" o "dove sono caduti i lombi del cadavere". È tutto a carico del cliente e totalmente influenzato dalla latenza, ma questo è irrilevante.

Dopo tutto, i giocatori ritardati devono accettare la loro condizione, o chiudere il loro maledetto eMule.

+0

Quindi stai dicendo che dovrei tornare indietro nel tempo sul mio client e reinserire lo stato del gioco? Diciamo che ho un giocatore che si muove verso sud. Continuerà a farlo su tutte le macchine client senza alcuna parola dal server. Se a un certo punto inizia a spostarsi verso nord, allora tutti i clienti lo percepiranno ancora mentre si spostano verso sud finché non ricevono un preavviso, e una volta che lo faranno, dovranno tornare indietro nel tempo e rinnovare la sua posizione dato che in realtà non era spostandosi verso sud tutto il tempo. Dato che tornare indietro nel tempo e rivalutare non è fattibile, suppongo di poter inviare il posizionamento assoluto del giocatore a un valore specifico –

+0

Ecco come dovrebbe essere fatto. Questa interpolazione del movimento deve avere un limite, lascerà qualche passo avanti a meno che il server non intervenga con nuove informazioni sui suoi movimenti. – Havenard

+0

In KalOnline viene eseguito mediante la correzione di coordinate, ogni fase che aggiorna il punto xyz del giocatore nel mondo con 3 byte firmati per X, Y e Z. Altri client si limitano a interpolare la posizione del modello al punto finale xyz. L'interpolazione non viene nemmeno saltata quando arrivano nuovi cambiamenti, considera solo il nuovo xyz finale da quel momento in poi. – Havenard

5

Non ci sarà mai un modo per garantire la perfetta sincronizzazione tra più punti di vista in tempo reale - le leggi della fisica lo rendono impossibile. Se il sole esplodesse ora, come potresti garantire che gli osservatori di Alpha Centauri vedano la supernova nello stesso momento in cui saremmo sulla Terra? Le informazioni richiedono tempo per viaggiare.

Pertanto, le tue scelte sono sia di modellare tutto accuratamente con latenza che possono differire dal visualizzatore al visualizzatore (che è ciò che hai al momento), o modellarlo in modo inaccurato senza latenza e ampiamente sincronizzato tra i visualizzatori (che è dove previsione/morto resa dei conti/estrapolazione entra in gioco). I giochi più lenti come la strategia in tempo reale tendono a percorrere il primo percorso, mentre i giochi più veloci seguono il secondo percorso.

In particolare, non si dovrebbe mai presumere che il tempo necessario per viaggiare sarà costante. Ciò significa che l'invio di messaggi di avvio e arresto per spostare le entità non sarà mai sufficiente in entrambi i modelli. È necessario inviare aggiornamenti periodici dello stato attuale (in genere diverse volte al secondo per giochi più veloci) in modo che il destinatario possa correggere l'errore nelle sue previsioni e interpolazioni.