Hasiberrientzako jokoetan sare-ereduari buruz

Hasiberrientzako jokoetan sare-ereduari buruz
Azken bi asteetan nire jokorako sareko motorra lantzen aritu naiz. Hori baino lehen, ez nekien ezer jokoetan saretzeari buruz, beraz, artikulu asko irakurri eta esperimentu asko egin nituen kontzeptu guztiak ulertzeko eta nire sareko motorra idatzi ahal izateko.

Gida honetan, zure joko-motorra idatzi aurretik ikasi behar dituzun hainbat kontzeptu, baita horiek ikasteko baliabide eta artikulu onenak ere partekatu nahi ditut.

Oro har, bi sare-arkitektura mota nagusi daude: parekidea eta bezero-zerbitzaria. Peer-to-peer (p2p) arkitektura batean, datuak konektatutako edozein jokalari bikoteren artean transferitzen dira, bezero-zerbitzariaren arkitekturan, berriz, datuak jokalarien eta zerbitzariaren artean soilik transferitzen dira.

Zenbait jokotan peer-to-peer arkitektura oraindik erabiltzen den arren, bezero-zerbitzaria da estandarra: inplementatzeko errazagoa da, kanal zabalera txikiagoa behar du eta iruzurretik babestea errazten du. Horregatik, gida honetan, bezero-zerbitzariaren arkitekturan zentratuko gara.

Bereziki, zerbitzari autoritarioak interesatzen zaizkigu gehien: halako sistemetan zerbitzariak beti du arrazoia. Adibidez, jokalariak (10, 5)-n dagoela uste badu eta zerbitzariak (5, 3-an dagoela) esaten badio, bezeroak bere posizioa zerbitzariak jakinaraziko duenarekin ordezkatu beharko luke, ez alderantziz. Zerbitzari autoritarioak erabiltzeak iruzurgileak antzematea errazten du.

Joko-sare-sistemetan hiru osagai nagusi daude:

  • Garraio-protokoloa: nola transferitzen diren datuak bezeroen eta zerbitzariaren artean.
  • Aplikazio-protokoloa: bezeroetatik zerbitzarira eta zerbitzaritik bezeroetara zer transmititzen den, eta zer formatuan.
  • Aplikazio-logika: transmititutako datuak nola erabiltzen diren bezeroen eta zerbitzariaren egoera eguneratzeko.

Oso garrantzitsua da zati bakoitzaren eginkizuna eta haiei lotutako zailtasunak ulertzea.

Garraio protokoloa

Lehen urratsa zerbitzariaren eta bezeroen artean datuak garraiatzeko protokolo bat aukeratzea da. Bi Internet protokolo daude horretarako: TCP и UDP. Baina horietako batean oinarrituta zure garraio-protokolo propioa sor dezakezu edo haiek erabiltzen dituen liburutegi bat erabil dezakezu.

TCP eta UDP konparaketa

TCP eta UDP-n oinarritzen dira IP. IP-ak pakete bat iturburu batetik hartzaile batera transmititzea ahalbidetzen du, baina ez du bermatzen bidalitako paketea lehenago edo beranduago hartzailera iritsiko denik, gutxienez behin iritsiko denik eta paketeen sekuentzia sartuko denik. ordena zuzena. Gainera, pakete batek datu-tamaina mugatua bakarrik eduki dezake, balioak emandakoa MTU.

UDP IParen gainean geruza mehe bat besterik ez da. Horregatik, muga berdinak ditu. Aitzitik, TCPk ezaugarri asko ditu. Bi nodoen arteko konexio ordenatu fidagarria eskaintzen du erroreen egiaztapenarekin. Hori dela eta, TCP oso erosoa da eta beste protokolo askotan erabiltzen da, adibidez, urtean HTTP, FTP и SMTP. Baina ezaugarri hauek guztiek prezio bat dute: atzerapena.

Funtzio horiek zergatik eragin dezaketen latentzia ulertzeko, TCP nola funtzionatzen duen ulertu behar dugu. Ostalari igorleak pakete bat igortzen dionean ostalari hartzaileari, aitorpen bat (ACK) jasotzea espero du. Denbora jakin baten buruan ez badu jasotzen (paketea edo berrespena galdu delako edo beste arrazoiren batengatik), paketea berriro bidaltzen du. Gainera, TCP-k paketeak ordena egokian jasotzen direla bermatzen du, beraz, galdutako pakete bat jaso arte, beste pakete guztiak ezin dira prozesatu, nahiz eta nodo hartzaileak dagoeneko jaso dituen.

Baina ziurrenik ulertzen duzunez, jokalari anitzeko jokoetan latentzia oso garrantzitsua da, batez ere FPS bezalako genero aktiboetan. Horregatik, joko askok UDP erabiltzen dute bere protokoloarekin.

UDPn oinarritutako jatorrizko protokoloa TCP baino eraginkorragoa izan daiteke hainbat arrazoirengatik. Adibidez, pakete batzuk fidagarri gisa markatu ditzake eta beste batzuk fidagarri gisa. Hori dela eta, ez dio axola fidagarria den paketea hartzailearengana iritsi ote den. Edo hainbat datu-korronte prozesatu ditzake korronte batean galdutako pakete batek beste korronte batzuk motel ez ditzan. Esaterako, baliteke jokalariaren sarrerarako hari bat egotea eta beste hari bat txat-mezuetarako. Premiazko datuak ez diren txat-mezu bat galtzen bada, ez du premiazkoa den sarrera motelduko. Edo jabedun protokolo batek fidagarritasuna ezar dezake TCP baino modu ezberdinean bideo-jokoen ingurunean eraginkorragoa izateko.

Beraz, TCP txundigarria bada, orduan gure garraio-protokolo propioa eraikiko dugu UDPn oinarrituta?

Dena apur bat konplikatuagoa da. TCP joko-sare-sistemetarako ia ezin hobea den arren, zure joko zehatzerako nahiko ondo funtziona dezake eta denbora baliotsua aurreztu dezakezu. Esate baterako, baliteke latentzia ez izatea txandakako joko batentzat edo LAN sareetan soilik jokatu daitekeen joko batentzat, non latentzia eta pakete-galera Interneten baino askoz txikiagoa den.

Joko arrakastatsu askok, World of Warcraft, Minecraft eta Terraria barne, TCP erabiltzen dute. Hala ere, FPS gehienek beren UDPn oinarritutako protokoloak erabiltzen dituzte, beraz, behean gehiago hitz egingo dugu.

TCP erabiltzea aukeratzen baduzu, ziurtatu desgaituta dagoela Nagle-ren algoritmoa, bidali aurretik paketeak buffer egiten dituelako, hau da, atzerapena areagotzen du.

Jokalari anitzeko jokoen testuinguruan UDP eta TCPren arteko desberdintasunei buruz gehiago jakiteko, ikusi Glenn Fiedler-en artikulua. UDP vs. TCP.

Protokolo jabeduna

Beraz, zure garraio-protokolo propioa sortu nahi duzu baina ez dakizu nondik hasi? Zorte ona duzu, Glenn Fiedlerrek bi artikulu harrigarri idatzi zituelako horri buruz. Ideia adimentsu asko aurkituko dituzu horietan.

Lehenengo artikulua Joko-programatzaileentzako sareak 2008, bigarrena baino errazagoa Joko sareko protokoloa eraikitzea 2016. Zaharrenetik hastea gomendatzen dizut.

Kontuan izan Glenn Fiedler-ek UDPn oinarritutako zure protokolo propioa erabiltzearen aldekoa dela. Eta bere artikuluak irakurri ondoren, ziurrenik bere iritzia hartuko duzu TCPk bideo-jokoetan eragozpen larriak dituela, eta zure protokolo propioa ezarri nahi izango duzu.

Baina sarean hasi berria bazara, egin mesede bat eta erabili TCP edo liburutegi bat. Zure garraio-protokoloa arrakastaz ezartzeko, asko ikasi behar duzu aldez aurretik.

Sareko liburutegiak

TCP baino zerbait eraginkorragoa behar baduzu, baina ez baduzu zure protokolo propioa inplementatzen eta xehetasun asko sartu nahi, sareko liburutegia erabil dezakezu. Asko dira:

Ez ditut denak probatu, baina ENet nahiago dut erabiltzeko erraza eta fidagarria delako. Horrez gain, dokumentazio argia eta hasiberrientzako tutorial bat ditu.

Garraio Protokoloaren Ondorioa

Laburbilduz, bi garraio-protokolo nagusi daude: TCP eta UDP. TCP-k ezaugarri erabilgarriak ditu: fidagarritasuna, paketeen ordena mantentzea, akatsak hautematea. UDP-k ez du hori guztia, baina TCPk, bere izaeragatik, joko batzuentzat onartezina den latentzia handia du. Hau da, latentzia txikia bermatzeko, zure protokolo propioa sor dezakezu UDPn oinarrituta edo UDPn garraio-protokoloa inplementatzen duen eta jokalari anitzeko bideo-jokoetarako egokituta dagoen liburutegi bat erabil dezakezu.

TCP, UDP eta liburutegiaren artean aukeratzea hainbat faktoreren araberakoa da. Lehenik eta behin, jokoaren beharretatik: latentzia txikia behar al du? Bigarrenik, aplikazio-protokoloaren eskakizunetatik: behar al du protokolo fidagarririk? Hurrengo zatian ikusiko dugunez, posible da aplikazio-protokolo bat sortzea, zeinetarako fidagarria ez den protokoloa nahiko egokia den. Azkenik, sare-motorren garatzailearen esperientzia ere kontuan hartu behar duzu.

Bi aholku dauzkat:

  • Garraio-protokoloa gainerako aplikazioetatik ahalik eta gehien abstraitu, erraz ordezkatu ahal izateko kode guztia berridatzi gabe.
  • Ez gehiegi optimizatu. Sareko aditua ez bazara eta ziur ez bazaude zure UDPn oinarritutako garraio-protokolo propioa behar duzun, TCP edo fidagarritasuna eskaintzen duen liburutegi batekin has zaitezke, eta gero probatu eta neurtu errendimendua. Arazoak badituzu eta ziur bazaude garraio-protokolo bat dela, baliteke zure garraio-protokoloa sortzeko garaia izatea.

Zati honen amaieran, irakurtzea gomendatzen dizut Jokalari anitzeko jokoen programazioaren hastapena Brian Hook, hemen eztabaidatutako gai asko biltzen dituena.

Aplikazio-protokoloa

Bezeroen eta zerbitzariaren artean datuak trukatu ditzakegun orain, zer datu transferitu eta zein formatutan erabaki behar dugu.

Eskema klasikoa bezeroei sarrera edo ekintzak bidaltzen dizkiela zerbitzariari, eta zerbitzariak uneko jokoaren egoera bidaltzen diela bezeroei.

Zerbitzariak ez du egoera osoa bidaltzen, erreproduzitzailetik gertu dauden entitateekin iragazitako egoera baizik. Hiru arrazoirengatik egiten du hori. Lehenik eta behin, egoera osoa handiegia izan daiteke maiztasun altuan transmititzeko. Bigarrenik, bezeroak batez ere ikusizko eta audioko datuetan interesatzen dira, jokoaren logika gehiena joko zerbitzarian simulatzen delako. Hirugarrenik, joko batzuetan jokalariak ez ditu datu jakin batzuk ezagutu behar, maparen beste aldean dagoen etsaiaren posizioa adibidez, zeren bestela paketeak usain ditzake eta bera hiltzeko nora mugitu behar den jakin dezakeelako.

Serializazioa

Lehenengo urratsa bidali nahi ditugun datuak (sarrera edo jokoaren egoera) transmisiorako egokia den formatu batean bihurtzea da. Prozesu honi deitzen zaio serializazioa.

Gizakiek irakur daitekeen formatu bat erabiltzeko ideia berehala datorkit burura, hala nola JSON edo XML. Baina hau guztiz eraginkorra izango da eta kanalaren zatirik handiena hartuko du ezertarako.

Horren ordez, formatu bitarra erabiltzea gomendatzen da, askoz trinkoagoa dena. Hau da, paketeek byte batzuk baino ez dituzte edukiko. Hemen arazoa kontuan hartu behar dugu byteen ordena, ordenagailu desberdinetan desberdina izan daitekeena.

Datuak serializatzeko, liburutegi bat erabil dezakezu, adibidez:

Ziurtatu liburutegiak artxibo eramangarriak sortzen dituela eta endiantasuna zaintzen duela.

Soluzio alternatibo bat zuk zeuk ezartzea izango litzateke, ez da hain zaila, batez ere zure kodean datuetan oinarritutako ikuspegia erabiltzen ari bazara. Horrez gain, liburutegia erabiltzean beti posible ez diren optimizazioak egiteko aukera emango du.

Glenn Fiedlerrek bi artikulu idatzi ditu serializazioari buruz: Irakurketa eta idazketa paketeak и Serializazio-estrategiak.

Konpresioa

Bezeroen eta zerbitzariaren artean transferitzen den datu kopurua kanalaren banda zabalerak mugatzen du. Datuen konpresioak argazki bakoitzean datu gehiago transferitzeko, freskatze-tasa handitzeko edo banda-zabalera eskakizunak murrizteko aukera emango dizu.

Bit ontziratzea

Lehenengo teknika bit paketatzea da. Nahi den balioa deskribatzeko behar den bit kopurua zehazki erabiltzean datza. Adibidez, 16 balio ezberdin izan ditzakeen enumerazio bat baduzu, byte oso baten ordez (8 bit), 4 bit besterik ez dituzu erabil dezakezu.

Glenn Fiedlerrek hau nola inplementatu azaltzen du artikuluaren bigarren zatian. Irakurketa eta idazketa paketeak.

Bit paketatzeak bereziki ondo funtzionatzen du diskretizazioarekin, hurrengo ataleko gaia izango dena.

Laginketa

Laginketa balio posibleen azpimultzo bat soilik erabiltzen duen konpresio galerazko teknika da, balio bat kodetzeko. Diskretizazioa ezartzeko modurik errazena koma mugikorreko zenbakiak biribiltzea da.

Glenn Fiedlerrek (berriz!) diskretizazioa praktikan nola aplikatu erakusten du bere artikuluan Argazkien konpresioa.

Konpresioaren algoritmoak

Hurrengo teknika galerarik gabeko konpresio algoritmoak izango dira.

Hona hemen, nire ustez, ezagutu behar dituzun hiru algoritmo interesgarrienak:

  • Huffman kodeketa aurrez kalkulatutako kodearekin, oso azkarra dena eta emaitza onak eman ditzakeena. Quake3 sare-motorrean paketeak konprimitzeko erabiltzen zen.
  • zlib helburu orokorreko konpresio-algoritmo bat da, inoiz datu kopurua handitzen ez duena. Nola ikusten duzu Hemen, hainbat aplikaziotan erabili izan da. Egoerak eguneratzeko, baliteke erredundantea izatea. Baina erabilgarria izan daiteke zerbitzaritik bezeroei aktiboak, testu luzeak edo lurrak bidali behar badituzu.
  • Korrika luzeak kopiatzea ziurrenik konpresio-algoritmorik errazena da, baina oso eraginkorra da datu mota batzuetarako, eta zlib aurretik prozesatzeko urrats gisa erabil daiteke. Bereziki egokia da ondoko elementu asko errepikatzen diren teila edo voxel osatutako lursaila konprimitzeko.

delta konpresioa

Azken konpresioaren teknika delta konpresioa da. Uneko joko-egoeraren eta bezeroak jasotako azken egoeraren arteko desberdintasunak soilik transmititzen direlako datza.

Lehen Quake3 sareko motorra erabili zen. Hona hemen nola erabili azaltzen duten bi artikulu:

Glenn Fiedlerrek ere erabili zuen bere artikuluaren bigarren zatian. Argazkien konpresioa.

enkriptatze

Horrez gain, baliteke bezeroen eta zerbitzariaren arteko informazioaren transmisioa zifratu behar izatea. Hainbat arrazoi daude horretarako:

  • Pribatutasuna/Konfidentzialtasuna: Mezuak hartzaileak bakarrik irakur ditzake eta beste sare-sniffer-ek ezingo ditu irakurri.
  • autentifikazioa: jokalari baten papera jokatu nahi duen pertsonak bere giltza ezagutu behar du.
  • iruzurrak prebenitzea: jokalari gaiztoentzat askoz zailagoa izango da beren iruzurra paketeak sortzea, enkriptazio-eskema errepikatu eta gakoa aurkitu beharko dute (konexio bakoitzean aldatzen dena).

Horretarako liburutegi bat erabiltzea gomendatzen dut. erabiltzea proposatzen dut libsodioa, bereziki sinplea delako eta tutorial bikainak dituelako. Bereziki interesgarria da tutoriala gako-trukea, konexio berri bakoitzean gako berriak sortzeko aukera ematen duena.

Aplikazio-protokoloa: Ondorioa

Honek aplikazio-protokoloa amaitzen du. Uste dut konpresioa guztiz hautazkoa dela eta erabiltzeko erabakia jokoaren eta beharrezko banda zabaleraren araberakoa soilik. Enkriptatzea, nire ustez, derrigorrezkoa da, baina lehen prototipoan gabe egin dezakezu.

Aplikazio Logika

Orain bezeroaren egoera eguneratzeko gai gara, baina baliteke latentzia arazoak izatea. Jokalariak, sarrera bat egin ondoren, zerbitzariaren jokoaren egoera eguneratzearen zain egon behar du munduan zer eragin izan duen ikusteko.

Gainera, bi estatu eguneratzeen artean, mundua guztiz estatikoa da. Egoeraren eguneratze-tasa baxua bada, orduan mugimenduak oso aldrebesak izango dira.

Arazo honen eragina arintzeko hainbat teknika daude, eta hurrengo atalean azalduko ditut.

Atzerapena Leuntzeko Teknikak

Atal honetan deskribatutako teknika guztiak zehatz-mehatz eztabaidatzen dira seriean. Jokalari anitzeko erritmo azkarra Gabriel Gambetta. Oso gomendatzen dut artikulu sorta bikain hau irakurtzea. Teknika hauek praktikan nola funtzionatzen duten ikusteko demo interaktibo bat ere sartzen da.

Lehenengo teknika sarrerako emaitza zuzenean aplikatzea da zerbitzariaren erantzunaren zain egon gabe. Deitzen da bezeroaren aldetik aurreikuspena. Hala ere, bezeroak zerbitzariaren eguneraketa bat jasotzen duenean, bere iragarpena zuzena zela egiaztatu behar du. Hori horrela ez bada, zerbitzaritik jasotakoaren arabera bere egoera aldatu besterik ez du behar, zerbitzaria autoritarioa delako. Teknika hau Quake-n erabili zen lehen aldiz. Artikuluan horri buruz gehiago irakur dezakezu. Quake Engine kodearen berrikuspena Fabien Sanglars [itzulpen Habré-n].

Bigarren teknika multzoa beste entitateen mugimendua leuntzeko erabiltzen da bi egoera-eguneratzeen artean. Arazo hau konpontzeko bi modu daude: interpolazioa eta estrapolazioa. Interpolazioaren kasuan, azken bi egoerak hartzen dira eta batetik besterako trantsizioa erakusten da. Bere desabantaila da atzerapenaren zati txiki bat eragiten duela, bezeroak beti ikusten duelako iraganean gertatutakoa. Estrapolazioa entitateek orain non egon behar duten aurreikustea da, bezeroak jasotako azken egoeran oinarrituta. Bere desabantaila da entitateak mugimenduaren norabidea guztiz aldatzen badu, iragarpenaren eta benetako posizioaren artean errore handia egongo dela.

Azken teknika aurreratuena, FPS-n bakarrik erabilgarria da atzerapenaren konpentsazioa. Lag-konpentsazioa erabiltzean, zerbitzariak bezeroaren atzerapenak kontuan hartzen ditu helburura tiro egiten duenean. Adibidez, jokalari batek bere pantailan buruko jaurtiketa bat egiten badu, baina errealitatean bere helburua atzerapenaren ondorioz beste kokapen batean zegoen, orduan bidegabea izango litzateke jokalariari atzerapenagatik hiltzeko eskubidea ukatzea. Beraz, zerbitzariak denbora atzera egiten du jokalariak tiro egin zuenean jokalariak pantailan ikusi zuena simulatzeko eta tiroaren eta helburuaren artean talkarik dagoen egiaztatzeko.

Glenn Fiedlerrek (beti bezala!) artikulu bat idatzi zuen 2004an Sareko Fisika (2004), bertan zerbitzariaren eta bezeroaren arteko fisikako simulazioak sinkronizatzeko oinarriak ezarri zituen. 2014an artikulu sorta berri bat idatzi zuen sarearen fisika, eta bertan, fisikako simulazioak sinkronizatzeko beste teknika batzuk deskribatu zituen.

Valve-ren wikian bi artikulu ere badaude, Iturria Jokalari Anitzeko Sarea и Latentzia konpentsatzeko metodoak Bezero/Zerbitzariaren joko barruko protokoloaren diseinuan eta optimizazioan atzerapen-konpentsazioari aurre egitea.

Iruzurren Prebentzioa

Bi iruzurra prebenitzeko teknika nagusi daude.

Lehenik eta behin, iruzurgileei pakete gaiztoak bidaltzea zailduz. Goian esan bezala, ezartzeko modu ona enkriptatzea da.

Bigarrenik, zerbitzari autoritarioak komandoak/sarrerak/ekintzak soilik jaso beharko lituzke. Bezeroak ezingo luke zerbitzariaren egoera aldatu sarrera bidaliz baino. Orduan zerbitzariak, sarrera jasotzen duen bakoitzean, baliozkotasuna egiaztatu behar du aplikatu aurretik.

Aplikazio-logika: Ondorioa

Latentzia handia eta freskatze tasa baxuak simulatzeko modu bat ezartzea gomendatzen dizut, zure jokoaren portaera baldintza txarretan probatu ahal izateko, baita bezeroa eta zerbitzaria makina berean exekutatzen ari direnean ere. Horrek asko errazten du atzerapena leuntzeko tekniken ezarpena.

Beste Baliabide Lagungarri batzuk

Sare ereduko beste baliabide batzuk aztertu nahi badituzu, hemen aurki ditzakezu:

Iturria: www.habr.com

Gehitu iruzkin berria