Megapack: Kuinka Factorio ratkaisi 200 pelaajan moninpeliongelman

Megapack: Kuinka Factorio ratkaisi 200 pelaajan moninpeliongelman
Tämän vuoden toukokuussa osallistuin pelaajana MMO-tapahtumat KatherineOfSky. Huomasin, että kun pelaajamäärä saavuttaa tietyn määrän, muutaman minuutin välein osa heistä "putoaa". Onneksi sinulle (mutta en minulle) olin yksi niistä pelaajista, jotka katkesivat joka kerta, vaikka olisi hyvä yhteys. Otin tämän henkilökohtaisena haasteena ja aloin etsimään ongelman syitä. Kolmen viikon virheenkorjauksen, testauksen ja korjausten jälkeen vika saatiin vihdoin korjattua, mutta matka ei ollut niin helppoa.

Moninpelien ongelmia on erittäin vaikea jäljittää. Ne esiintyvät yleensä hyvin tietyissä verkkoparametreissa ja hyvin erityisissä peliolosuhteissa (tässä tapauksessa yli 200 pelaajaa). Ja vaikka ongelma voidaan toistaa, sitä ei voida korjata kunnolla, koska keskeytyskohtien lisääminen pysäyttää pelin, sekoittaa ajastimet ja aiheuttaa yleensä yhteyden aikakatkaisun. Mutta kiitos sinnikkyyden ja upean työkalun nimeltä kömpelö Onnistuin ottamaan selvää, mitä oli tekeillä.

Lyhyesti sanottuna, virheen ja latenssitilasimuloinnin epätäydellisen toteutuksen vuoksi asiakas joutui joskus tilanteeseen, jossa sen piti lähettää verkkopaketti, joka koostuu pelaajan noin 400 peliolion syötteen valintatoiminnoista yhdessä kellojaksossa ( kutsumme tätä "megapaketiksi"). Palvelimen on tällöin paitsi vastaanotettava kaikki nämä syöttötoiminnot oikein, vaan myös lähetettävä ne kaikille muille asiakkaille. Jos sinulla on 200 asiakasta, siitä tulee nopeasti ongelma. Linkki palvelimeen tukkeutuu nopeasti, mikä johtaa pakettien katoamiseen ja uudelleen pyydettyjen pakettien sarjaan. Syöttötoiminnon viivästyminen saa sitten entistä useammat asiakkaat lähettämään megapaketteja, jolloin lumivyöry kasvaa entisestään. Onnelliset asiakkaat onnistuvat toipumaan, kaikki muut putoavat.

Megapack: Kuinka Factorio ratkaisi 200 pelaajan moninpeliongelman
Ongelma oli varsin perustavanlaatuinen ja sen korjaaminen kesti 2 viikkoa. Se on melko tekninen, joten selitän alla mehukkaat tekniset yksityiskohdat. Mutta ensin sinun on tiedettävä, että 0.17.54. kesäkuuta julkaistusta versiosta 4 lähtien, tilapäisten yhteysongelmien edessä, moninpelistä on tullut vakaampi ja viiveiden piilottamisesta on tullut paljon vähemmän bugisia (vähemmän hidastumista ja teleportointia). Olen myös muuttanut tapaa, jolla taisteluviive piilotetaan, ja toivon, että tämä tekee siitä hieman tasaisempaa.

Multiplayer Mega Pack - Tekniset tiedot

Yksinkertaisesti sanottuna pelin moninpeli toimii näin: kaikki asiakkaat simuloivat pelin tilaa ja vastaanottavat ja lähettävät vain pelaajan syötteitä (jota kutsutaan "syöttötoiminnoiksi", Syöttötoiminnot). Palvelimen päätehtävä on siirtää Syöttötoiminnot ja valvoa, että kaikki asiakkaat suorittavat samat toiminnot samassa kellojaksossa. Tästä voit lukea lisää postauksesta FFF-149.

Koska palvelimen on tehtävä päätökset suoritettavista toimista, pelaajan toiminnot liikkuvat suunnilleen tätä polkua pitkin: pelaajan toiminta -> peliohjelma -> verkko -> palvelin -> verkko -> peliohjelma. Tämä tarkoittaa, että jokaisen pelaajan toiminta suoritetaan vasta sen jälkeen, kun hän on tehnyt edestakaisen matkan verkon yli. Tästä johtuen peli näyttäisi hirvittävän hitaalta, joten melkein heti moninpelin käyttöönoton jälkeen otettiin käyttöön mekanismi viivästysten piilottamiseksi. Piilotusviive simuloi pelaajan syötteitä ottamatta huomioon muiden pelaajien toimia ja palvelimen päätöksiä.

Megapack: Kuinka Factorio ratkaisi 200 pelaajan moninpeliongelman
Factoriossa on pelitila Pelin tila on kortin, pelaajan, entiteettien ja kaiken muun täydellinen tila. Se simuloidaan deterministisesti kaikissa asiakkaissa palvelimelta saatujen toimien perusteella. Pelin tila on pyhä, ja jos se joskus alkaa erota palvelimesta tai mistä tahansa muusta asiakkaasta, synkronointi tapahtuu.

Paitsi Pelin tila meillä on viivästystila Latenssitila. Se sisältää pienen osajoukon perustilasta. Latenssitila ei ole pyhää ja edustaa yksinkertaisesti kuvaa siitä, miltä pelin tila tulee näyttämään tulevaisuudessa pelaajien syötteiden perusteella Syöttötoiminnot.

Tätä tarkoitusta varten tallennamme kopion luodusta Syöttötoiminnot viivejonossa.

Megapack: Kuinka Factorio ratkaisi 200 pelaajan moninpeliongelman
Eli prosessin lopussa asiakaspuolen kuva näyttää suunnilleen tältä:

  1. Käytä Syöttötoiminnot kaikki pelaajat Pelin tila tapa, jolla nämä syöttötoiminnot vastaanotettiin palvelimelta.
  2. Poistamme kaiken viivejonosta Syöttötoiminnot, joihin palvelimen mukaan on jo sovellettu Pelin tila.
  3. Poistaa Latenssitila ja nollaa se niin, että se näyttää täsmälleen samalta kuin Pelin tila.
  4. Käytämme kaikkia toimia viivejonosta asti Latenssitila.
  5. Tietojen perusteella Pelin tila и Latenssitila Näytämme pelin pelaajalle.

Kaikki tämä toistetaan joka mittakaavassa.

Liian vaikea? Älä rentoudu, tässä ei vielä kaikki. Epäluotettavien Internet-yhteyksien kompensoimiseksi olemme luoneet kaksi mekanismia:

  • Missed ticks: kun palvelin niin päättää Syöttötoiminnot teloitetaan pelin alussa, jos hän ei saanut Syöttötoiminnot joku pelaaja (esimerkiksi lisääntyneen viiveen vuoksi), hän ei odota, vaan ilmoittaa tälle asiakkaalle "En ottanut huomioon sinun Syöttötoiminnot, yritän lisätä ne seuraavassa palkissa." Tämä tehdään niin, että yhden pelaajan yhteysongelmien (tai tietokoneen) takia karttapäivitys ei hidastu kaikkien muiden kohdalla. Se kannattaa huomioida Syöttötoiminnot niitä ei jätetä huomiotta, vaan ne yksinkertaisesti jätetään sivuun.
  • Täysi edestakainen latenssi: Palvelin yrittää arvata, mikä on kunkin asiakkaan edestakainen viive asiakkaan ja palvelimen välillä. Joka 5. sekunti se neuvottelee asiakkaan kanssa tarvittaessa uuden latenssin (sen perusteella, miten yhteys on toiminut aiemmin), ja lisää tai vähentää edestakaisen matkan viivettä vastaavasti.

Yksinään nämä mekanismit ovat melko yksinkertaisia, mutta kun niitä käytetään yhdessä (mitä usein tapahtuu yhteysongelmissa), koodin logiikasta tulee vaikeasti hallittava ja paljon reunatapauksia. Lisäksi, kun nämä mekanismit tulevat käyttöön, palvelimen ja viivejonon on toteutettava erikoistoiminto oikein Syöttötoiminto oikeutettu StopMovementInTheNextTick. Tämän ansiosta, jos yhteyden kanssa on ongelmia, hahmo ei juokse yksin (esimerkiksi junan edessä).

Nyt meidän on selitettävä sinulle, kuinka kokonaisuuden valinta toimii. Yksi lähetetyistä tyypeistä Syöttötoiminto on muutos kokonaisuuden valintatilassa. Se kertoo kaikille, minkä entiteetin päällä pelaaja liikkuu. Kuten voitte kuvitella, tämä on yksi yleisimmistä asiakkaiden lähettämistä syöttötoiminnoista, joten kaistanleveyden säästämiseksi olemme optimoineet sen viemään mahdollisimman vähän tilaa. Se toimii siten, että kun kukin entiteetti valitaan, sen sijaan, että se tallentaisi absoluuttisia, erittäin tarkkoja karttakoordinaatteja, peli tallentaa alhaisen tarkkuuden suhteellisen poikkeaman edellisestä valinnasta. Tämä toimii hyvin, koska hiiren valinnat ovat yleensä hyvin lähellä edellistä valintaa. Tämä asettaa kaksi tärkeää vaatimusta: Syöttötoiminnot Niitä ei saa koskaan ohittaa, ja ne on täytettävä oikeassa järjestyksessä. Nämä vaatimukset täyttyvät Pelin tila. Mutta tehtävästä lähtien Latenssitila "Näyttää tarpeeksi hyvältä" pelaajalle, he eivät ole tyytyväisiä viivetilaan. Latenssitila ei ota huomioon monia reunatapauksia, joka liittyy kellojaksojen ohittamiseen ja edestakaisen lähetysviiveen muuttamiseen.

Voit jo arvata, mihin tämä johtaa. Alamme vihdoin nähdä syitä megapakkausongelmaan. Ongelman juuri on siinä, että kokonaisuuden valintalogiikka luottaa Latenssitila, ja tämä tila ei aina sisällä oikeaa tietoa. Siksi megapaketti luodaan jotain tällaista:

  1. Soittimessa on yhteysongelmia.
  2. Mekanismit kellojaksojen ohittamiseksi ja edestakaisen lähetyksen viiveen säätämiseksi tulevat käyttöön.
  3. Viivetilajono ei ota näitä mekanismeja huomioon. Tämä aiheuttaa sen, että jotkin toiminnot poistetaan ennenaikaisesti tai suoritetaan väärässä järjestyksessä, mikä johtaa virheisiin Latenssitila.
  4. Soittimella on yhteysongelma, ja päästäkseen palvelimeen kiinni se simuloi jopa 400 jaksoa.
  5. Jokaisen rastin kohdalla luodaan uusi kokonaisuusvalintaa muuttava toiminto, joka valmistetaan lähetettäväksi palvelimelle.
  6. Asiakas lähettää palvelimelle mega-erän yli 400 entiteetin valintamuutosta (ja muilla toimilla: ammuntatilat, kävelytilat jne. kärsivät myös tästä ongelmasta).
  7. Palvelin vastaanottaa 400 syöttötoimintoa. Koska syöttötoimintoja ei saa ohittaa, se käskee kaikki asiakkaat suorittamaan kyseiset toiminnot ja lähettää ne verkon yli.

Ironista on, että kaistanleveyden säästämiseen suunniteltu mekanismi päätyi luomaan valtavia verkkopaketteja.

Ratkaisimme tämän ongelman korjaamalla kaikki päivityksen ja ruuhkajonotuen reunatapaukset. Vaikka se vei melko vähän aikaa, kannatti lopulta saada se kuntoon mieluummin kuin luottaa nopeisiin hakkereihin.

Lähde: will.com

Lisää kommentti