Algajatele mÀngude vÔrgumudelist

Algajatele mÀngude vÔrgumudelist
Viimased kaks nĂ€dalat olen töötanud oma mĂ€ngu vĂ”rgu mootoriga. Enne seda ei saanud ma ĂŒldse aru mĂ€ngude vĂ”rgutehnoloogiatest, seetĂ”ttu lugesin palju artikleid ja tegin hulganisti katseid, et mĂ”ista kĂ”iki kontseptsioone, et suuta kirjutada oma vĂ”rgu mootor.

Selles juhendis soovin jagada teiega erinevaid kontseptsioone, mida peate uurima enne oma mÀngu mootori kirjutamist, samuti parimaid ressursse ja artikleid nende uurimiseks.

Üldiselt on olemas kaks peamist tĂŒĂŒpi vĂ”rgu arhitektuure: peer-to-peer ja kliendiserver. Peer-to-peer (p2p) arhitektuuris edastatakse andmed igasuguste ĂŒhendatud mĂ€ngijate vahel, kuid kliendiserveri arhitektuuris edastatakse andmeid ainult mĂ€ngijate ja serveri vahel.

Kuigi peer-to-peer arhitektuuri kasutatakse endiselt mÔnedes mÀngudes, on standardiks kliendiserver: see on lihtsam teostada, vajab vÀiksemat ribalaiust ja lihtsustab petmisvastase kaitse rakendamist. SeetÔttu keskendume selles juhendis kliendiserveri arhitektuurile.

Eriti huvitavad meid autoriteetsed serverid: sellistes sĂŒsteemides on server alati Ă”igus. NĂ€iteks, kui mĂ€ngija arvab, et ta asub koordinaatides (10, 5), kuid server ĂŒtleb talle, et ta on koordinaatides (5, 3), siis peab klient asendama oma positsiooni serveri edastatud positsiooniga, mitte vastupidi. Autoriteetsete serverite kasutamine lihtsustab petjate tuvastamist.

MĂ€ngude vĂ”rgusĂŒsteemides on kolm peamist komponenti:

  • Transpordiprotokoll: kuidas andmeid edastatakse klientide ja serveri vahel.
  • Rakendusprotokoll: mida edastatakse klientidelt serverile ja serverilt klientidele ning millises formaadis.
  • Rakenduse loogika: kuidas edastatud andmeid kasutatakse klientide ja serveri oleku uuendamiseks.

On vÀga oluline mÔista iga osa rolli ja nendega seotud raskusi.

Transpordiprotokoll

Esimene samm on valida protokoll andmete edastamiseks serveri ja klientide vahel. Selleks on kaks Interneti-protokolli: TCP ja UDP. Kuid saate luua ka oma transpordiprotokolli selle pÔhjal vÔi kasutada raamatukogu, kus need on kasutusel.

TCP ja UDP vÔrdlus

N tanto TCP kui UDP pÔhinevad IP. IP vÔimaldab paketti edastada allikast saajale, kuid ei garanteeri, et saadetud pakk jÔuab saajani varem vÔi hiljem, vÔi et see saabub vÀhemalt korra ja et paketid jÔuavad Ôiges jÀrjekorras. Veelgi enam, pakk vÔib sisaldada ainult piiratud suuruses andmeid, mis on mÀÀratud suurusega MTU.

UDP on lihtsalt Ă”huke kiht IP kohal. SeetĂ”ttu on tal samad piirangud. Erinevalt sellest, TCP-l on mitmeid omadusi. See tagab usaldusvÀÀrse jĂ€rjekorraga ĂŒhenduse kahe sĂ”lme vahel koos veakontrolliga. Seega on TCP vĂ€ga mugav ja seda kasutatakse paljus muudes protokollides, nĂ€iteks HTTP, FTP ja SMTP. Kuid kĂ”ik need funktsioonid tulevad oma hinnaga: viivitus.

MÔistmaks, miks need funktsioonid vÔivad pÔhjustada viivitust, tuleb aru saada, kuidas TCP töötab. Kui saatja sÔlm edastab paketi vastuvÔtjale, ootab ta kinnitust (ACK). Kui ta teatud aja pÀrast ei saa kinnitust (kuna pakk vÔi kinnitus on kadunud vÔi mÔnel muul pÔhjusel), saadab ta paki uuesti. Veelgi enam, TCP garanteerib, et paketid saadakse Ôiges jÀrjekorras, seega kuni kadunud paketti ei ole saadud, ei saa kÔik teised paketid töötlemiseks lahti vÔtta, isegi kui need on juba vastuvÔtja sÔlme jÔudnud.

Kuid nagu ilmselt 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 efektiivsem kui TCP mitmetel pĂ”hjustel. NĂ€iteks vĂ”ib see mĂ€rgistada mĂ”ned paketid usaldusvÀÀrseteks ja teised — usaldamatuteks. SeetĂ”ttu ei huvita see, kas usaldamatu pakk jĂ”uab saajani. VĂ”i vĂ”ib see hallata mitmeid andmevooge, et ĂŒhes voos kadunud pakk ei aeglustaks teisi vooge. NĂ€iteks vĂ”ib olla voog mĂ€ngija sisendi jaoks ja veel ĂŒks voog jututoas. Kui jututoas kadus sĂ”num, mis ei ole hĂ€davajalik andmestik, ei aeglusta see sisendi aktiveerimist, mis on kriitiline. VĂ”i vĂ”ib oma protokoll rakendada usaldusvÀÀrsust teistmoodi kui TCP, et olla efektiivsem videomĂ€ngude tingimustes.

Nii et, kui TCP on nii halb, siis kas me hakkame looma oma transportprotokolli UDP pÔhjal?

Asjad on veidi keerulisemad. Isegi kui TCP on peaaegu suboptimaalne mĂ€ngu veebisĂŒsteemide jaoks, vĂ”ib see teie mĂ€ngus siiski vĂ€ga hĂ€sti töötada ja sÀÀsta teie vÀÀrtuslikku aega. NĂ€iteks ei pruugi viivitus olla probleem kĂ€igupĂ”hises mĂ€ngus vĂ”i mĂ€ngus, mida saab mĂ€ngida ainult LAN-vĂ”rkudes, kus viivitused ja pakettide kaotus on palju vĂ€iksemad kui Internetis.

Paljudes edukates mÀngudes, sealhulgas World of Warcraft, Minecraft ja Terraria, kasutatakse TCP-d. Kuid enamikes FPS-idest kasutatakse oma UDP-pÔhiseid protokolle, seega rÀÀgime neist allpool lÀhemalt.

Kui otsustate kasutada TCP-d, veenduge, et oleks vĂ€lja lĂŒlitatud Nagle'i algoritm, sest see puhastab pakette enne saatmist, mis tĂ€hendab viivituse suurenemist.

UDP ja TCP erinevuste kohta mitmÀngijamÀngude kontekstis saate lugeda Glen Fidler'i artiklit UDP vs. TCP.

Oma protokoll

Nii et soovite luua oma transportprotokolli, kuid ei tea, kust alustada? Teil on vedanud, kuna Glen Fidler on selle kohta kirjutanud kaks fantastilist artiklit. Neis on palju nutikaid mÔtteid.

Esimene artikkel, Networking for Game Programmers on 2008. aastast ja lihtsam kui teine, Building A Game Network Protocol on 2016. aastast. Soovitan alustada vanemast.

Pange tÀhele, et Glen Fidler on suur oma UDP-pÔhise protokolli kasutamise toetaja. Ja pÀrast tema artiklite lugemist vÔtate tÔenÀoliselt tema seisukoha, et TCP-l on videomÀngudes tÔsiseid puudusi ja soovite ellu viia oma protokolli.

Kuid kui olete vÔrgu töödes uus, siis tehke endale teene ja kasutage TCP-d vÔi mÔnda raamatukogu. Oma transportprotokolli edukaks rakendamiseks peate eelnevalt palju Ôppima.

VÔrguraamatukogud

Kui vajate midagi tĂ”husamat kui TCP, kuid ei soovi oma protokolli rakendamisega vaeva nĂ€ha ja paljudesse ĂŒksikasjadesse sĂŒveneda, saate kasutada vĂ”rguraamatukogu. Neid on vĂ€ga palju:

Ma ei ole neid kÔiki proovinud, kuid eelistan ENet'i, kuna see on kasutajasÔbralik ja usaldusvÀÀrne. Samuti on sellel arusaadav dokumentatsioon ja algajatele mÔeldud juhend.

Transportprotokoll: kokkuvÔte

KokkuvÔttes on olemas kaks peamist transportprotokolli: TCP ja UDP. TCP-l on palju kasulikke omadusi: usaldusvÀÀrsus, pakettide jÀrjekorra sÀilitamine, vigade tuvastamine. UDP-l seda ei ole, kuid TCP-l on loomulikult suuremad viivitused, mis ei sobi mÔnede mÀngude jaoks. Seega, et tagada madalad viivitused, vÔib luua oma protokolli UDP pÔhjal vÔi kasutada teeki, mis rakendab UDP-l pÔhinevat transportprotokolli ja on kohandatud mitmikmÀngude jaoks.

Valik TCP, UDP ja teeki vahel sÔltub mitmest tegurist. Esiteks mÀngu vajadustest: kas on vajalikud madalad viivitused? Teiseks rakenduse protokolli nÔuetest: kas on vaja usaldusvÀÀrset protokolli? Nagu nÀeme jÀrgmistest osadest, vÔib luua rakenduse protokolli, mille jaoks sobib tÀiesti usaldusvÀÀrne protokoll. LÔpuks tuleb arvestada ka vÔrgu mootori arendaja kogemustega.

Mul on kaks soovitust:

  • Maksimaalselt abstraktselt transportprotokolli ĂŒlejÀÀnud rakendusest, et seda oleks vĂ”imalik lihtsalt vahetada, ilma et peaksite kogu koodi ĂŒmber kirjutama.
  • Ärge tegelege enneaegse optimeerimisega. Kui te pole vĂ”rgu spetsialist ja ei ole kindel, kas vajate UDP pĂ”hist oma transportprotokolli, siis vĂ”ite alustada TCP-st vĂ”i teegist, mis tagab usaldusvÀÀrsuse, ning seejĂ€rel testida ja mÔÔta jĂ”udlust. Kui tekivad probleemid ja olete kindel, et pĂ”hjuseks on transportprotokoll, siis vĂ”ib-olla on aeg luua oma transportprotokoll.

KÀesoleva osa lÔpetuseks soovitan lugeda Multiplayer MÀngu Programmeerimise Sissejuhatus Bryan Hook'i poolt, kus kÀsitletakse palju siin arutatud teemasid.

Rakenduse protokoll

NĂŒĂŒd, kui me saame andmeid vahetada kliendi ja serveri vahel, tuleb otsustada, milliseid andmeid edastada ja millises formaadis.

Klassikaline skeem on see, et kliendid saadavad serverile sisendi vĂ”i toimingud, samas kui server saadab klientidele nĂŒĂŒdse mĂ€ngu oleku.

Server saadab mitte tÀielikku, vaid filtreeritud olekut koos mÀngijaga lÀhedal asuvate objektidega. Ta teeb seda kolmel pÔhjusel. Esiteks vÔib tÀielik olek edastamisel olla liiga suur, et seda sagedasti edastada. Teiseks huvitavad kliente peamiselt visuaalsed ja helidata, kuna suurem osa mÀngulogikast simuleeritakse mÀngu serveris. Kolmandaks, mÔnedes mÀngudes 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 Àra tappa.

Serialiseerimine

Esimene samm on andmete, mida soovime edastada (sisend vÔi mÀnguolek), teisendamine edastamiseks sobivasse formaati. Seda protsessi nimetatakse serialiseerimiseks.

Esimesena tuleb meelde mÔte kasutada inimloetavat formaati, nÀiteks JSON vÔi XML. Kuid see oleks tÀiesti ebatÔhus ja raiskaks suure osa kanalist.

SeetÔttu on soovitatav kasutada binaarfaili formaati, mis on palju kompaktsem. See tÀhendab, et paketid sisaldavad vaid mÔnda bitti. Siin tuleb arvesse vÔtta bitti jÀrjekorda, mis vÔib erinevates arvutites erineda.

Andmete serialiseerimiseks vÔib kasutada erinevaid teeke, nÀiteks:

Lihtsalt veenduge, et teek loob kantavaid arhiive ja hoolitseb bitti jÀrjekorra eest.

Alternatiivne lahendus vÔiks olla ise teostamine, see ei ole eriti keeruline, eriti kui teie koodis kasutatakse andmeorienteeritud lÀhenemist. Lisaks vÔimaldab see teil teostada optimeerimisi, mis ei pruugi alati olla vÔimalik teegi kasutamise korral.

Glenn Fidler on kirjutanud serialiseerimisest kaks artiklit: Pakettide lugemine ja kirjutamine ja Serialiseerimisstrateegiad.

Kompressioon

Andmete hulk, mis edastatakse klientide ja serveri vahel, on piiratud kanali lÀbilaskevÔimega. Andmete tihendamine vÔimaldab edastada igas snapshots rohkem andmeid, suurendada vÀrskendussagedust vÔi lihtsalt vÀhendada kanali nÔudeid.

Biti pakkimine

Esimene tehnika on bitipakendamine. See seisneb just nii palju bite kasutamises, kui on vajalik soovitud vÀÀrtuse kirjeldamiseks. NĂ€iteks, kui teil on loend, mis vĂ”ib omada 16 erinevat vÀÀrtust, siis vĂ”ib ĂŒhe tĂ€isbaiti (8 bitti) asemel kasutada vaid 4 bitti.

Glenn Fiddler selgitab, kuidas seda ellu viia, artikli teises osas. Pakettide lugemine ja kirjutamine.

Bitipakendamine toimib eriti hÀsti diskreetsuse korral, mis on jÀrgmise osa teema.

Diskreetsus

Diskreetsus on kaotusega kompressioonitehnika, mis seisneb selles, et vÀÀrtuse kodeerimiseks kasutatakse ainult osade valikute alamhulka. Diskreetsuse rakendamine on kĂ”ige lihtsam ujukoma numbrite ĂŒmardamise teel.

Glenn Fiddler (taas!) nÀitab, kuidas rakendada diskreetsust praktikas, oma artiklis. Snapshot Compression.

Kompressioonialgoritmid

JĂ€rgmine tehnika on kaotusteta kompressioonialgoritmid.

Siin on minu arvates kolm kÔige huvitavamat algoritmi, millest peaks teadma:

  • NĂŒĂŒd, kui oleme tutvunud muutuva pikkusega kodeerimise ja eelseisva reegliga, rÀÀgime Huffmani kodeerimisest. eelnevalt arvutatud koodiga, mis on ÀÀrmiselt kiire ja vĂ”ib anda hĂ€id tulemusi. Seda on kasutatud pakettide kompressiooniks Quake3 vĂ”rgu mootoris.
  • zlib on ĂŒldotstarbeline kompressioonialgoritm, mis ei suurenda kunagi andmete mahtu. Kuidas nĂ€ha siin, on seda rakendatud paljudes rakendustes. Oleks see vĂ”ib-olla ĂŒlearune olekute vĂ€rskendamiseks. Aga see vĂ”ib ka osutuda kasulikuks, kui peate serverilt klientidele edastama varasid, pikki tekste vĂ”i maanĂ”gusid.
  • Pikkade jadade kopeerimine on tĂ”enĂ€oliselt kĂ”ige lihtsam kompressioonialgoritm, kuid see on teatud tĂŒĂŒpi andmete jaoks vĂ€ga tĂ”hus ja seda saab kasutada eeltöötluse etapina enne zlib-i. See sobib eriti hĂ€sti maanĂ”gude kompressiooniks, mis koosneb plaadist vĂ”i vookidest, kus palju naaber-elemente kordub.

Delta-kompressioon

Viimane kompressioonimeetod on delta-kompressioon. See seisneb selles, et edastatakse ainult erinevused praeguse mÀngu oleku ja viimase seisundi vahel, mille klient on saanud.

Esmakordselt rakendati seda Quake3 vÔrgu mootoris. Siin on kaks artiklit, mis selgitavad selle kasutamise viisi:

Glenn Fiddler kasutas seda ka oma artikli teises osas. Snapshot Compression.

KrĂŒpteerimine

Lisaks peate vĂ”ib-olla krĂŒpteerima teabe edastamise klientide ja serveri vahel. Sellel on mitu pĂ”hjust:

  • privaatsus: sĂ”numeid saavad lugeda ainult vastReceiving, ja mitte ĂŒkski teine isik, kes teostab vĂ”rgu nuhkimist, ei saa neid lugeda.
  • autentimine: isik, kes soovib mĂ€ngija rolli tĂ€ita, peab teadma tema vĂ”tit.
  • pettuste vĂ€ltimine: pahatahtlikel mĂ€ngijatel on palju keerulisem luua oma pakette petmiseks, nad peavad paljundama krĂŒptimise skeemi ja leidma vĂ”tme (mis muutub iga ĂŒhenduse korral).

Soovitan tungivalt kasutada selleks raamatukogu. Soovitan kasutada libsodium, kuna see on eriti lihtne ja sellel on suurepĂ€rased Ă”petused. Erakordselt huvitav on Ă”petus vĂ”tmevahetusest, mis vĂ”imaldab genereerida uusi vĂ”tmeid iga uue ĂŒhenduse korral.

Rakenduse protokoll: kokkuvÔte

Sellega lĂ”petame rakenduse protokolli. Arvan, et tihendamine ei ole sugugi vajalik ja otsus selle kasutamiseks sĂ”ltub ainult mĂ€ngust ja nĂ”utud ribalaiusest. KrĂŒptimine on minu arust hĂ€davajalik, kuid esimeses prototĂŒĂŒbis saab sellest loobuda.

Rakenduse loogika

NĂŒĂŒd oleme vĂ”imelised vĂ€rskendama olekut kliendis, kuid vĂ”ime toime tulla viivituste probleemidega. MĂ€ngijal, kes teostab sisestamise, tuleb oodata serverilt mĂ€ngu oleku vĂ€rskendust, et nĂ€ha, millist mĂ”ju ta maailmale avaldas.

Veelgi enam, kahe oleku vĂ€rskenduse vahel on maailm tĂ€iesti staatiline. Kui oleku vĂ€rskendamise sagedus on madal, on liikumine vĂ€ga hĂŒplik.

On mitmeid tehnikaid, mis aitavad seda probleemi leevendada, ja jĂ€rgmises peatĂŒkis rÀÀgin nendest.

Viivituste silumise tehnikad

KĂ”ik selles peatĂŒkis kirjeldatud tehnikad on ĂŒksikasjalikult kĂ€sitletud seerias Fast-Paced Multiplayer Gabriela Gambettalt. Soovitan tungivalt lugeda seda suurepĂ€rast artiklite seeriat. Seal on ka interaktiivne demo, mis vĂ”imaldab nĂ€ha, kuidas need tehnikad praktikas toimivad.

Esimene tehnika seisneb sisendi tulemuse otseses kasutamises, ootamata serverilt vastust. Seda nimetatakse kliendipoolseks prognoosimiseks.. Kuid kui klient saab serverilt uuenduse, peab ta veenduma, et tema prognoos oli Ôige. Kui see nii ei ole, peab ta lihtsalt muutma oma staatust vastavalt serverilt saadud teabele, kuna server on autoriteetne. Seda tehnikat kasutati esmakordselt mÀngus Quake. Lisainfot selle kohta on vÔimalik leida artiklist. Quake Enginei koodiarvustus Fabien Sanglar [tÔlge Habrists].

Teine tehnikate kogum kasutatakse teiste olendite liikumise sujuvamaks muutmiseks kahe olekuuuenduse vahel. Selle ĂŒlesande lahendamiseks on kaks meetodit: interpoleerimine ja ekstrapoleerimine. Interpoleerimise korral vĂ”etakse kaks viimast staatust ja nĂ€idatakse ĂŒleminekut ĂŒhest teise. Selle puuduseks on, et see tekitab vĂ€ikest viivitust, kuna klient nĂ€eb alati seda, mis juhtus minevikus. Ekstrapoleerimine seisneb selles, et ennustatakse, kus peaksid sel ajal olendid asuma, tuginedes kliendi viimasele saadud olekule. Selle puuduseks on, et kui olend muudab liikumise suunda, siis tekib suur viga prognoosi ja tegeliku positsiooni vahel.

Viimane, kĂ”ige arenenum tehnika, mis on kasulik ainult FPS-is — see on viivituse kompenseerimine. Viivituse kompenseerimise puhul arvestab server kliendi viivitusi, kui ta sihtmĂ€rki tulistab. NĂ€iteks, kui mĂ€ngija tegi hiirelöögi oma ekraanil, kuid tegelikult oli tema sihtmĂ€rg viivituse tĂ”ttu teises kohas, oleks ebaaus keelduda mĂ€ngijalt tapmise Ă”igust viivituse tĂ”ttu. SeetĂ”ttu teeb server aja tagasi kerimise hetkel, mil mĂ€ngija tulistas, et simuleerida seda, mida mĂ€ngija oma ekraanil nĂ€gi, ja kontrollida kokkupĂ”rget tema tulistamise ja sihtmĂ€rgi vahel.

Glen Fiddler (nagu alati!) kirjutas 2004. aastal artikli Network Physics (2004), milles pandi alus fĂŒĂŒsikasimulatsiooni sĂŒnkroniseerimisele serveri ja kliendi vahel. 2014. aastal kirjutas ta uue artiklite sarja Networking Physics, milles kirjeldati muid tehnikaid fĂŒĂŒsikasimulatsiooni sĂŒnkroniseerimiseks.

Valve'i wiki-s on ka kaks artiklit, Source Multiplayer Networking ja Viivituse kompenseerimise meetodid kliendi/serveri mÀnguprotokolli kujunduses ja optimeerimisel , milles kÀsitletakse viivituste kompenseerimist.

Petmise tÔkestamine

On kaks peamist tehnikat petmise Àrahoidmiseks.

Esite: petukate saatmine petudelt. Nagu juba mainitud, on hea viis selle rakendamiseks krĂŒpteerimine.

Teine: autoritaarne server peab saama ainult kÀske/sisestusi/tegevusi. Klient ei tohiks omada vÔimalust serveri olekut muuta, vÀlja arvatud sisendi saatmise teel. SeetÔttu peab server iga kord, kui see sisendi saab, enne selle rakendamist kontrollima selle lubatavust.

Rakenduse loogika: jÀreldus

Soovitan teil ellu viia meetodi suurte viivituste ja madalate uuendussagedustega simuleerimiseks, et testida oma mÀngu kÀitumist halvas keskkonnas, isegi kui klient ja server töötavad samal arvutis. See lihtsustab viivituste silumise meetodite rakendamist.

Teised kasulikud ressursid

Kui soovite uurida teisi ressursse, mis on pĂŒhendatud vĂ”rgumudelitele, leiate need siit:

  • Glen Fiedleri blogi — tasub lugeda tema kogu blogi, kus on palju suurepĂ€raseid artikleid. Siin kĂ”ik artiklid, mis kĂ€sitlevad vĂ”rgutehnoloogiaid.
  • Awesome Game Networking autor M. Fatih MAR — see on ĂŒksikasjalik loend artiklitest ja videotest videomĂ€ngude vĂ”rgumootorite kohta.
  • Uues subredditi r/gamedev wiki ka on palju kasulikke linke.

Allikas: habr.com

Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid đŸ”„ Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid | ProHoster