Ingresso lato server


9

Attualmente nel mio gioco, il client non è altro che un renderer. Quando lo stato dell'input viene modificato, il client invia un pacchetto al server e sposta il lettore come se stesse elaborando l'input, ma il server ha l'ultima parola sulla posizione.

Questo generalmente funziona davvero bene, tranne per un grosso problema: cadere dai bordi. Fondamentalmente, se un giocatore sta camminando verso un limite, dì una scogliera e si ferma proprio prima di scendere dal limite, a volte un secondo dopo, verrà teletrasportato fuori dal limite. Questo perché il pacchetto "Ho smesso di premere W" viene inviato dopo che il server ha elaborato le informazioni.

Ecco un diagramma di ritardo per aiutarti a capire cosa intendo: http://i.imgur.com/Prr8K.png

Potrei semplicemente inviare un pacchetto "W Pressed" a ciascun frame per l'elaborazione del server, ma sembrerebbe una soluzione costosa in termini di larghezza di banda.

Qualsiasi aiuto è apprezzato!

Risposte:


5

Mentre il server ha l'ultima parola sulla posizione, dovrebbe farlo verificando e controllando la sanità mentale ciò che il client invia come input e posizione. Lo dico perché ciò che stai facendo è spostare immediatamente il giocatore e l'aspettativa che crea nel tuo codice è che il cliente sia la vera posizione.

Pensi che generalmente funzioni bene, ma non lo è. Nota a margine: dici che il tuo client non è altro che un renderer, quindi dai prontamente il controllo locale per spostarti senza i messaggi del server. Non puoi avere entrambi i modi, o attendere che il server ti dica di spostarti o assumere un certo controllo sulla tua posizione e utilizzare il server per verificare i trucchi.

Prendo atto che le tue risposte stanno raggiungendo un secondo intero? È una latenza di 500 ms che è ridicolmente grande per qualsiasi tipo di gioco d'azione. Prova a scoprire perché questo inversione di tendenza sta impiegando così tanto tempo, che potrebbe essere qualsiasi cosa, dalle code di comando di backup dal non essere gestito prontamente alla larghezza di banda allagata o persino ai demoni che causano molti pacchetti persi.

Quello che penso dovrebbe accadere è quello

client sends a move + position update
server gets it t+latency time later
server verifies and sends out info to all clients
client receives this at (t+latency + latency)

La parte difficile qui è che se un client riceve un messaggio su se stesso, dovrebbe per lo più ignorarlo a meno che quel messaggio sia qualcosa come "mossa non valida, vai invece a XYZ". Se quel messaggio è per il cliente di qualcun altro di cui stai ricevendo informazioni, dovrai estrapolare in avanti in modo che sembri un po 'dove sarà.


Il cliente non invia affatto la sua posizione; predice / interpola semplicemente. Ecco perché cade quando pensa di essere al limite. Inoltre, non vedo dove ho detto che il ritardo era di 1 secondo, è più simile a 8 ms (test locale) a 100 ms (su Internet). Ho detto che il giocatore si sarebbe ritirato più tardi perché invio periodicamente aggiornamenti di posizione completi. Sono corretto nel capire che dovrei inviare la posizione che il client pensa che dovrebbe essere, insieme ai tasti premuti, e il server dovrebbe verificare se è possibile?
Thomas,

"a volte un secondo dopo, verrà teletrasportato" implicava grandi ritardi, da cui ho avuto il tempo. Per un gioco d'azione reattivo sì, il client gioca e il server gioca indietro nel tempo e fa sapere al client se ha fatto qualcosa di illegale. Noterai che nei giochi multiplayer online vedrai soprattutto posizioni di turni di altre persone (che provengono dal server) mentre la tua posizione cambia molto raramente dalle correzioni dirette del server. Altre persone ti vedono cambiare posizione, ecc ...
Patrick Hughes,

Non potrebbe comunque causare la caduta del giocatore dal limite sul server? A meno che non invii un pacchetto per ogni frame, il server potrebbe ancora pensare che il lettore si stia muovendo per circa 32ms. (Mando solo pacchetti ogni tre frame). O stai suggerendo che non simulo affatto l'input sul server, ma piuttosto controllo solo se la posizione è nei limiti dell'input premuto?
Thomas,

Dal momento che il server corregge solo i movimenti non validi segnalati dal client, non invierebbe mai "sei caduto dalla scogliera" a meno che il client stesso non abbia superato il limite. In questo circuito di feedback è il server che si corregge alla visione del mondo da parte del cliente e al suo posto in esso. Il movimento sarà nitido e reattivo per il giocatore. Altre azioni come l'interazione con gli oggetti del mondo implicheranno l'attesa del server per dire al client cosa è appena successo, fare clic su una casella e attendere la risposta, ma stiamo solo parlando di movimento qui.
Patrick Hughes,

Sembra molto quello che sto facendo attualmente; inviando una posizione al server e facendo convalidare il server se il giocatore avrebbe potuto spostarsi in quella posizione. Questo sembra essere un approccio più euristico, e secondo me non sarebbe quasi efficace come far decidere il server, punto. L'invio di timestamp con ciascun pacchetto funzionerebbe? Penso che sradicherebbe il problema. Credo che Halo e i giochi che utilizzano il motore Source lo utilizzino.
Thomas,

0

Capisco la tua domanda come:

Il server riceve un pacchetto quando inizio a premere il pulsante "Avanti" e un altro pacchetto quando finalmente rilascia il pulsante "Avanti". Pertanto, il movimento effettivo sul server inizia e termina circa 100 millisecondi "troppo tardi" nel gioco reale rispetto a ciò che il giocatore sta esprimendo sul lato client. Quindi, se il giocatore vuole muoversi di 10 secondi, può finire per muoversi di 10.x secondi invece che x >= 1online.

Questa è una cattiva strategia di progettazione perché non esprime la volontà del giocatore nel mondo di gioco come intende il giocatore, creando un'esperienza utente piuttosto scadente.

La soluzione che consiglierei è l'invio di un pacchetto (il più spesso possibile) che indica quanti passi ha fatto il giocatore e in quale direzione. Il server quindi aggiorna il mondo di gioco con la posizione del nuovo giocatore se supera un controllo di correttezza. In questo modo il giocatore può muoversi con grande precisione ed evitare di cadere dalle sporgenze alte.

L'alternativa sarebbe quella di ricordare le posizioni del giocatore negli ultimi secondi e correggere la posizione in retrospettiva al momento in cui il pulsante è stato rilasciato. Sembra che creerebbe quell'effetto elastico dei vecchi tempi (solo per una ragione diversa)

Quindi in pratica dovresti inviare un pacchetto di quale pulsante viene premuto e qual è stato il tempo di gioco effettivo in cui il pulsante è stato premuto e poi, quale pulsante è stato rilasciato e in quale momento esatto.


Come ho detto a Patrick, penso che la soluzione sarebbe più di un approccio euristico; invece che il server sia "The Man", il server controlla invece la validità dei dati del client. Questo, ovviamente, dovrà creare un margine di manovra in modo che i ritardi o altri problemi di rete non creino falsi positivi.
Thomas,
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.