
Viimased kaks nÀdalat olen töötanud oma mÀngu vÔrgumootori kallal. Enne seda ei teadnud ma mÀngude vÔrgutehnoloogiatest mitte midagi, seega lugesin hulk artikleid ja tegin palju katseid, et mÔista kÔiki kontseptsioone ja suuta kirjutada oma vÔrgumootor.
Selles juhendis soovin jagada teiega erinevaid kontseptsioone, mida peate Ôppima enne oma mÀngumootori kirjutamist, samuti parimaid ressursse ja artikleid nende Ôppimiseks.
Ăldiselt on olemas kaks peamist tĂŒĂŒpi vĂ”rgusĂŒsteeme: peer-to-peer ja kliendi-server. Peer-to-peer (p2p) arhitektuuris edastatakse andmed mis tahes ĂŒhendatud mĂ€ngijate paaride vahel, samas kui kliendi-server arhitektuuris edastatakse andmed ainult mĂ€ngijate ja serveri vahel.
Kuigi peer-to-peer arhitektuuri kasutatakse endiselt mÔnedes mÀngudes, on standardiks kliendi-server arhitektuur: see on kergemini teostatav, nÔuab vÀhem ribalaiust ja lihtsustab petmise kaitset. SeetÔttu keskendume selles giidis kliendi-server arhitektuurile.
EelkĂ”ige huvitavad meid autoriteetsed serverid: sellistes sĂŒsteemides on server alati Ă”igus. NĂ€iteks, kui mĂ€ngija arvab, et ta asub koordinaatides (10, 5), aga server ĂŒtleb talle, et ta on (5, 3), peab klient asendama oma positsiooni selle, mille server edastab, mitte vastupidi. Autoriteetsete serverite kasutamine lihtsustab petiste tuvastamist.
MĂ€ngulistes vĂ”rgusĂŒsteemides on kolm peamist komponenti:
- Transportprotokoll: kuidas andmeid edastatakse klientide ja serveri vahel.
- Rakenduse protokoll: mis edastatakse klientidelt serverile ja serverilt klientidele ning millises formaadis.
- Rakenduse loogika: kuidas edastatud andmeid kasutatakse klientide ja serveri oleku vÀrskendamiseks.
On vÀga oluline mÔista iga osa rolli ja nendega seotud raskusi.
Transportprotokoll
Esimene samm on valida protokoll andmete edastamiseks serveri ja klientide vahel. Selleks on kaks Interneti-protokolli: ja . Kuid vĂ”ite luua ka oma transportprotokolli, mis pĂ”hineb ĂŒhel neist, vĂ”i kasutada raamatukogu, milles need on kasutusel.
TCP ja UDP vÔrdlemine
N nii TCP kui ka UDP pÔhinevad . IP vÔimaldab paketti saata allikast saajani, kuid ei garanteeri, et saadetud pakk jÔuab saajani varem vÔi hiljem, et see jÔuab temani vÀhemalt korra ja et pakettide jÀrjestus saabub Ôigel viisil. Rohkemgi veel, pakett vÔib sisaldada ainult piiratud suurusega andmeid, mille mÀÀrab .
UDP on lihtsalt Ă”huke kiht IP kohal. Seega on tal samad piirangud. Erinevalt sellest, TCP-l on palju omadusi. See tagab usaldusvÀÀrse jĂ€rjestatud ĂŒhenduse kahe sĂ”lme vahel koos vigade kontrollimisega. Seega on TCP vĂ€ga mugav ning seda kasutatakse paljude teiste protokollide, nĂ€iteks, , ja . Kuid kĂ”ik need funktsioonid tulevad oma hinna: .
Kuna mÔista, miks need funktsioonid vÔivad viivitusi tekitada, on oluline aru saada, kuidas TCP töötab. Kui saatja sÔlme saadab paketi vastuvÔtjale, ootab ta kinnitusvastust (ACK). Kui ta ei saa seda teatud aja jooksul (sest paketid vÔi kinnitus on kadunud vÔi muudel pÔhjustel), saadab ta paketi uuesti. Veelgi enam, TCP tagab pakettide kÀttesaamise Ôiges jÀrjekorras, seega ei saa kÔik teised paketid, kuigi need on juba vastuvÔetud, jÀÀda töödeldud, kuni kadunud pakett on kÀtte saadud.
Kuid nagu tĂ”enĂ€oliselt mĂ”istate, on viivitus mitme mĂ€ngija mĂ€ngudes vĂ€ga oluline, eriti sellistes aktiivsetes ĆŸanrites nagu FPS. Just sellepĂ€rast kasutavad paljud mĂ€ngud UDP-d koos oma protokolliga.
Oma UDP-pĂ”hine protokoll vĂ”ib olla mitmel pĂ”hjusel tĂ”husam kui TCP. NĂ€iteks vĂ”ib see mĂ€rgistada mĂ”ned paketid usaldusvÀÀrseteks ja teised mitteusaldusvÀÀrseteks. SeetĂ”ttu ei huvita seda, kas mitteusaldusvÀÀrne paket jĂ”udis vastuvĂ”tjani. VĂ”i vĂ”ib see hallata mitut andmevoogu, et ĂŒhe voolu kadunud pakett ei aeglustaks ĂŒlejÀÀnud vooge. NĂ€iteks vĂ”ib olla ĂŒks voog mĂ€ngija sisendi jaoks ja veel ĂŒks voog vestlusmesside jaoks. Kui vestlusteade, mis ei ole hĂ€davajalik teave, kaob, ei aeglusta see sisendi reageerimist, mis on hĂ€davajalik. VĂ”i vĂ”ib oma protokoll rakendada usaldusvÀÀrsust teisiti kui TCP, et olla mĂ€ngude tingimustes efektiivsem.
Nii et kui TCP on nii halb, kas me siis loome oma UDP-pĂ”hise ĂŒlekandeprotokolli?
Asjad on veidi keerulisemad. Isegi kui TCP on mĂ€nguvĂ”rkude jaoks peaaegu suboptimaalne, vĂ”ib see teie mĂ€ngus ĂŒsna hĂ€sti toimida ja sÀÀsta teie vÀÀrtuslikku aega. NĂ€iteks ei pruugi latentsus olla probleemiks kordusmĂ€ngus vĂ”i mĂ€ngus, mida saab mĂ€ngida ainult LAN-vĂ”rkudes, kus latentsus ja pakettide kadumine on palju madalamad kui Internetis.
Paljudes edukates mĂ€ngudes, sealhulgas World of Warcraft, Minecraft ja Terraria, kasutatakse TCP-d. Siiski kasutavad enamik FPS-mĂ€nge oma UDP-pĂ”hiseid protokolle, seega rÀÀgime allpool neist ĂŒksikasjalikumalt.
Kui otsustate kasutada TCP-d, veenduge, et on vĂ€lja lĂŒlitatud, kuna see puhverdab pakette enne saatmist ja seega suurendab latentsust.
UDP ja TCP erinevuste kohta mitmikmÀngu kontekstis saab lugeda Glen Fidler'i artiklit .
Kohandatud protokoll
Nii et soovite luua oma transpordiprotokolli, kuid ei tea, kust alustada? Teil on vedanud, kuna Glen Fidler on sellest kirjutanud kaks suurepÀras artiklit. Neis leiate palju nutikaid mÔtteid.
Esimene artikkel, 2008. Aeg on lihtsam kui teine. 2016. Soovitan alustada vanemast versioonist.
Pidage meeles, et Glenn Fiddler on suure toetaja oma UDP-pÔhise protokolli kasutamise. Tema artiklite lugemine vÔib teie arvamust TCP tÔsiste puuduste kohta videomÀngudes muuta, ja te vÔite soovida rakendada oma protokolli.
Kuid kui olete algaja vÔrgu alal, siis tehke endale teene ja kasutage TCP-d vÔi mÔnda raamatukogu. Oma transportprotokolli edukaks vÀljatöötamiseks peate enne palju Ôppima.
VÔrguraamatukogud
Kui vajate midagi tĂ”husamat kui TCP, kuid ei soovi oma protokolli rakendamisega vaeva nĂ€ha ega kĂ”igisse ĂŒksikasjadesse sĂŒveneda, vĂ”ite kasutada vĂ”rguraamatukogu. Neid on palju:
- Glenn Fiddler
- , mis enam ei toeta, kuid selle fork tundub olevat veel aktiivne.
- on raamatukogu, mis on loodud mitme mÀngijaga FPS-i jaoks
- ettevÔttelt Valve
Ma ei ole kÔiki proovinud, kuid eelistan ENet'i, kuna see on lihtne kasutada ja usaldusvÀÀrne. Lisaks on sellel arusaadav dokumendi- ja algajatele suunatud juhend.
Transpordiprotokoll: kokkuvÔte
KokkuvÔtteks, on olemas kaks peamist transpordiprotokolli: TCP ja UDP. TCP-l on palju kasulikke omadusi: usaldusvÀÀrsus, paketide jÀrjekorra sÀilitamine, vigade tuvastamine. UDP-l seda ei ole, kuid TCP-l on omamoodi suuremad viivitused, mis ei sobi teatud mÀngude jaoks. SeetÔttu on madalate viivituste tagamiseks vÔimalik luua oma protokoll UDP pÔhjal vÔi kasutada teeki, mis rakendab transpordiprotokolli UDP-l ja on kohandatud mitmikmÀngu videomÀngude jaoks.
Valiku tegemine TCP, UDP ja raamatukogu vahel sÔltub mitmest tegurist. Esiteks mÀngu vajadustest: kas on vaja madalaid latentsusviise? Teiseks rakenduse protokolli nÔuetest: kas on vajalik usaldusvÀÀrne protokoll? Nagu nÀeme jÀrgmises osas, saab luua rakenduse protokolli, mille jaoks sobib tÀielikult usaldusvÀÀrne protokoll. LÔpuks tuleb arvesse vÔtta ka vÔrgu mootorite arendaja kogemust.
Mul on kaks soovitust:
- Maksimaalselt abstraktaage transportprotokoll rakenduse ĂŒlejÀÀnud osast, et seda saaks hĂ”lpsasti asendada, ilma et oleks vaja kogu koodi ĂŒmber kirjutada.
- Ărge tegelege enneaegse optimeerimisega. Kui te ei ole vĂ”rgu spetsialist ega ole kindel, kas vajate UDP-pĂ”hist kohandatud transportprotokolli, siis vĂ”ite alustada TCP-st vĂ”i raamatukogudest, mis soovivad usaldusvÀÀrsust, ning seejĂ€rel testida ja mÔÔta jĂ”udlust. Kui esinevad probleemid ja olete kindel, et pĂ”hjus on transportprotokollis, siis vĂ”ib-olla on aeg luua oma transportprotokoll.
Selle osa lÔpetuseks soovitan teil lugeda Bryan Hooki artikkel, kus kÀsitletakse mitmeid siin arutatud teemasid.
Rakendusprotokoll
Kuna me saame andmeid klientide ja serveri vahel vahetada, tuleb otsustada, milliseid andmeid edastada ja millises formaadis.
Klassikaline skeem on see, et kliendid saadavad serverile sisendeid vÔi toiminguid ning server saadab klientidele hetke mÀnguseisundi.
Server edastab mitte tÀiusliku, vaid filtreeritud seisundi koos objektidega, mis asuvad mÀngijaga lÀheduses. Ta teeb seda kolmel pÔhjusel. Esiteks, tÀiuslik seisund vÔib olla liiga suur edastamiseks kÔrge sagedusega. Teiseks, kliente huvitavad enamasti visuaalsed ja helid, kuna suurem osa mÀngu loogikast simuleeritakse mÀngu serveris. Kolmandaks, mÔnes mÀngus ei tohiks mÀngija teada teatud andmeid, nÀiteks vastase positsiooni kaardi teises otsas, sest vastasel juhul vÔib ta pakette nuhkida ja tÀpselt teada, kuhu liikuda, et teda tappa.
Serialiseerimine
Esimene samm on andmete, mida soovime edastada (sisend vÔi mÀnguolek), muutmine edastamiseks sobivaks formaadiks. Seda protsessi nimetatakse .
SeetÔttu tuleb kohe mÔelda, et kasutame inimloetavat formaati, nÀiteks JSON vÔi XML. Kuid see oleks ÀÀrmiselt ebaefektiivne ja raiskab suure osa kanalist.
Selle asemel soovitatakse kasutada binaarset formaati, mis on palju kompaktsem. See tÀhendab, et pakettid sisaldavad vaid mÔnda baiti. Siin tuleb arvesse vÔtta , mis vÔib erinevatel arvutitel erineda.
Andmete serialiseerimiseks vÔib kasutada teeki, nÀiteks:
- Google'i ettevÔttest
- Sandstormi ettevÔttest
- Shane Granti ja Randolph Voorhise
Lihtsalt veenduge, et teek genereerib kergesti kantavaid arhiive ja hoolitseb baiti jÀrjekorra eest.
Alternatiivseks lahenduseks vÔib olla ka iseseisev rakendus, mis ei ole eriliselt keeruline, eriti kui kasutate koodis andmepÔhist lÀhenemist. Lisaks vÔimaldab see teil teha optimeerimisi, mis ei ole alati vÔimalik teegi kasutamisel.
Glenn Fiddler on kirjutanud serialiseerimisest kaks artiklit: ja .
Kompresseerimine
Kliendi ja serveri vahel edastatavate andmete hulk on piiratud kanali lÀbilaskevÔimega. Andmete kompressioon vÔimaldab edastada igas snapshots rohkem andmeid, suurendada vÀrskenduse sagedust vÔi lihtsalt vÀhendada kanali nÔudmisi.
Bitipakkimine
Esimene tehnika on bitipakkimine. See seisneb just nii paljude bitide kasutamises, kui on vajalik soovitud mÔÔtme kirjeldamiseks. NĂ€iteks kui teil on loetelu, mis vĂ”ib sisaldada 16 erinevat vÀÀrtust, vĂ”ite kasutada ĂŒhe tĂ€ispika byte'i (8 bitti) asemel vaid 4 bitti.
Glenn Fiddler selgitab, kuidas seda rakendada artikli teises osas .
Bitipakkimine töötab eriti hÀsti diskretiseerimisega, mis on jÀrgmise jaotise teema.
Diskretiseerimine
on kaotanud kompressioonitehnika, mis kasutab mahu kodeerimiseks ainult osasetete kombinatsiooni vĂ”imalike vÀÀrtuste hulgast. Diskretiseerimist on kĂ”ige lihtsam rakendada ujukommade ĂŒmardamise kaudu.
Glenn Fiddler (taaskordus!) nÀitab, kuidas praktiliselt rakendada diskreetimist oma artiklis .
Kompresseerimisalgoritmid
JĂ€rgmine tehnika on kaotusteta kompressioonialgoritmid.
Siin on minu arvates kolm kÔige huvitavamat algoritmi, millest teada:
- ettearvutatud koodiga, mis on erakordselt kiire ja vÔib anda hÀid tulemusi. Seda on kasutatud pakettide kompressiooniks Quake3 vÔrgumootoris.
- â ĂŒldotstarbeline kompressioonialgoritm, mis ei suurenda kunagi andmete mahutatavust. Nagu nĂ€ha , on seda rakendatud paljudes valdkondades. Olemasoleku uuendamiseks vĂ”ib see osutuda ĂŒleliigseks. Kuid see vĂ”ib olla kasulik, kui peate saatma klientidele serverist varasid, pikki tekste vĂ”i maastikku.
- â see on ilmselt lihtsaim kompressioonialgoritm, kuid see on vĂ€ga tĂ”hus teatud tĂŒĂŒpi andmete jaoks ja vĂ”ib olla kasutatav eelprotsessina enne zlib'd. See sobib eriti hĂ€sti maastiku kompressiooniks, mis koosneb plaatidest vĂ”i voolikutest, kus palju naabruses olevaid elemente kordub.
Delta-kompressioon
Viimane kompressioonimeetod on delta-kompressioon. See seisneb selles, et edastatakse ainult erinevused praeguse mÀngu seisundi ja viimasest seisundist, mille klient on saanud.
Esmakordselt rakendati seda Quake3 vÔrgumootoris. Siin on kaks artiklit, mis selgitavad selle kasutusviisi:
- Bryan Hook
- Fabien Sanglar [ artikkel HabrĂ©, vt jaotist âVĂ”rgumudelâ]
Glenn Fiedler kasutas seda ka oma artikli teises osas .
KrĂŒpteerimine
Lisaks vĂ”ib teil olla vaja krĂŒpteerida teabe edastamine klientide ja serveri vahel. Sellel on mitu pĂ”hjust:
- privaatsus/confidentsiaalsus: sĂ”numid saavad lugeda ainult saaja ning ĂŒkski teine, kes tehingut jĂ€lgib, ei suuda neid lugeda.
- autentimine: inimene, kes soovib mÀngija rolli tÀita, peab teadma tema vÔtit.
- pettuste vĂ€ltimine: pahatahtlikel mĂ€ngijatel on palju raskem luua oma pakette petmiseks, neil tuleb reprodutseerida krĂŒptimisreeglid ja leida vĂ”ti (mis muutub iga ĂŒhenduse korral).
Soovitan tungivalt kasutada selleks raamatukogu. Soovitan kasutada , kuna see on eriti lihtne ja tal on suurepĂ€rased Ă”petused. Erakordselt huvitav on Ă”petus , mis vĂ”imaldab igal uuel ĂŒhendusel genereerida uusi vĂ”tmeid.
Rakenduse protokoll: kokkuvÔte
Selle kĂ€igus lĂ”petame rakenduse protokolliga. Arvan, et kokkusurumine ei ole sugugi vajalik ja selle kasutamise otsus sĂ”ltub ainult mĂ€ngust ja nĂ”utavast ribalaiusest. KrĂŒpteerimine on minu meelest kohustuslik, kuid esimeses prototĂŒĂŒbis on sellest mööda saab.
Rakenduse loogika
NĂŒĂŒd suudame klientide seisundit uuendada, kuid vĂ”ime sattuda viivituse probleemide keskele. MĂ€ngija, kes on andmeid sisestanud, peab ootama mĂ€ngu seisundi vĂ€rskendust serverilt, et nĂ€ha, millist mĂ”ju ta maailmale avaldas.
Lisaks sellele on kahe seisundi uuenduse vahel maailm tÀiesti staatiline. Kui seisundite vÀrskendamise sagedus on madal, siis liikumine on vÀga katkendlik.
On mitmeid tehnikaid, mis aitavad selle probleemi mÔju vÀhendada, ja jÀrgmises osas rÀÀgin neist.
Viivituse sujuvuse tehnikad
KÀesolevas jaotises kirjeldatud kÔik tehnikad on pÔhjalikult kÀsitletud seerias Gabriela Gambetta. Soovitan tungivalt lugeda seda suurepÀrast artiklite seeriat. Seal on ka interaktiivne demo, mis vÔimaldab nÀha, kuidas need tehnikad praktikas töötavad.
Esimene tehnika seisneb selles, et rakendatakse sisendi tulemust otse, ootamata serverilt vastust. Seda nimetatakse kliendi poole prognoosimiseks. Siiski, kui klient saab serverilt vÀrskenduse, peab ta veenduma, et tema prognoos oli Ôige. Kui see ei ole nii, peab ta lihtsalt muutma oma olekut vastavalt serverilt saadud teabele, sest server on autoriteetne. Seda tehnikat kasutati esmakordselt mÀngus Quake. Selle kohta saab rohkem lugeda artiklis Fabien Sanglar [ Habr].
Teine tehnikate kogum kasutatakse teiste olendite liikumise sujuvamaks muutmiseks kahe olekuuuenduse vahel. Selle ĂŒlesande lahendamiseks on kaks meetodit: interpolatsioon ja ekstrapolatsioon. Interpolatsiooni puhul vĂ”etakse kaks viimast seisundit ja nĂ€idatakse ĂŒleminekut ĂŒhest teise. Selle puuduseks on see, et see tekitab vĂ€ikese viivituse, kuna klient nĂ€eb alati seda, mis toimus minevikus. Ekstrapolatsioon sĂ”ltub ennustamisest, kus need olendid peaksid praegu asuma, lĂ€htudes kliendile saadud viimasest olekust. Selle puudus on see, et kui olend muudab liikimise suunda tĂ€ielikult, tekib suur erinevus prognoosi ja tegeliku asukoha vahel.
Viimane, kĂ”ige arenenum tehnika, mis on kasulik ainult FPS-ide puhul â see on viivituse kompenseerimine. Lati kompenseerida viivitust, arvestab server mĂ€ngija viivitusi, kui ta sihtmĂ€rkidele tulistab. NĂ€iteks, kui mĂ€ngija tegi oma ekraanil headshot'i, kuid reaalsuses oli tema sihtmĂ€rk viivituse tĂ”ttu mujal, oleks vale keelduda mĂ€ngijalt tapmise Ă”igust viivituse tĂ”ttu. Seega keerab server aega tagasi hetkele, mil mĂ€ngija lasi, et simuleerida, mida mĂ€ngija oma ekraanil nĂ€gi, ja kontrollida kokkupĂ”rget tema lasu ja sihtmargi vahel.
Glen Fiddler (nagu alati!) kirjutas 2004. aastal artikli , millega pani aluse fĂŒĂŒsika simuleerimise sĂŒnkroniseerimisele serveri ja kliendi vahel. 2014. aastal kirjutas ta uue artiklite seeria , kus ta kirjeldas teisi tehnikaid fĂŒĂŒsika simuleerimise sĂŒnkroniseerimiseks.
Ka Valve'i ettevÔtte wikis on kaks artiklit, ja , mis kÀsitlevad viivituste kompenseerimist.
Petmise ennetamine
On olemas kaks peamist tehnikat petmise ennetamiseks.
Esimene: pahatahtlike pakettide saatmise keerukus. Nagu ĂŒlalmainitud, on selle rakendamiseks hea viis krĂŒpteerimine.
Teine: autoritaarne server peab saama ainult kÀske/sisestusi/tegevusi. Klient ei tohiks saada vÔimalust muuta serveri seisundit muud moodi kui sisendi saatmise kaudu. Seega peab server iga kord sisendi saades enne selle rakendamist kontrollima selle lubatavust.
Rakenduse loogika: kokkuvÔte
Soovitan teil rakendada viisi suurte viivituste ja madalate vÀrskendussageduste simuleerimiseks, et testida oma mÀngu kÀitumist kehvades tingimustes, isegi kui klient ja server töötavad samal arvutil. See lihtsustaks viivituste silumisvÔtete rakendamist.
Teised kasulikud ressursid
Kui soovite uurida teisi ressursse, mis on pĂŒhendatud vĂ”rgumudelitele, siis neid leiate siit:
- â tasub lugeda kogu tema blogi, seal on palju suurepĂ€raseid artikleid. sisse on kogutud kĂ”ik artiklid vĂ”rgutehnoloogiate kohta.
- autor M. Fatih MAR â see on pĂ”hjalik nimekiri artiklitest ja videotest videomĂ€ngude vĂ”rgumootoritest.
- V on ka palju kasulikke linke.
Allikas: habr.com
