Miért nem egyetlen feladat a „legyen benne multiplayer”?

Amikor egy stúdió multiplayert kér, az elsőre egyetlen funkciónak hangzik. A gyakorlatban több, egymástól elkülönülő felelősségi területről van szó, amelyek máshol futnak, másképp hibáznak, és gyakran más-más ember a gazdájuk:

  • a játékkliens a játékos gépén;
  • a valós idejű játékszerver, amely a meccset futtatja;
  • az alkalmazás-backend, amely mindent kezel, ami a meccs körül történik;
  • az üzemeltetés: mindezek buildelése, telepítése, megfigyelése és frissítése.

Az online projektek scope-meglepetései többnyire nem magukból a területekből, hanem a köztük lévő résekből jönnek. Senki sem döntötte el, hogy a találatot a szerver vagy a kliens ellenőrzi, ki foglal le szervert a meccs indulásakor, vagy mi történik egy futó meccsel, amikor kijön egy új build. Ez a cikk sorra veszi a négy területet, ad egy felelősségi mátrixot, amelyet a saját tervezésedben is használhatsz, és azokkal a döntésekkel zárul, amelyeket érdemes tisztázni, mielőtt bárkitől árajánlatot kérsz.

A játékkliens: input, megjelenítés és visszajelzés

A kliens feladata, hogy a játék egyetlen játékos számára azonnalinak hasson. Beolvassa az inputot, kirajzolja a világot, lejátssza a hangokat és effekteket, és megmutatja, mi történik. Online játékban emellett elküldi a játékos szándékait a szervernek, a szerver frissítéseit pedig folyamatos képpé alakítja vissza.

Amit a kliens ne legyen: végső döntéshozó bármiben, ami a többi játékost is érinti. A sebzés, a pontszám, az inventory változásai és a meccs eredménye könnyen manipulálható egy olyan gépen, amely felett nincs kontrollod. Az általános szabály: a kliens javasol, a szerver dönt.

A fő kivétel a predikció, és ennek tudatos döntésnek kell lennie, nem alapbeállításnak. Gyors akciójátékokban lomhának hat, ha a saját karakter mozgatása vagy egy lövés megjelenítése előtt meg kell várni a szerver válaszát, ezért a kliens helyben szimulálja ezeket, majd korrigál, amikor megérkezik a hiteles eredmény. Ez a korrekciós lépés, a reconciliation, a netcode bonyolultságának jelentős része. Egy lassabb, körökre osztott vagy co-op játéknak lehet, hogy egyáltalán nincs szüksége predikcióra. Viszonyítási pontként: a VOXSYS-ban, egy kompetitív mobil VR lövöldözős játékban, amelyet a Sourcegarden Studio jelenlegi csapattagjai korábbi, VR Storm Studiós szerepükben fejlesztettek, kliensoldali predikciót használó multiplayer keretrendszer csökkentette az érzékelt késleltetést a harcban.

A kliens tipikus feladatai:

  • input beolvasása és a játékos szándékainak elküldése a szervernek;
  • renderelés, hang, UI és azonnali visszajelzés;
  • predikció és reconciliation azoknál az akcióknál, amelyeknek azonnalinak kell hatniuk;
  • a többi játékos és objektum interpolációja két szerverfrissítés között;
  • a kapcsolati állapotok egyértelmű kezelése: csatlakozás, betöltés, megszakadt kapcsolat, verzióeltérés.

A valós idejű játékszerver: autoritás és szimuláció

A valós idejű szerver birtokolja a meccs igazságát, amíg az fut. Fogadja a játékosok inputjait, futtatja a szimulációt, alkalmazza a játékszabályokat, és replikálja az eredményül kapott állapotot minden csatlakozott kliensnek.

Ezt a réteget négy kérdés határozza meg:

  • Autoritás. Melyik rendszer dönt az egyes állapotokról: mozgás, találat, tárgyfelvétel, a világ változásai? Az autoritás rendszerenként eltérhet, és mindegyiknél érdemes leírni.
  • Szimuláció. Mit kell a szervernek magának szimulálnia, és milyen frissítési gyakorisággal? Egy fizikát és változó világot használó shooter sokkal többet kér a szervertől, mint egy kártyajáték.
  • Replikáció. Milyen állapot, mely kliensekhez, milyen gyakran és milyen keretből megy ki? A sávszélesség- és frissítési budget tervezési korlát, nem implementációs részlet.
  • Szabályellenőrzés. Mely klienskéréseket ellenőriz a szerver, mielőtt alkalmazza őket, és mi történik, ha egy ellenőrzés elbukik?

Gyakori architekturális döntés ezen a ponton a dedikált szerver, a listen server (az egyik játékos a host) és a relay közötti választás. A dedikált szerver adja a legtisztább autoritási modellt és védi a fair playt, de magával hozza a szerverbuildet, a hosztingot és az üzemeltetést. Ezt a kompromisszumot az elején, kimondva érdemes meghozni, mert minden más terület scope-ját megváltoztatja.

Az alkalmazás-backend: csak az, amire a terméknek tényleg szüksége van

A backend a meccs körüli szolgáltatások összessége: hogyan jut be a játékos egy játékba, és mi marad meg a meccs után. Itt szokott a scope észrevétlenül nőni, ezért abból indulj ki, amire a terméknek ténylegesen szüksége van, ne abból a listából, amit egy online játék elvben tartalmazhat.

Területek, amelyeket egy backend lefedhet:

  • Identitás: kellenek-e egyáltalán fiókok, vagy elég a platform identitása.
  • Session-folyamat: session keresése vagy létrehozása, partyk vagy lobbik, szerverfoglalás, valamint a szervercím és a csatlakozási adatok átadása a kliensnek.
  • Perzisztencia: milyen adatnak kell túlélnie a meccset: progresszió, inventory, beállítások, meccseredmények.
  • Integrációk: platformszolgáltatások, analitika vagy külső backend-platformok.

Mindegyikhez saját biztonsági, adatvédelmi és karbantartási felelősség tartozik. Ahol egy bevált platformszolgáltatás már lefedi a folyamat egy részét, ott általában olcsóbb integrálni, mint újraépíteni; egyedi szolgáltatás ott indokolt, ahol a játéknak valóban szüksége van rá. Egy prototípusnak lehet, hogy nem kell több annál, hogy el tudj indítani egy szervert és csatlakozni tudj hozzá. Ha a fő nyitott kérdésed az, mekkora legyen ez a réteg, a játék backend scope-járól szóló külön útmutatónk részletesebben foglalkozik vele, a játék backend fejlesztés oldalon pedig azt írjuk le, hogyan közelítjük meg ezeket a szolgáltatásokat.

Üzemeltetés: telepítés, megfigyelhetőség és hibakezelés

Egy dedikált szerver, amely egy fejlesztő gépén fut, még nem olyasmi, amit egy csapat üzemeltetni tud. Az üzemeltetés az a munka, amely minden más réteget reprodukálhatóvá és láthatóvá tesz:

  • Build és telepítés: automatizált szerverbuild, konténer vagy image, környezetenkénti konfiguráció, és megismételhető mód a szerverek indítására és leállítására.
  • Megfigyelhetőség: strukturált logok, metrikák és health jelek a sessionök, a szerverfolyamatok és a szolgáltatáshívások körül, hogy egy játékosi hibajelentés visszavezethető legyen az okára.
  • Verziókompatibilitás: szabály arra, hogy mely kliensbuildek csatlakozhatnak mely szerverbuildekhez, és olyan rollout-folyamat, amely nem töri el a már futó meccseket.
  • Hibakezelés: graceful shutdown, újracsatlakozás, tele szerverek, összeomlott folyamatok és sikertelen szolgáltatáshívások – mindegyik definiált viselkedéssel.
  • Kapacitás és költség: dokumentált feltételezések arról, hány meccset bír el egy szerver, és mi hajtja az infrastruktúra költségét – mérve, nem becsülve.

Az üzemeltetést könnyű halogatni, mert az első játszható buildhez semmi sem kell belőle. Éppen ezért ez a terület hiányzik a leggyakrabban az árajánlatokból.

Újrahasználható felelősségi mátrix

Az alábbi táblázat kiinduló sablon. A gazda oszlop szerepkört jelöl, nem létszámot: kis csapatban egy fejlesztő több szerepet is vihet, és ez rendben van, amíg a területek közötti interfészek explicitek maradnak.

Rendszer Fő feladatok Tipikus gazda Kapcsolat a többi réteggel Átadandó anyag
Játékkliens Input, renderelés, UI, visszajelzés; szükség esetén predikció és reconciliation; interpoláció; kapcsolati állapotok Gameplay- / kliensfejlesztők Inputokat és kéréseket küld a játékszervernek; backend API-kat hív sessionökhöz és adatokhoz A kliens hálózati modelljének leírása, a predikált akciók listája, a kapcsolati állapotok folyamata
Valós idejű játékszerver Rendszerenkénti autoritás, szimuláció, replikáció, szabályellenőrzés, a meccs életciklusa Hálózati / szerverfejlesztő Fogadja az inputokat, replikálja az állapotot a klienseknek; jelenti a meccs eredményét és állapotát a backendnek Autoritási és replikációs terv, sávszélesség- és frissítési budget, headless szerverbuild
Alkalmazás-backend Identitás (ha kell), session- és lobbifolyamat, szerverfoglalás, perzisztencia, integrációk Backendfejlesztő vagy integrált platformszolgáltatás Verziózott kliens–backend szerződések; szerverfoglalási és meccseredmény-hívások A szolgáltatáshatárok dokumentációja, API-szerződések, adatmodell és adatgazdák
Üzemeltetés Szerverbuild-automatizálás, telepítés, környezetek, logok és metrikák, verzió-rollout, hibakezelés DevOps / technikai vezető, a hosztingfiók gazdájával együtt Health checkek, logok és metrikák minden rétegből; deployment pipeline Telepítési lépések, runbookok a gyakori incidensekhez, ismert korlátok, költségtényezők
Termékdöntések Játékmód, játékosszám sessionönként, régiók, platformok, fair play- és perzisztenciaszabályok Producer / game director Követelmények és elfogadási feltételek mind a négy réteghez Írásos feltételezések, amelyekre az árajánlat épül

Ha egy cellát nem tudsz kitölteni, általában azt kell elsőként tisztázni, nem későbbre hagyni.

Ugyanez az architektúra folyamatként

Sorrendben olvasva a területek így kapcsolódnak:

  1. A játékos elindítja a klienst. Ha a játéknak szüksége van rá, a kliens a backenden vagy a platformon keresztül azonosítja a játékost.
  2. A kliens sessiont kér a backendtől. A backend talál vagy lefoglal egy játékszervert, és visszaadja a címét és a csatlakozási adatokat.
  3. A kliens csatlakozik a játékszerverhez, amely a játékos beengedése előtt ellenőrzi a verziókompatibilitást.
  4. A meccs alatt a kliens inputokat küld, a szerver szimulálja és ellenőrzi őket, majd visszareplikálja az állapotot. A kliens csak azt predikálja, amiben megállapodtatok.
  5. A meccs végén a szerver jelenti az eredményt a backendnek, amely elmenti azt, aminek meg kell maradnia.
  6. Közben minden réteg logokat, metrikákat és health jeleket ad, amelyekre az üzemeltetés a telepítést, a monitorozást és a frissítést építi.

Kérdések, amelyek a technikai tervet alakítják

A megfelelő architektúra néhány termékdöntésből következik. Ezekre érdemes – akár csak hozzávetőleg – válaszolni az első technikai megbeszélés előtt:

Kérdés Miért számít?
Játékmód: co-op, kompetitív, perzisztens világ? A kompetitív játék magasabbra teszi a lécet a szerveroldali autoritás és ellenőrzés terén; co-opban néha több bizalom adható a kliensnek.
Játékosszám sessionönként Ez hajtja a szimulációs terhelést, a replikációs budgetet és azt, hány meccs fér el egy szerveren.
Régiók Meghatározza, hol kell szervereknek futniuk, és együtt játszhatnak-e a különböző régiók játékosai.
Késleltetésérzékenység Eldönti, kell-e predikció és reconciliation, és mely akcióknál.
Platformok Hatással van az identitásra, a crossplayre, a build pipeline-okra és a platformintegrációkra.
Perzisztencia Megmondja, mennyi backend kell: semmi, csak meccseredmények, vagy teljes progresszió és inventory.

Egyikhez sem kell végleges válasz az induláshoz. Kimondott feltételezés viszont kell, mert egy árajánlat pontosan annyira stabil, mint a mellé írt feltételezések.

Példa: hogyan választja szét a rendszereit a Bad Goons

A Bad Goons a Sourcegarden Studio jelenlegi saját IP-je: csapatalapú PC-s shooter egy voxeles csatatéren, amelyet a játékosok a meccs közben ásnak, rombolnak és újraépítenek. A játék aktív fejlesztés alatt áll, a hozzá kapcsolódó 64 játékos pedig tervezési cél, nem mért kapacitás.

Az architektúrája a fenti területeket explicit gyártási rendszerekként kezeli:

  • Kliens: Unity 6 játékkliens.
  • Valós idejű réteg: a FishNet hálózati keretrendszer, predikcióval és reconciliationnel.
  • Szimuláció: voxelszimuláció, amelynek világmódosításait minden játékoshoz szinkronizálni kell – ez is az egyik oka annak, hogy az autoritás a szerveren van.
  • Szerverek: autoritatív dedikált szerverek, amelyek Unity headless buildeket futtatnak Linuxon.
  • Üzemeltetés: konténeres telepítés, ahol a kapacitás, a leállítás, a health, a logok és a verzió-rollout játékot érintő kérdésnek számít, mert az infrastruktúra viselkedése közvetlenül hat a futó meccsekre és arra, hogy ki tudjuk-e deríteni egy játékosi hibajelentés okát.

A példa lényege nem a konkrét stack. A FishNet erre a játékra lett kiválasztva; egy másik játék, platform vagy csapat esetén más keretrendszer lehet indokolt. A lényeg, hogy minden határ explicit, így a kliens, a szerver és a telepítés külön építhető, tesztelhető és módosítható.

Checklist megrendelőknek: amit az árajánlat előtt tisztázni kell

Ezeket a válaszokat – vagy a jelenlegi legjobb feltételezéseidet – hozd magaddal az első beszélgetésre egy multiplayer partnerrel:

  • Játékmód és session-modell: co-op, kompetitív vagy perzisztens; meccshossz; hogyan jutnak be a játékosok egy meccsbe.
  • Játékosszám sessionönként tervezési célként, és ha van, a várható egyidejű játékosszám tartománya.
  • Autoritási modell: dedikált szerver, listen server vagy relay, és mely akciókat kell a szervernek ellenőriznie.
  • Predikció: mely játékosakcióknak kell azonnalinak hatniuk, és melyek várhatnak a szerverre.
  • Régiók és késleltetési elvárások a célközönségednél.
  • Platformok, és kell-e crossplay.
  • Engine és meglévő kódbázis: engine-verzió, jelenlegi hálózati keretrendszer, és multiplayerre készült-e eredetileg a játék.
  • Backend-igények: identitás, sessionök vagy lobbik, perzisztencia, integrációk, és a már használt platformszolgáltatás, ha van.
  • Üzemeltetési felelősség: kié a hosztingfiók, ki telepít, ki kap riasztást, ha egy szerver leáll, és várható-e támogatás az átadás után.
  • Verziókezelési szabály: hogyan kell egyeznie a kliens- és szerververzióknak, és hogyan jutnak el a frissítések a futó meccsekhez.
  • Átadási elvárások: milyen dokumentumokra, buildekre és runbookokra van szüksége a csapatodnak ahhoz, hogy átvegye az eredményt.
  • Ütemezés, mérföldkövek és költségkeret, beleértve azt is, mit kell bizonyítania az első mérföldkőnek.

Ha ezek közül több még nyitott, egy fókuszált architektúra-felmérés vagy kockázati prototípus gyakran jobb első lépés, mint egy teljes gyártási árajánlat. Ilyen munkát a multiplayer játékfejlesztési szolgáltatásunk keretében szoktunk scope-olni.