Alle innlegg

Å bygge et MMORPG med Unreal Engine 5.8 – Devlog #1: den autoritative serveren og verdensarkitekturen

Arkitekturen i Ancient Online: klient i Unreal Engine 5.8, autoritativ server i C++, verdensløkke på 25 Hz og én samlet verden som redigeres live.

En arbeidsstasjon med skjermer og bærbare PC-er side om side i et svakt opplyst studio

Det som skiller et MMORPG fra et enspillerspill, er serveren bak alt du ser. I denne første delen av devloggen for Ancient Online: Remastered forklarer vi hvordan vi bygger et MMORPG med Unreal Engine 5.8: hvordan arbeidet fordeles mellom klient og server, hvordan verdenen simuleres, og hvordan vi kan redigere én samlet verden live.

To deler: klient og server

Ancient Online består av to separate programmer:

  • Klienten er skrevet i C++ på Unreal Engine 5.8. Rendring, lyd, grensesnitt og inndata er dens jobb.
  • Serveren er uavhengig av Unreal: vi har skrevet den fra bunnen av i C++23. Alle spillets regler kjører her.

Hvorfor skrev vi serveren separat i stedet for inne i motoren? Fordi det en MMORPG-server trenger, er noe annet enn det en spillmotor trenger: det finnes ingen grafikk, men det finnes tusenvis av entiteter, vedvarende data, lange oppetider og et behov for forutsigbar ytelse. En separat server lar oss gjøre bare det arbeidet som kreves, og ha kontroll over hver byte.

Den autoritative serveren: å ikke stole på klienten

Grunnregelen vår er denne: klienten påstår, serveren avgjør.

  • Bevegelse: Spillerens inndata går til serveren, og serveren beregner posisjonen. Klienten viser posisjonen serveren rapporterer, med myk interpolering. En klient som «teleporterer seg selv» eller går gjennom en vegg, kommer altså ingen vei, sett fra serveren.
  • Kamp: Utfall som skade, treff og tilbakeslag beregnes på serveren. Det er for eksempel serveren som avgjør om et kombotreff slår motstanderen over ende, og den sender resultatet ut til alle samtidig.
  • Økonomi: Gjenstander, valuta og butikktransaksjoner endres bare på serveren og i databasen.

Prisen for denne tilnærmingen er at nettverksforsinkelsen må håndteres godt; gevinsten er en verden der det er mye vanskeligere å jukse, og der de samme reglene gjelder for alle.

En verdensløkke på 25 Hz

Serveren oppdaterer verdenen 25 ganger i sekundet. I hvert steg går monster-AI, bevegelse, kamp, ferdighetseffekter og vær fremover. Et fast steg holder simuleringen forutsigbar og sørger for at samme inndata alltid gir samme resultat.

Ikke alle spillere trenger å vite om alt. Serveren deler verdenen inn i et rutenett og sender hver spiller oppdateringer bare om entitetene innenfor spillerens interesseområde (de som er i nærheten). Det holder nettverkstrafikken på et rimelig nivå selv i en overfylt by.

En lettvekts binærprotokoll

Det finnes ingen JSON og ingen REST mellom klient og server; hver melding er en binær pakke med fast oppsett. Det sparer både båndbredde og prosessortid. Når vi legger til et nytt system (som vær, bevegelse eller kontotjenesten i spillet), skriver vi en egen, versjonert pakkekontrakt for det, og vi bruker delte headerfiler for å garantere at klient og server jobber ut fra samme kontrakt.

Lagring: å lagre uten å la spillet vente

Spillerdata ligger i en PostgreSQL-database. Men det er ikke akseptabelt at verdensløkken venter på databasen i hvert steg. Derfor skjer lagringen i bakgrunnen, som write-behind-lagring: verdensserveren legger endringene i en kø (Redis), og en bakgrunnsprosess skriver dem til databasen i bolker. Flyten i spillet avhenger ikke av hvor rask databasen er.

Kanaler og innloggingsserveren

Spillerne kobler først til en innloggingsserver, som tar seg av kontoverifisering, karaktervalg og økten. Deretter går de videre til en av fire spillkanaler (CH1–CH4). Sanntidsstatus for kanalene vises på siden serverstatus på spillets nettsted.

Én samlet verden som redigeres live

Verdenen i Ancient Online er utformet som én samlet verden i stedet for separate kart atskilt av lasteskjermer; den er delt inn i celler og lastes inn ved strømming.

Innholdet i verdenen (terreng, objekter, plassering av monstre) ligger ikke i koden, men i databasen, versjonert. Vi kan redigere denne verdenen med en verdenseditor inne i spillet: endringer gjøres først i et utkast, kontrolleres og publiseres deretter. Hver publisering lager en ny versjon, og klienten verifiserer at verdensdataene den har, stemmer med serverens ved å sammenligne en kontrollsum. Hvis de ikke stemmer, venter den på at dataene blir oppdatert før den fortsetter inn i spillet.

Oppdrag: Lua som skriptspråk

Oppdrag og NPC-dialoger skrives i Lua 5.4 på serveren. Det lar oss utvikle og teste oppdrag uten å kompilere serveren på nytt.

Spillernes meldinger forlater aldri serverne våre

Vi bruker ingen ekstern oversettelsestjeneste til chatoversettelsen i spillet. Vi kjører en lokal oversettelsesmodell, som bare bruker prosessoren, på våre egne servere; spillernes meldinger sendes ikke til noe eksternt API. Slik kan spillere som snakker ulike språk, forstå hverandre uten at meldingene deres noen gang forlater studioet.

Hva kommer nå?

Del to av devloggen tar for seg valgene vi tok da vi gjorde den samme verdenen spillbar med mus, berøringsskjerm og håndkontroll. Vil du bli kjent med studioet, kan du lese Hvem er Astronaut Entertainment?; for selve spillet finner du siden Spill.

Del:
Finnes også på29