Ce qui distingue un MMORPG d'un jeu solo, c'est le serveur qui se cache derrière tout ce que tu vois. Dans cette première partie du journal de développement (devlog) d'Ancient Online: Remastered, nous expliquons comment nous créons un MMORPG avec Unreal Engine 5.8 : comment le travail se répartit entre le client et le serveur, comment le monde est simulé et comment nous parvenons à éditer en direct un monde unique et unifié.
Deux éléments : le client et le serveur
Ancient Online se compose de deux logiciels distincts :
- Le client est écrit en C++ sur Unreal Engine 5.8. Le rendu, le son, l'interface et les entrées sont de son ressort.
- Le serveur est indépendant d'Unreal : nous l'avons écrit de zéro en C++23. Toutes les règles du jeu s'exécutent ici.
Pourquoi avoir écrit le serveur à part plutôt qu'à l'intérieur du moteur ? Parce que les besoins d'un serveur de MMORPG ne sont pas ceux d'un moteur de jeu : il n'y a pas de graphismes, mais il y a des milliers d'entités, des données persistantes, de longues durées de fonctionnement et un besoin de performances prévisibles. Un serveur séparé nous permet de ne faire que le travail nécessaire et de maîtriser chaque octet.
Le serveur autoritaire : ne pas faire confiance au client
Notre règle de base est la suivante : le client affirme, le serveur décide.
- Déplacement : les entrées du joueur partent vers le serveur, et c'est le serveur qui calcule la position. Le client affiche la position communiquée par le serveur, avec une interpolation fluide. Ainsi, un client qui « se téléporte » ou traverse un mur ne va nulle part du point de vue du serveur.
- Combat : les résultats tels que les dégâts, les coups portés et les projections sont calculés sur le serveur. Par exemple, c'est le serveur qui décide si un coup de combo met l'adversaire à terre, et il diffuse le résultat à tout le monde au même instant.
- Économie : les objets, la monnaie et les transactions en boutique ne changent que sur le serveur et dans la base de données.
Le prix de cette approche, c'est de devoir bien gérer la latence réseau ; le bénéfice, c'est un monde où tricher est bien plus difficile et où les mêmes règles s'appliquent à tous.
Une boucle de monde à 25 Hz
Le serveur met le monde à jour 25 fois par seconde. À chaque pas, l'IA des monstres, les déplacements, les combats, les effets de compétences et la météo avancent tous. Un pas fixe rend la simulation prévisible et garantit que la même entrée produit toujours le même résultat.
Chaque joueur n'a pas besoin de tout savoir. Le serveur découpe le monde en grille et n'envoie à chaque joueur que les mises à jour des entités situées dans sa zone d'intérêt (celles qui sont proches). Le trafic réseau reste ainsi raisonnable, même dans une ville bondée.
Un protocole binaire léger
Il n'y a ni JSON ni REST entre le client et le serveur ; chaque message est un paquet binaire à la structure fixe. Cela économise à la fois de la bande passante et du temps processeur. Quand nous ajoutons un nouveau système (comme la météo, le déplacement ou le service de compte en jeu), nous lui écrivons un contrat de paquets séparé et versionné, et nous utilisons des fichiers d'en-tête partagés pour garantir que le client et le serveur travaillent à partir du même contrat.
Persistance : sauvegarder sans faire attendre le jeu
Les données des joueurs vivent dans une base de données PostgreSQL. Mais faire attendre la boucle du monde après la base de données à chaque pas n'est pas acceptable. La sauvegarde se fait donc en arrière-plan, en écriture différée (write-behind) : le serveur de monde dépose les changements dans une file d'attente (Redis), et un processus d'écriture en arrière-plan les enregistre par lots dans la base de données. Le déroulement du jeu ne dépend pas de la vitesse de la base de données.
Les canaux et le serveur de connexion
Les joueurs se connectent d'abord à un serveur de connexion, qui gère la vérification du compte, la sélection du personnage et la session. Ils passent ensuite sur l'un des quatre canaux de jeu (CH1–CH4). L'état en direct des canaux est affiché sur la page État des serveurs du site du jeu.
Un monde unifié, édité en direct
Le monde d'Ancient Online est conçu comme un monde unique et unifié plutôt que comme des cartes séparées par des écrans de chargement ; il est découpé en cellules et chargé en streaming.
Le contenu du monde (terrain, objets, emplacements des monstres) n'est pas conservé dans le code mais dans la base de données, sous forme versionnée. Nous pouvons éditer ce monde avec un éditeur de monde intégré au jeu : les changements sont d'abord faits dans un brouillon, vérifiés, puis publiés. Chaque publication crée une nouvelle version, et le client vérifie que les données du monde qu'il détient correspondent à celles du serveur en comparant une empreinte (digest). En cas de divergence, il attend que les données soient mises à jour avant de poursuivre vers le jeu.
Les quêtes : Lua comme langage de script
Les quêtes et les dialogues des PNJ sont écrits en Lua 5.4 sur le serveur. Cela nous permet de développer et de tester des quêtes sans recompiler le serveur.
Les messages des joueurs ne quittent jamais nos serveurs
Nous n'utilisons pas de service de traduction externe pour la traduction du chat en jeu. Nous faisons tourner sur nos propres serveurs un modèle de traduction local, qui n'utilise que le processeur ; les messages des joueurs ne sont envoyés à aucune API externe. Ainsi, des joueurs de langues différentes peuvent se comprendre sans que leurs messages ne quittent jamais le studio.
La suite
La deuxième partie du journal de développement revient sur les décisions prises pour rendre le même monde jouable à la souris, sur écran tactile et à la manette. Pour faire connaissance avec le studio, lis Qui est Astronaut Entertainment ? ; pour le jeu lui-même, consulte la page Jeux.


