"Noi incoraggiamo gli individui, consapevolmente curiosi, a passare dalla complessità alla semplicità, dall'interno all'esterno e, a metà strada fra la ricerca e la negazione del significato, vogliamo che i curiosi facciano una dannata scelta". Wachowski

lunedì 23 settembre 2013

NET CODE: (pt.3) NOI ED IL NOSTRO LAG

Continuiamo la nostra discussione su come un sistema multiplayer gestica i client.
Nei primi due post abbiamo iniziato a capire che anche il solo andare avanti con il nostro personaggio, può mettere in difficoltà il server. Questo vale sia per il caso di 1 secondo considerato sia per il casi di pochi millisecondi. La quantità di ritardo non fa cambiare l'entità dei problemi in gioco.
Vediamo perciò ora qualcosa di un pò più elaborato, pur rimanendo nel solo caso di un client e un server.
Fatemi fare, prima, un piccolo chiarimento: qualcuno, dal precedente post, potrebbe dirmi che
, il fatto di aver attaccato Twitchtv, Youtube mentre ero in un server australiano, non abbia realmente creato un ritardo ma solo occupato la banda.
Facciamo una piccola premessa di rete di telecomunicazioni, con le dovute semplificazioni:
Quante volte avete sentito di porte da aprire sul router? Un sacco. Scommetto che avete anche visto che le porte si chiamano UDP o TCP.
Questi due sono due metodi di trasferimento di un pacchetto da un computer ad un altro nella rete.

La differenza tra i due è semplicissima. Il TCP ha un protocollo che garantisce che il destinatario riceverà l'informazione e che i dati ricevuti saranno in sequenza. Nel UDP, invece, un computer trasmette qualcosa ma non ha la garanzia che l'altro computer lo riceva. Vive nella speranza che lo riceva, ma non ha la sicurezza.

Il TCP ha un meccanismo di "retry" per il quale, semplifichiamolo, ogni volta che uno o più pacchetti vengono trasmessi, si ha sempre indietro la notifica di ciò che è stato inviato. Se nella notifica arriva l'informazione che non è stato ricevuto tutto, oppure la notifica non arriva, allora si riprova (retry) a trasmettere. In questo modo si ha la garanzia che l'informazione arriverà.
Nel UDP questo meccanismo manca.

Un pacchetto parte dal pc. Questo pacchetto, ha in particolare, una informazione chiamata TTL (Time To Live) impostata a 255. Ogni volta che questo pacchetto passa per un router nell'internet, il TTL viene decrementato.
Se un router incontra un pacchetto che ha TTL = 0, lo butta, perciò l'informazione non arriverà mai al destinatario.
Aggiungiamoci inoltre che, questo pacchetto, che viaggia da un router ad un altro, può fare ogni volta un percorso diverso. Questo perchè, in caso di congestione, viene reindirizzato verso un router differente.
Il criterio è che deve arrivare, non che faccia sempre lo stesso giro, ma questo vale anche per il TCP. E' il criterio della rete internet.

Ecco perciò che informazioni tra la mia PS3 e il server Australiano potrebbero aver fatto addirittura il giro del mondo in direzioni anche opposte, verso l'america, verso l'Asia o verso la Groellandia e di volta in volta anche con tragitti più o meno lunghi.

Diciamo che solo la DICE sa quello che trasmette in TCP e quello che trasmette in UDP.

Aggiungiamo, inoltre, che la latenza, in generale, è dovuta in misura minore dalla distanza e in misura maggiore dalla elaborazione (router, server, client).
In una rete, le informazioni non viaggiano alla velocità della luce, ma ad una velocità leggermente inferiore.
Basti pensare che, in una fibra ottica, un dato impiega 7,5 millisecondi per fare circa 1600km.
Poi ci sono i ritardi dovuti al traffico delle reti e all'instradamento dei pacchetti (come detto prima).
Valori tipici, perlomeno secondo questo studio sulle reti americane, sono ad esempio:
  •  fibra ottica: 18 ms
  •  DSL: 44 ms
  •  internet satellitare: 638 ms

La vera causa di lag, perciò, sono la capacità di gestire carichi di traffico dei nostri service provider e la posizione geografica (cose alle quali, mi dispiace per voi, non potete fare niente).
Valori medi e americani. Da noi forse le cose sono peggiori e variano parecchio in certi orari del giorno.

Avendo capito questo iniziamo a comprendere l'effetto del ritardo (lag) tra il client ed il server.
In questo articolo, non parliamo di posizione, ma di proiettili. Solo i nostri, non quelli degli altri.
Aggiungiamoci inoltre un oggetto come questo.



Questo è degli oggetti che si possono distruggere, la caratteristica principe di battlefield. E' un riparo che si distrugge sempre di più ogni volta che gli spariamo.
E' qualcosa che tutti vedono allo stesso modo. E' perciò un oggetto condiviso, di proprietà del server.
Non può essere proprietà di un client qualsiasi, non avrebbe senso.

Quando facciamo partire un proiettile, quello si che è un oggetto di proprietà del nostro client che viaggia in rete. Invece quel riparo è in mano al server.

Adesso la domanda: se gli sparassi, si distruggerebbe nell'istante nel quale sparo oppure solo dopo che il server mi ha confermato la collisione del proiettile?

Riprendiamo l'esempio del ritardo di 1 secondo tra client e server del secondo post. Se sparassi, riceverei (e vedrei) la distruzione ben 2 secondi dopo il colpo. Forse il client, anche in questo caso, potrebbe predire il fatto che si distrugga, facendomelo vedere distrutto subito.

Allora? Secondo voi il client predice (come appreso per la corsa del proprio giocatore) oppure aspetta il server per mostrarne la distruzione?

Il client aspetta il server.

Guardate il filmato del server australiano : sparo e solo dopo un pò il riparo si distrugge.
Guardate il filmato del server europeo: sparo e il riparo si distrugge con un ritardo minore.


Non poteva che essere altrimenti. Tutti i client devono vedere il riparo con lo stato di distruzione alla stessa maniera. Impossibile da predire per tutti alla stessa maniera. Meglio farlo controllare dal server.
Sparare ad un oggetto del server, e non ad un altro client, ci facilita la percezione del proprio ritardo.
Rivediamolo con l'esempio esagerato:

Sparo.
Il proiettile impiega 1 secondo ad arrivare al server.
Ipotiziamo che il server istantaneamente processi tutto e trasmetta il nuovo stato del riparo.
Dopo un altro secondo, finalmente il client può mostrare sul video la distruzione del riparo.

OK, siamo quasi pronti per affrontare il prossimo articolo, ovvero far apparire la posizione di un'altro giocatore nel nostro schermo.
Ma prima fatemi dire che adesso avete un metodo per capire se e quanto siete voi a laggare: basta percepire la distruzione di un qualsiasi oggetto di proprietà del server.
E forse qualcuno di voi avrà iniziato a capire dove voglio arrivare: che forse invece di lamentarsi degli altri, dovreste lamentarvi sono del vostro fornitore internet.
Ma con calma, la verità è difficile da digerire...


2 commenti: