Cosa inviare al server in gioco FPS in tempo reale?


23

Qual è il modo giusto per dire la posizione del nostro player locale al server? Alcuni documenti affermano che è meglio inviare gli input ogni volta che vengono prodotti. E alcuni documenti dicono che il client invia la sua posizione in un intervallo fisso.

Con l'invio dell'approccio input: cosa devo fare se il giocatore tiene premuti i tasti direzionali? Significa che devo inviare un pacchetto al server in ogni frame. Non è troppo? E c'è anche la rotazione del giocatore dall'input del mouse. Ecco un esempio:

http://www.gabrielgambetta.com/fpm_live.html

Che dire dell'invio della posizione in approccio ad intervallo fisso. Invia troppi pochi messaggi al server. Ma riduce anche la reattività.

Quindi in che modo è meglio?

Risposte:


19

Risposta semplice: imbrogliare o non essere così preciso!

Se hai giocato a qualche sparatutto online, molto probabilmente avrai sperimentato la cosiddetta "banda di gomma" se la tua connessione al server è errata.

Ciò è causato dal tuo cliente che corregge periodicamente la tua posizione.

Fondamentalmente, cosa succede sui due lati:

  • Il server seguirà il tuo movimento e invierà gli aggiornamenti ai client come previsto. Questi non devono sempre essere aggiornamenti completi. Ogni x frame potrebbe esserci un aggiornamento completo, tutti gli altri frame invieranno solo nuovi vettori di velocità (se ci sono cambiamenti).

  • Il tuo client ti consentirà di muoverti liberamente ma utilizzerà gli aggiornamenti forniti dal server per correggere / regolare la tua posizione. Ciò assicurerà che il gioco sia reattivo, anche se non aggiorni la posizione fotogramma per fotogramma.

Ma come viene gestito l'input? Il tuo client invierà la tua posizione al server "Mi sono trasferito lì". Il server verificherà questo aggiornamento (ad es. Dovresti essere in grado di spostarti così velocemente?) E se è valido ti sposta (o rifiuta l'aggiornamento, con conseguente "fascia di gomma").

Quindi sì, molto probabilmente il tuo approccio a intervalli fissi funzionerà e sarà sufficiente.

Ma anche se si desidera inviare input e gestire il movimento su entrambi i lati, tenere presente che non è necessario inviare "il pulsante è ancora premuto". Invece, invia un evento quando viene premuto il pulsante e un altro una volta rilasciato il pulsante.


5
Sì, posso tenere traccia della pressione e del rilascio del pulsante. Ma per quanto riguarda l'input del mouse? È in continua evoluzione.
Syloc

6
"Invece, invia un evento quando viene premuto il pulsante e un altro una volta rilasciato il pulsante." - Vero, ma è necessario che siano presenti dei controlli per assicurarsi che l'evento "on release" sia eventualmente forzato, a seconda delle regole dei giochi. Ad esempio, nel multiplayer di Rainbow Six Vegas 2 , un giocatore può iniziare a sparare e un bug (purtroppo comune) fa sì che il messaggio "smetti di sparare" non raggiunga con successo il server. Ciò comporta che l'audio da arma da fuoco rimanga in un ciclo infinito per il resto della partita. Solo un esempio di cui diffidare. youtu.be/GOQIbLCy7m8?t=9m10s
Mike Baxter

@syloc: basta gestirlo sul lato client e lasciare che il server determini se il movimento è valido / possibile (per prevenire cose come hack di teletrasporto e simili).
Mario,

@syloc Basta impostare un intervallo per il mouse, ma per risparmiare ulteriore larghezza di banda, fai ancora il controllo sul lato client per vedere se è cambiato. Se c'è un periodo di tempo senza movimento del mouse, non è necessario continuare a inviare messaggi al riguardo.
agweber

In uno dei miei lavori, abbiamo avuto un ingegnere praticamente impazzire ottimizzando il comportamento della molla per gli aggiornamenti di posizione mancati per il dial-up (13 anni fa). Ora vedo giochi con molta larghezza di banda e ridicolmente a bassa latenza che soffrono di questo problema, sembra che il problema non si risolverà mai prima o che le persone si preoccupino molto meno al giorno d'oggi.
Andon M. Coleman,

5

Se non l'hai già fatto, ti suggerisco di leggere questi due articoli profondi ma comprensibili: https://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking e http://fabiensanglard.net/quake3/network.php .

Questi spiegano perché si consiglia di utilizzare l'invio di pacchetti a "intervallo fisso". Per essere brevi, in effetti è importante soprattutto per i pacchetti inviati dal server.

L'invio di un pacchetto ha un costo fisso e la dimensione massima di un pacchetto di rete è di circa 1,5 KB. Quindi se hai ad esempio 16 giocatori sul tuo server, ogni frame quando calcoli il movimento per un giocatore, il codice ingenuo potrebbe inviare un pacchetto di aggiornamento a ciascun giocatore dopo ogni risoluzione di movimento, quindi 16 * 16 = 256 pacchetti. Se hai un framerate di 30, sono 7680 pacchetti.

Un approccio migliore è quello di creare un buffer in ogni inizio del frame, concatenare in esso il tuo aggiornamento di 16 posizioni calcolate e quindi inviarlo ai tuoi 16 giocatori.

Ora si inviano solo 480 pacchetti al secondo per gli stessi risultati.

Nel caso da giocatore a server, ciò significa solo che dovresti inviare, nello stesso pacchetto, un massimo di dati, come; sembrava posizione, le azioni hanno chiamato questo frame e così via.

Circa la seconda parte della tua domanda - il modo in cui ho scelto di ridurre la sensazione di ritardo è stato quello di inviare queste informazioni al server su ciascun frame:

  • posizione attuale attuale del giocatore (utilizzata dal server per verificare se le posizioni lato server e lato giocatore non sono troppo desincronizzate).

  • Posizione stimata del giocatore in 1 secondo: calcolata dal cliente: se il giocatore non cambia la direzione del mouse e lascia la tastiera nello stato corrente per 1 secondo, dove sarà il giocatore? (non ci importa delle collisioni) Se il giocatore non si muove, la sua posizione stimata in 1 secondo è la sua posizione attuale.

  • La posizione che osserva.

Ogni volta che il server riceve queste informazioni aggiorna la posizione futura e la posizione osservata e l'entità giocatore alla fine si sposta verso la sua posizione futura.

I giocatori non sono mai esattamente sincronizzati, ma la risposta in ingresso è istantanea (la cosa più importante per me) e ho trovato le posizioni previste sufficientemente accurate per me.


"I giocatori non sono mai esattamente sincronizzati" Penso che sia anche importante ricordare che il livello di precisione qui dipende dal gioco reale (gioco). Ad esempio, un MMO classico in cui fai semplicemente clic e selezioni le entità, non avrà bisogno di una precisione perfetta per praticamente tutto, ma in uno sparatutto è fondamentale una perfetta sincronizzazione.
Mario,

Il fatto è che nessuno nella loro giusta mente usa TCP per un FPS. Preferirebbero affrontare complicate sequenze di sequenze e datagrammi mancanti piuttosto che sostenere il sovraccarico di TCP.
Andon M. Coleman,
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.