Was ein MMORPG von einem Einzelspieler-Spiel unterscheidet, ist der Server hinter allem, was Sie sehen. In diesem ersten Teil des Devlogs zu Ancient Online: Remastered erklären wir, wie wir ein MMORPG mit Unreal Engine 5.8 bauen: wie die Arbeit zwischen Client und Server aufgeteilt ist, wie die Welt simuliert wird und wie wir eine einzige, zusammenhängende Welt live bearbeiten können.
Zwei Teile: Client und Server
Ancient Online besteht aus zwei getrennten Programmen:
- Der Client ist in C++ auf Unreal Engine 5.8 geschrieben. Rendering, Audio, Oberfläche und Eingabe sind seine Aufgabe.
- Der Server ist unabhängig von Unreal: Wir haben ihn von Grund auf in C++23 geschrieben. Hier laufen sämtliche Spielregeln.
Warum haben wir den Server separat geschrieben und nicht innerhalb der Engine? Weil ein MMORPG-Server andere Dinge braucht als eine Game-Engine: Es gibt keine Grafik, dafür aber Tausende von Entitäten, persistente Daten, lange Laufzeiten und den Bedarf an vorhersagbarer Leistung. Ein separater Server erlaubt uns, nur die Arbeit zu erledigen, die nötig ist, und jedes Byte zu kontrollieren.
Der autoritative Server: dem Client nicht vertrauen
Unsere Grundregel lautet: Der Client behauptet, der Server entscheidet.
- Bewegung: Die Eingabe des Spielers geht an den Server, und der Server berechnet die Position. Der Client zeigt die vom Server gemeldete Position mit weicher Interpolation an. Ein Client, der sich „selbst teleportiert“ oder durch eine Wand läuft, kommt aus Sicht des Servers also nirgendwohin.
- Kampf: Ergebnisse wie Schaden, Treffer und Rückstoß werden auf dem Server berechnet. Der Server entscheidet zum Beispiel, ob ein Kombotreffer den Gegner zu Boden wirft, und sendet das Ergebnis gleichzeitig an alle.
- Wirtschaft: Gegenstände, Währung und Shop-Transaktionen ändern sich ausschließlich auf dem Server und in der Datenbank.
Der Preis dieses Ansatzes ist, dass wir die Netzwerklatenz gut im Griff haben müssen; der Lohn ist eine Welt, in der Cheating deutlich schwerer ist und für alle dieselben Regeln gelten.
Eine Weltschleife mit 25 Hz
Der Server aktualisiert die Welt 25-mal pro Sekunde. In jedem Schritt laufen Monster-KI, Bewegung, Kampf, Fertigkeitseffekte und Wetter weiter. Ein fester Schritt hält die Simulation vorhersagbar und stellt sicher, dass dieselbe Eingabe immer dasselbe Ergebnis liefert.
Nicht jeder Spieler muss über alles Bescheid wissen. Der Server teilt die Welt in ein Raster und schickt jedem Spieler nur Updates zu den Entitäten in seinem Interessenbereich (denen in der Nähe). So bleibt der Netzwerkverkehr selbst in einer vollen Stadt im Rahmen.
Ein schlankes Binärprotokoll
Zwischen Client und Server gibt es weder JSON noch REST; jede Nachricht ist ein Binärpaket mit festem Aufbau. Das spart sowohl Bandbreite als auch CPU-Zeit. Wenn wir ein neues System hinzufügen (etwa Wetter, Bewegung oder den Kontodienst im Spiel), schreiben wir dafür einen eigenen, versionierten Paketvertrag, und über gemeinsame Header-Dateien stellen wir sicher, dass Client und Server mit demselben Vertrag arbeiten.
Persistenz: speichern, ohne das Spiel warten zu lassen
Spielerdaten liegen in einer PostgreSQL-Datenbank. Dass die Weltschleife bei jedem Schritt auf die Datenbank wartet, ist aber nicht akzeptabel. Deshalb wird im Hintergrund gespeichert, als Write-Behind-Persistenz: Der Weltserver legt Änderungen in eine Warteschlange (Redis), und ein Hintergrundprozess schreibt sie stapelweise in die Datenbank. Der Spielfluss hängt nicht von der Geschwindigkeit der Datenbank ab.
Kanäle und der Login-Server
Spieler verbinden sich zuerst mit einem Login-Server, der Kontoprüfung, Charakterauswahl und Sitzung übernimmt. Danach wechseln sie auf einen von vier Spielkanälen (CH1–CH4). Den Live-Status der Kanäle zeigt die Seite Serverstatus auf der Spiel-Website.
Eine zusammenhängende Welt, live bearbeitet
Die Welt von Ancient Online ist als eine einzige, zusammenhängende Welt angelegt, nicht als getrennte Karten mit Ladebildschirmen dazwischen; sie ist in Zellen unterteilt und wird per Streaming geladen.
Die Inhalte der Welt (Terrain, Objekte, Monsterplatzierungen) liegen nicht im Code, sondern versioniert in der Datenbank. Wir können diese Welt mit einem Welteditor im Spiel bearbeiten: Änderungen entstehen zuerst in einem Entwurf, werden geprüft und dann veröffentlicht. Jede Veröffentlichung erzeugt eine neue Version, und der Client prüft anhand einer Prüfsumme, ob seine Weltdaten mit denen des Servers übereinstimmen. Bei einer Abweichung wartet er, bis die Daten aktualisiert sind, bevor es ins Spiel weitergeht.
Quests: Lua als Skriptsprache
Quests und NPC-Dialoge werden auf dem Server in Lua 5.4 geschrieben. So können wir Quests entwickeln und testen, ohne den Server neu zu kompilieren.
Spielernachrichten verlassen unsere Server nie
Für die Chat-Übersetzung im Spiel nutzen wir keinen externen Übersetzungsdienst. Wir betreiben ein lokales, rein CPU-basiertes Übersetzungsmodell auf unseren eigenen Servern; Spielernachrichten werden an keine externe API geschickt. So können sich Spieler, die unterschiedliche Sprachen sprechen, verstehen, ohne dass ihre Nachrichten jemals das Studio verlassen.
Wie es weitergeht
Teil zwei des Devlogs behandelt die Entscheidungen, die wir getroffen haben, um dieselbe Welt mit Maus, Touchscreen und Controller spielbar zu machen. Um das Studio kennenzulernen, lesen Sie Wer ist Astronaut Entertainment?; zum Spiel selbst geht es auf der Seite Spiele.


