Alle indlæg

Sådan bygger vi et MMORPG med Unreal Engine 5.8 – Devlog #1: den autoritative server og verdensarkitekturen

Ancient Onlines arkitektur: en Unreal Engine 5.8-klient, en autoritativ server i C++, en verdensløkke på 25 Hz og én samlet verden, der redigeres live.

En arbejdsstation med skærme og bærbare computere side om side i et svagt oplyst studie

Det, der adskiller et MMORPG fra et singleplayerspil, er serveren bag alt det, du ser. I denne første del af devloggen for Ancient Online: Remastered forklarer vi, hvordan vi bygger et MMORPG med Unreal Engine 5.8: hvordan arbejdet er fordelt mellem klient og server, hvordan verden simuleres, og hvordan vi kan redigere én samlet verden live.

To dele: klient og server

Ancient Online består af to separate stykker software:

  • Klienten er skrevet i C++ på Unreal Engine 5.8. Rendering, lyd, interface og input er dens opgave.
  • Serveren er uafhængig af Unreal: vi har skrevet den fra bunden i C++23. Alle spillets regler kører her.

Hvorfor skrev vi serveren særskilt i stedet for inde i motoren? Fordi en MMORPG-server har brug for noget andet end en spilmotor: der er ingen grafik, men der er tusindvis af entiteter, vedvarende data, lange oppetider og et behov for forudsigelig ydeevne. En særskilt server lader os kun udføre det arbejde, der er nødvendigt, og styre hver eneste byte.

Den autoritative server: stol ikke på klienten

Vores grundregel er denne: klienten påstår, serveren beslutter.

  • Bevægelse: Spillerens input går til serveren, og serveren beregner positionen. Klienten viser den position, serveren melder, med blød interpolation. En klient, der ”teleporterer sig selv” eller går gennem en væg, kommer altså ingen vegne, hvad serveren angår.
  • Kamp: Udfald som skade, træffere og tilbageslag beregnes på serveren. For eksempel afgør serveren, om et combo-slag vælter modstanderen, og sender resultatet til alle på samme tid.
  • Økonomi: Genstande, valuta og butikstransaktioner ændres kun på serveren og i databasen.

Prisen for den tilgang er, at netværksforsinkelsen skal håndteres godt; gevinsten er en verden, hvor snyd er langt sværere, og de samme regler gælder for alle.

En verdensløkke på 25 Hz

Serveren opdaterer verden 25 gange i sekundet. I hvert trin rykker monstrenes AI, bevægelse, kamp, færdighedseffekter og vejr alt sammen frem. Et fast trin holder simulationen forudsigelig og sikrer, at det samme input altid giver det samme resultat.

Ikke alle spillere behøver at kende til alt. Serveren deler verden op i et gitter og sender kun hver spiller opdateringer om entiteterne inden for spillerens interesseområde (dem i nærheden). Det holder netværkstrafikken rimelig, selv i en tætpakket by.

En letvægts binær protokol

Der er hverken JSON eller REST mellem klient og server; hver besked er en binær pakke med fast layout. Det sparer både båndbredde og CPU-tid. Når vi tilføjer et nyt system (som vejr, bevægelse eller kontotjenesten i spillet), skriver vi en særskilt, versioneret pakkekontrakt til det, og vi bruger delte headerfiler til at garantere, at klient og server arbejder ud fra den samme kontrakt.

Persistens: at gemme uden at lade spillet vente

Spillerdata ligger i en PostgreSQL-database. Men det er ikke acceptabelt, at verdensløkken venter på databasen i hvert trin. Derfor sker lagringen i baggrunden, som write-behind-persistens: verdensserveren lægger ændringer i en kø (Redis), og en baggrundsskriver skriver dem til databasen i batches. Spillets flow afhænger ikke af databasens hastighed.

Kanaler og login-serveren

Spillerne forbinder først til en login-server, som står for kontoverifikation, karaktervalg og sessionen. Derefter går de videre til en af fire spilkanaler (CH1–CH4). Kanalernes live-status vises på siden Serverstatus på spillets hjemmeside.

Én samlet verden, redigeret live

Verden i Ancient Online er designet som én samlet verden frem for særskilte kort adskilt af indlæsningsskærme; den er delt op i celler og indlæses ved streaming.

Verdens indhold (terræn, objekter, placering af monstre) ligger ikke i koden, men i databasen, versioneret. Vi kan redigere verden med en verdenseditor inde i spillet: ændringer laves først i en kladde, kontrolleres og udgives derefter. Hver udgivelse opretter en ny version, og klienten verificerer, at de verdensdata, den har, svarer til serverens, ved at sammenligne en digest. Er der uoverensstemmelse, venter den på, at dataene bliver opdateret, før den fortsætter ind i spillet.

Missioner: Lua som scriptsprog

Missioner og NPC-dialog skrives i Lua 5.4 på serveren. Det lader os udvikle og teste missioner uden at genkompilere serveren.

Spillernes beskeder forlader aldrig vores servere

Vi bruger ikke en ekstern oversættelsestjeneste til chatoversættelsen i spillet. Vi kører en lokal oversættelsesmodel, der kun bruger CPU, på vores egne servere; spillernes beskeder sendes ikke til noget eksternt API. På den måde kan spillere, der taler forskellige sprog, forstå hinanden, uden at deres beskeder nogensinde forlader studiet.

Hvad kommer der nu?

Anden del af devloggen handler om de beslutninger, vi traf, da vi gjorde den samme verden spilbar med mus, touchskærm og controller. Vil du lære studiet at kende, så læs Hvem er Astronaut Entertainment?; selve spillet finder du på siden Spil.

Del:
Findes også på29