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:
- 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.
- 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.
- A kliens csatlakozik a játékszerverhez, amely a játékos beengedése előtt ellenőrzi a verziókompatibilitást.
- 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.
- A meccs végén a szerver jelenti az eredményt a backendnek, amely elmenti azt, aminek meg kell maradnia.
- 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.