Circa u mudellu di rete in ghjochi per i principianti

Circa u mudellu di rete in ghjochi per i principianti
Per l'ultime duie settimane aghju travagliatu nantu à u mutore di rete per u mo ghjocu. Prima di quessa, ùn sapia nunda di rete in i ghjoculi, cusì aghju lettu assai articuli è aghju fattu assai esperimenti per capiscenu tutti i cuncetti è pudè scrive u mo propiu mutore di rete.

In questa guida, mi piacerebbe sparte cun voi i diversi cuncetti chì avete bisognu à amparà prima di scrive u vostru propiu mutore di ghjocu, è ancu i migliori risorse è articuli per amparà.

In generale, ci sò dui tipi principali di architetture di rete: peer-to-peer è client-server. In una architettura peer-to-peer (p2p), i dati sò trasferiti trà ogni paru di attori cunnessi, mentre chì in una architettura client-server, i dati sò trasferiti solu trà i ghjucatori è u servitore.

Ancu s'è l'architettura peer-to-peer hè sempre aduprata in certi ghjoculi, u cliente-servitore hè u standard: hè più faciule d'implementazione, richiede una larghezza di canali più chjuca, è facilita a prutezzione di l'inganni. Dunque, in questa guida, ci focalizemu nantu à l'architettura cliente-servitore.

In particulare, simu più interessate in i servitori autoritarii: in tali sistemi, u servitore hè sempre ghjustu. Per esempiu, se u ghjucatore pensa ch'ellu hè à (10, 5) è u servitore li dice chì hè in (5, 3), allora u cliente deve rimpiazzà a so pusizioni cù quella chì u servitore informa, micca l'invece. L'usu di servitori autoritarii facilita a ricunnosce i traditori.

Ci sò trè cumpunenti principali in i sistemi di rete di ghjocu:

  • Protokollu di trasportu: cumu e dati sò trasferiti trà i clienti è u servitore.
  • Protocolu di l'applicazione: ciò chì hè trasmessu da i clienti à u servitore è da u servitore à i clienti, è in quale formatu.
  • Lògica di l'applicazione: cumu si usanu i dati trasmessi per aghjurnà u statu di i clienti è u servitore.

Hè assai impurtante per capisce u rolu di ogni parte è e difficultà assuciate cun elli.

Protocolu di trasportu

U primu passu hè di sceglie un protocolu per u trasportu di dati trà u servitore è i clienti. Ci hè dui protokolli Internet per questu: TCP и UDP. Ma pudete creà u vostru propiu protokollu di trasportu basatu annantu à unu di elli o aduprà una biblioteca chì li usa.

Comparazione di TCP è UDP

TCP è UDP sò basati IP. L'IP permette à un pacchettu per esse trasmessu da una fonte à un receptore, ma ùn guarantisci micca chì u pacchettu mandatu ghjunghjerà à u receptore prima o dopu, ch'ellu vi ghjunghjerà almenu una volta, è chì a sequenza di pacchetti ghjunghjerà l'ordine currettu. Inoltre, un pacchettu pò cuntene solu una dimensione limitata di dati, datu da u valore MTU.

UDP hè solu una fina capa sopra IP. Dunque, hà i stessi limitazioni. In cuntrastu, TCP hà parechje funziunalità. Fornisce una cunnessione urdinata affidabile trà dui nodi cun verificazione di errore. Per quessa, TCP hè assai còmuda è hè utilizatu in parechji altri protokolli, per esempiu, in HTTP, FTP и SMTP. Ma tutte queste caratteristiche venenu à un prezzu: ritardu.

Per capisce perchè queste funzioni ponu causà latenza, avemu bisognu di capiscenu cumu travaglia TCP. Quandu l'ospitu chì trasmette un pacchettu à l'ospite ricevente, aspetta di riceve un ricunniscenza (ACK). Se dopu à un certu tempu ùn riceve micca (perchè u pacchettu o a cunferma hè stata persa, o per qualchì altra ragione), allora manda u pacchettu di novu. Inoltre, TCP guarantisci chì i pacchetti sò ricivuti in l'ordine currettu, cusì finu à chì un pacchettu persu hè ricevutu, tutti l'altri pacchetti ùn ponu esse processati, ancu s'ellu sò digià ricevutu da u node di ricivutu.

Ma cum'è prubabilmente capite, a latenza in i ghjochi multiplayer hè assai impurtante, soprattuttu in i generi attivi cum'è FPS. Hè per quessa chì parechji ghjochi utilizanu UDP cù u so propiu protokollu.

Un protokollu nativu basatu in UDP pò esse più efficaci cà TCP per diverse razze. Per esempiu, pò marcà certi pacchetti cum'è fiducia è altri cum'è micca fiducia. Dunque, ùn importa micca se u pacchettu inaffidabile hà righjuntu u destinatariu. O pò processà parechji flussi di dati in modu chì un pacchettu persu in un flussu ùn rallenta altri flussi. Per esempiu, pò esse un filu per l'input di u ghjucatore è un altru filu per i missaghji di chat. Sè un missaghju di chat chì ùn hè micca dati urgente hè persu, allura ùn vi rallentà u input chì hè urgente. O un protokollu pruprietariu puderia implementà a affidabilità di manera diversa da TCP per esse più efficace in un ambiente di video game.

Allora, se TCP sucks, allora andemu à custruisce u nostru propiu protocolu di trasportu basatu in UDP?

Tuttu hè un pocu più complicatu. Ancu s'è TCP hè quasi sub-ottimale per i sistemi di rete di ghjoculi, pò travaglià bè per u vostru ghjocu specificu è risparmià un tempu preziosu. Per esempiu, a latenza pò esse micca un prublema per un ghjocu basatu in turnu o un ghjocu chì pò esse ghjucatu solu nantu à e rete LAN, induve a latenza è a perdita di pacchetti sò assai menu di l'Internet.

Parechji ghjochi di successu, cumpresi World of Warcraft, Minecraft è Terraria, utilizanu TCP. In ogni casu, a maiò parte di l'FPS utilizanu i so protokolli basati in UDP, cusì parlemu di più quì sottu.

Se sceglite di utilizà TCP allora assicuratevi chì hè disattivatu L'algoritmu di Nagle, perchè buffer pacchetti prima di mandà, chì significa chì aumenta u ritardu.

Per sapè di più nantu à e differenze trà UDP è TCP in u cuntestu di ghjochi multiplayer, vede l'articulu di Glenn Fiedler. UDP vs. TCP.

Prutucolu di pruprietà

Allora vulete creà u vostru propiu protokollu di trasportu ma ùn sapete da induve principià ? Avete furtuna, perchè Glenn Fiedler hà scrittu dui articuli maravigghiusi nantu à questu. Truverete assai idee intelligenti in elli.

Primu articulu Networking per i programatori di ghjocu 2008, più faciule ch'è u sicondu Custruì un protocolu di rete di ghjocu 2016. Vi cunsigliu di principià cù u più vechju.

Siate cuscenti chì Glenn Fiedler hè un grande proponente di utilizà u vostru propiu protokollu basatu in UDP. E dopu avè lettu i so articuli, prubabilmente adopterete a so opinione chì TCP hà seriu svantaghji in i video games, è vulete implementà u vostru propiu protokollu.

Ma s'è vo site novu in rete, fate un favore è utilizate TCP o una biblioteca. Per implementà cù successu u vostru propiu protocolu di trasportu, avete bisognu di amparà assai prima.

Biblioteche di rete

Sè avete bisognu di qualcosa di più efficau chè TCP, ma ùn vulete micca fastidiu à implementà u vostru propiu protokollu è andendu in assai dettagli, pudete aduprà a biblioteca di a rete. Ci sò assai di elli:

Ùn aghju micca pruvatu tutti, ma preferimu ENet perchè hè faciule d'utilizà è affidabile. Inoltre, hà una documentazione chjara è un tutoriale per i principianti.

Cunclusione di u Protocolu di Trasportu

Per riassume, ci sò dui protokolli di trasportu principali: TCP è UDP. TCP hà parechje caratteristiche utili: affidabilità, preservazione di l'ordine di pacchetti, rilevazione di errore. UDP ùn hà micca tuttu ciò, ma TCP, per a so natura, hà una alta latenza chì hè inacceptable per certi ghjochi. Questu hè, per assicurà una latenza bassa, pudete creà u vostru propiu protokollu basatu in UDP o utilizate una biblioteca chì implementa u protocolu di trasportu in UDP è hè adattatu per i video games multiplayer.

L'scelta trà TCP, UDP è a biblioteca dipende di parechji fatturi. Prima, da i bisogni di u ghjocu: hà bisognu di una latenza bassa? Siconda, da i requisiti di u protocolu di l'applicazione: hè bisognu di un protocolu affidabile? Comu avemu vistu in a prossima parte, hè pussibule di creà un protokollu d'applicazione per quale un protokollu inaffidabile hè abbastanza adattatu. Infine, avete ancu bisognu di cunsiderà l'esperienza di u sviluppatore di u mutore di rete.

Aghju dui cunsiglii:

  • Astrattu u protocolu di trasportu quant'è pussibule da u restu di l'applicazione in modu chì pò esse facilmente rimpiazzatu senza riscrive tuttu u codice.
  • Ùn ottimisate micca eccessivamente. Se ùn site micca un espertu di rete è ùn sò micca sicuru d'avè bisognu di u vostru propiu protokollu di trasportu basatu in UDP, pudete principià cù TCP o una biblioteca chì furnisce affidabilità, è poi pruvà è misura u rendiment. Sè vo avete prublemi è site sicuru chì hè un protokollu di trasportu, allora puderia esse u tempu di creà u vostru propiu protocolu di trasportu.

À a fine di sta parte, vi cunsigliu di leghje Introduzione à a prugrammazione di ghjocu multiplayer Brian Hook, chì copre parechji di i temi discututi quì.

Protocolu di l'applicazione

Avà chì pudemu scambià dati trà i clienti è u servitore, avemu bisognu di decide quale dati trasfiriri è in quale formatu.

U schema classicu hè chì i clienti mandanu input o azzioni à u servitore, è u servitore manda u statu di ghjocu attuale à i clienti.

U servitore ùn manda micca u pienu, ma u statu filtratu cù entità chì sò vicinu à u lettore. Face questu per trè motivi. Prima, u statu tutale pò esse troppu grande per trasmette à una freccia alta. Siconda, i clienti sò principarmenti interessate in dati visuali è audio, perchè a maiò parte di a logica di u ghjocu hè simulata nantu à u servitore di ghjocu. In terzu, in certi ghjoculi, u ghjucatore ùn hà micca bisognu di cunnosce certi dati, cum'è a pusizione di u nemicu in l'altra parte di a mappa, perchè altrimenti pò sniff pacchetti è sapè esattamente induve si move per tumballu.

Serializazione

U primu passu hè di cunvertisce e dati chì vulemu mandà (input o statu di ghjocu) in un furmatu adattatu per a trasmissione. Stu prucessu hè chjamatu serializazione.

L'idea vene subitu in mente di utilizà un formatu leggibile da l'omu, cum'è JSON o XML. Ma questu serà cumplettamente inefficiente è pigliarà a maiò parte di u canali per nunda.

Invece, hè cunsigliatu di utilizà u furmatu binariu, chì hè assai più compactu. Questu hè, i pacchetti cuntenenu solu uni pochi bytes. Quì ci vole à piglià in contu u prublema ordine di byte, chì pò differisce in diverse computer.

Per serializà e dati, pudete aduprà una biblioteca, per esempiu:

Solu assicuratevi chì a biblioteca crea archivi portatili è cura di l'endianness.

Una soluzione alternativa seria di implementà sè stessu, ùn hè micca cusì difficiule, soprattuttu s'è vo aduprate un accostu centru di dati in u vostru codice. Inoltre, vi permetterà di realizà ottimisazioni chì ùn sò micca sempre pussibuli quandu si usa a biblioteca.

Glenn Fiedler hà scrittu dui articuli nantu à a serializazione: Pacchetti di lettura è scrittura и Strategii di Serializazione.

Cumpressione

A quantità di dati trasferiti trà i clienti è u servitore hè limitata da a larghezza di banda di u canali. A cumpressione di dati vi permetterà di trasferisce più dati in ogni snapshot, aumentà a freccia di rinfrescante, o simpricimenti riduce i requisiti di larghezza di banda.

Imballaggio di pocu

A prima tecnica hè pocu imballaggio. Consiste à aduprà esattamente u numeru di bits chì hè necessariu per discrìviri u valore desideratu. Per esempiu, sè vo avete un enum chì pò avè 16 valori diffirenti, allora invece di un byte sanu (8 bits), pudete aduprà solu 4 bits.

Glenn Fiedler spiega cumu implementà questu in a seconda parte di l'articulu. Pacchetti di lettura è scrittura.

L'imballaggio di bit travaglia particularmente bè cù a discretizazione, chì serà u tema di a sezione dopu.

Sampling

Sampling hè una tecnica di cumpressione di perdita chì usa solu un subset di valori pussibuli per codificà un valore. A manera più faciule di implementà a discretizazione hè di arrotonda i numeri in virgola flottante.

Glenn Fiedler (di novu!) Mostra cumu applicà a discretizazione in pratica in u so articulu Cumpressione di Snapshot.

Algoritmi di cumpressione

A prossima tecnica serà algoritmi di compressione senza perdita.

Eccu, in my opinion, sò i trè algoritmi più interessanti chì avete bisognu di sapè:

  • Codificazione di Huffman cù codice precomputed, chì hè estremamente veloce è pò pruduce boni risultati. Hè stata utilizata per cumpressà i pacchetti in u mutore di rete Quake3.
  • zlib hè un algoritmu di cumpressione generale chì ùn aumenta mai a quantità di dati. Cumu pudete vede ccà, hè stata utilizata in una varietà di applicazioni. Per l'aghjurnamentu di i stati, pò esse redundante. Ma pò esse utile si avete bisognu di mandà l'assi, testi longu o terrenu à i clienti da u servitore.
  • Copia lunghezze di corsa hè prubabilmente l'algoritmu di cumpressione più simplice, ma hè assai efficace per certi tipi di dati, è pò esse usatu cum'è un passu di pre-processazione prima di zlib. Hè soprattuttu adattatu per cumpressione di u terrenu custituitu di tile o voxels in quale parechji elementi vicini sò ripetuti.

compressione delta

A tecnica di cumpressione finale hè a compressione delta. Si trova in u fattu chì solu i diffirenzii trà u statu di ghjocu attuale è l'ultimu statu ricevutu da u cliente sò trasmessi.

Hè stata prima utilizata in u mutore di rete Quake3. Eccu dui articuli chì spieganu cumu si usanu:

Glenn Fiedler hà ancu utilizatu in a seconda parte di u so articulu. Cumpressione di Snapshot.

Criptografia

Inoltre, pudete bisognu di criptà a trasmissione di l'infurmazioni trà i clienti è u servitore. Ci hè parechje ragioni per questu:

  • Privacità / Cunfidenziale: I missaghji ponu esse leghjiti solu da u destinatariu è nisun altru sniffer di a rete puderà leghje.
  • autentificazione : una persona chì vole ghjucà u rolu di un ghjucatore deve cunnosce a so chjave.
  • prevenzione di cheat: serà assai più difficiuli per i ghjucatori maliziusi di creà i so pacchetti di cheat, anu da riplicà u schema di criptografia è truvà a chjave (chì cambia in ogni cunnessione).

Vi cunsigliu assai di utilizà una biblioteca per questu. Suggeriu l'usu libsodiu, perchè hè soprattuttu simplice è hà grandi tutoriali. Particularmente interessante hè u tutoriale nantu scambiu di chjave, chì permette di generà novi chjave in ogni nova cunnessione.

Protokollu di l'applicazione: Cunclusione

Questu cuncludi u protocolu di l'applicazione. Credu chì a cumpressione hè cumplettamente facultativa è a decisione di usà dipende solu da u ghjocu è a larghezza di banda necessaria. A criptografia, in my opinion, hè ubligatoriu, ma in u primu prototipu pudete fà senza.

Logica di l'applicazione

Pudemu avà aghjurnà u statu in u cliente, ma pudemu avè prublemi di latenza. U ghjucatore, dopu avè fattu un input, deve aspittà una aghjurnazione di u statu di u ghjocu da u servitore per vede quale effettu hà avutu in u mondu.

Inoltre, trà dui aghjurnamenti statali, u mondu hè cumplettamente staticu. Se a tarifa di l'aghjurnamentu di u statu hè bassu, allora i muvimenti seranu assai jerky.

Ci hè parechje tecniche per mitigà l'impattu di stu prublema, è discuteraghju in a sezione dopu.

Tecniche di ritardu di lisciatura

Tutte e tecniche descritte in questa sezione sò discussate in detail in a serie. Multiplayer à ritmu veloce Gabriel Gambetta. Vi cunsigliu assai di leghje questa eccellente serie di articuli. Include ancu una demo interattiva per vede cumu queste tecniche funzionanu in pratica.

A prima tecnica hè di applicà u risultatu di input direttamente senza aspittà una risposta da u servitore. Hè chjamatu predizione di u cliente. Tuttavia, quandu u cliente riceve una aghjurnazione da u servitore, deve verificà chì a so predizione era curretta. S'ellu ùn hè micca u casu, allora solu deve cambià u so statu secondu ciò chì hà ricevutu da u servitore, perchè u servitore hè autoritariu. Sta tecnica hè stata utilizata prima in Quake. Pudete leghje più nantu à questu in l'articulu. Revisione di u codice Quake Engine Fabien Sanglars [traduzzione su Habré].

U secondu settore di tecniche hè utilizatu per liscia u muvimentu di altre entità trà dui aghjurnamenti statali. Ci hè dui modi per risolve stu prublema: interpolazione è estrapolazione. In u casu di l'interpolazione, l'ultimi dui stati sò pigliati è a transizione da unu à l'altru hè mostratu. U so svantaghju hè chì provoca una piccula frazzioni di u ritardu, perchè u cliente sempre vede ciò chì hè accadutu in u passatu. L'estrapolazione hè di predichendu induve l'entità deve esse avà basatu annantu à l'ultimu statu ricevutu da u cliente. U so svantaghju hè chì se l'entità cambia completamente a direzzione di u muvimentu, allora ci sarà un grande errore trà a previsione è a pusizione reale.

L'ultima, a tecnica più avanzata, utile solu in FPS, hè compensazione di ritardo. Quandu s'utilice a compensazione di lag, u servitore piglia in contu i ritardi di u cliente quandu spara à u mira. Per esempiu, se un ghjucatore hà fattu un headshot in u so schermu, ma in a realità u so mira era in un locu diversu per via di u ritardu, allora ùn saria ingiustu di ricusà u ghjucatore u dirittu di tumbà per via di u ritardu. Allora u servitore torna à u tempu quandu u ghjucatore hà sparatu per simulà ciò chì u ghjucatore hà vistu nantu à a so schermu è verificate per una collisione trà u so tiru è u mira.

Glenn Fiedler (cum'è sempre!) hà scrittu un articulu in u 2004 Fisica di rete (2004), in quale hà stabilitu i fundamenti per a sincronizazione di simulazioni di fisica trà u servitore è u cliente. In u 2014 hà scrittu una nova serie di articuli fisica di rete, in quale hà descrittu altre tecniche per a sincronizazione di simulazioni di fisica.

Ci sò ancu dui articuli nantu à a wiki di Valve, Surghjente Multiplayer Networking и Metodi di Compensazione di Latenza in Cliente / Servitore Protokollu In-game Design è Ottimisazione tratta di compensazione di ritardu.

Prevenzione di Cheat

Ci sò dui tecniche principali di prevenzione di tradimentu.

Prima, rende più difficiuli per i cheaters di mandà pacchetti maliziusi. Cumu l'esitatu sopra, una bona manera di implementà hè a criptografia.

Siconda, u servitore autoritariu deve riceve solu cumandamenti / input / azzioni. U cliente ùn deve esse capace di cambià u statu nantu à u servitore altru ch'è da mandà input. Allora u servitore, ogni volta chì riceve input, deve verificà a validità prima di applicà.

Lògica di l'applicazione: cunclusione

Vi ricumandemu chì implementate un modu per simulà una alta latenza è una freccia di rinfrescante bassu per pudè pruvà u cumpurtamentu di u vostru ghjocu in cundizioni cattivi, ancu quandu u cliente è u servitore sò in esecuzione nantu à a stessa macchina. Questu simplifica assai l'implementazione di tecniche di ritardu di lisciamentu.

Altre risorse utili

Se vulete esplorà altre risorse di mudelli di rete, pudete truvà quì:

Source: www.habr.com

Add a comment