2 points par GN⁺ 2026-03-08 | 1 commentaires | Partager sur WhatsApp
  • Projet open source qui réimplémente entièrement un serveur Ultima Online en .NET 10 et C#, avec un objectif de hautes performances et d’exécution stable grâce à l’AOT (compilation anticipée)
  • Il dispose d’une architecture modulaire, d’un traitement précis de la boucle de jeu et d’un outillage de paquets, tout en prenant en charge les interactions en jeu et le contrôle de l’IA via des scripts Lua
  • Il fournit une infrastructure serveur complète, incluant un système de persistance basé sur MessagePack-CSharp, le réseau TCP, des endpoints d’administration HTTP, ainsi que Docker et une stack de monitoring
  • Des fonctionnalités d’extension par script comme les commandes basées sur Lua, l’IA des PNJ, les effets visuels et le système d’UI (Gump) permettent de mettre en œuvre un gameplay personnalisable
  • Le projet est publié en open source et est considéré comme un framework serveur .NET moderne utile pour le développement de serveurs MMO haute performance et la recherche sur la restauration de jeux legacy

Aperçu du projet

  • Moongate v2 est un projet moderne de serveur Ultima Online écrit en .NET 10, qui assure de hautes performances et une bonne maintenabilité grâce à une structure modulaire et à la compilation AOT
  • Il est conçu avec une architecture intégrant la génération automatique des définitions de paquets, une boucle de jeu déterministe et une couverture de tests
  • Il a été reconstruit de zéro en s’inspirant de serveurs existants comme ModernUO, RunUO et ServUO, sans en copier le code

Objectifs principaux

  • Construire une base serveur maintenable, centrée sur la précision et la vitesse d’itération
  • Clarifier la séparation entre le réseau et la boucle de jeu et garantir la sûreté des threads
  • Appliquer une modélisation des paquets fondée sur les types et un mode d’enregistrement par génération de code
  • Préserver une structure compatible AOT tout en assurant l’efficacité du développement local

État actuel du développement

  • Les fonctionnalités clés sont déjà implémentées, notamment le serveur TCP, le parsing des paquets, le bus d’événements, la gestion des sessions, l’interface d’administration HTTP et le runtime Lua
  • Le projet inclut aussi la génération automatique de métadonnées Lua, une UI console, une boucle de jeu basée sur des timers, le pathfinding A*, le contrôle de l’éclairage et de la météo, ainsi qu’une fonction d’envoi d’e-mails
  • Un module de persistance basé sur MessagePack permet de sauvegarder l’état du jeu sous forme de snapshots et de fichiers journal
  • Des images Docker et une stack de monitoring Prometheus/Grafana sont fournies pour faciliter le déploiement en environnement d’exploitation

Système de script et de commandes

  • Il intègre un moteur de scripting Lua (basé sur MoonSharp) permettant de contrôler l’IA des PNJ, le comportement des objets, les effets visuels et l’UI (Gump)
  • Il prend en charge à la fois un système d’enregistrement de commandes en C# et un enregistrement dynamique de commandes en Lua
  • Exemples : commandes GM .teleport, .add_item_backpack, .set_world_light
  • Le dispatch par ScriptId des objets permet de gérer les événements de clic à partir de tables Lua

Performances et benchmarks

  • D’après les mesures réalisées avec BenchmarkDotNet, les principales opérations de parsing et de sérialisation des paquets sont traitées à l’échelle de quelques dizaines de nanosecondes
  • Dans la comparaison AOT vs JIT, certaines opérations montrent un gain de vitesse pouvant atteindre 5 à 6 fois
  • L’efficacité de traitement de chemins critiques du jeu comme SpatialWorldService et ItemService est mesurée en détail

Déploiement et exécution

  • .NET SDK 10.0.x requis
  • Procédure d’exécution de base :
    dotnet restore
    dotnet build
    dotnet run --project src/Moongate.Server
    
  • Une configuration basée sur des variables d’environnement (MOONGATE_*) permet de contrôler les paramètres détaillés liés au port HTTP, à la boucle de jeu, aux e-mails, au scripting, etc.
  • Un exemple de Docker Compose est fourni, avec les ports par défaut 2593 (jeu) et 8088 (HTTP)

Licence et contribution

Résumé des caractéristiques techniques

  • Framework serveur MMO basé sur C# + .NET 10 + NativeAOT
  • Prend en charge l’intégration de scripts Lua, la persistance MessagePack et le monitoring Prometheus/Grafana
  • Inclut le déploiement Docker et des scripts d’automatisation
  • Une conception haute performance, modulaire et centrée sur les tests, adaptée au développement de serveurs modernes

1 commentaires

 
GN⁺ 2026-03-08
Commentaires sur Hacker News
  • Parmi tous les jeux auxquels j’ai joué, aucun n’avait autant de joueurs « ordinaires » que UO (Ultima Online)
    Même sans obtenir d’équipement puissant, on pouvait s’y amuser, et les meilleurs joueurs étaient connus presque comme des célébrités
    C’était complètement différent des jeux actuels où tout le monde ressemble à un super-héros

    • Je suis tellement d’accord. Dans UO, il y avait une vraie économie et des classes sociales
      On pouvait passer des mois comme pêcheur ou tailleur et vivre malgré tout une expérience riche de sens, tandis qu’un guerrier redoutable et un marchand ordinaire trouvaient chacun leur plaisir dans le même monde
      Les MMO d’aujourd’hui ressemblent tous à des parcs à thème où tout le monde prend le même manège, alors que UO était un monde vivant où les rôles naissaient des choix des joueurs
    • Mon objectif, c’était de devenir un forgeron légendaire. L’artisanat, c’était le vrai endgame, et chaque équipement ou meuble venait des mains de quelqu’un
      Le but du jeu n’était pas de « vaincre » le monde, mais d’y vivre
      Il n’y avait ni quêtes, ni grands méchants, seulement le bien, le mal, et tout ce qui existe entre les deux
      J’aimerais qu’un studio refasse un jour vivre cette philosophie. Je pense que si Minecraft a eu autant de succès, c’est aussi grâce à cette dimension sandbox
    • UO était le meilleur jeu en ligne que j’aie connu. Tous les autres vivent dans son ombre
      J’ai aimé EverQuest et WoW aussi, mais je n’y ai jamais retrouvé cette liberté brute
      À titre personnel, je mettrais aussi The Realm parmi les candidats au meilleur MMO
    • J’ai même l’impression qu’il avait une sensibilité plus moderne qu’aujourd’hui. C’est aussi pour ça que j’aime Stardew Valley ou Animal Crossing
    • J’aurai probablement toute ma vie la nostalgie de ce plaisir pur que j’avais en jouant à UO. Même aujourd’hui, j’aurais envie de quitter mon travail pour y jouer toute la journée
  • C’est vraiment un travail impressionnant. En voyant le graphe des contributions, j’ai du mal à croire qu’une seule personne ait tout fait
    Ça me rappelle un peu le projet d’émulateur de serveur Infantry Online commencé il y a 16 ans
    J’ai même retrouvé les commits d’origine sur SourceForge : c’était un projet maintenu pendant plus de 15 ans par plus de 10 développeurs
    Je me demande comment une seule personne a pu accomplir autant

    • J’ai repris l’infrastructure de mes premières tentatives, Moongate et Prima, pour poser rapidement les bases
      Le scripting Lua, je l’avais déjà implémenté dans Lilly.Engine, et Codex m’a aidé pour les tests et l’implémentation de fonctionnalités
      Pour l’import des données, je me suis inspiré de la logique de ModernUO, et les items ont été importés par script depuis POL
      C’est surtout possible parce que, quand je m’absorbe dans quelque chose, je creuse avec un niveau de fixation presque obsessionnel
    • Tout le frontend web a été développé en React par Codex. Je déteste le développement frontend
  • Très beau projet. À une époque, j’ai maintenu UOX3, un émulateur UO en C++
    Je ne l’avais pas développé moi-même, mais je m’occupais de la communauté et des releases, et j’exploitais aussi un serveur privé avec un ami canadien
    Heureusement qu’Origin n’en a pas fait une affaire juridique

    • Au lycée, j’étais tellement accro à UO que j’ai fini par vendre mon compte pour arrêter
      Je me souviens l’avoir vendu sur eBay pour plusieurs milliers de dollars et une MTG Mox Pearl
      C’est à cette époque, grâce à UOX, que j’ai appris le C++ et ressenti pour la première fois la puissance de la programmation
      Avec un mod que j’avais écrit, je pouvais placer des moongates connectés à l’infini, et cette expérience m’a mis sur la voie du développement
      J’ai ensuite appris Python, ce qui m’a mené à ma carrière actuelle. Ça a vraiment changé ma vie
      (lien vers ma présentation)
    • Ravi de l’entendre ! En fait, UOX3 a été l’une des inspirations de Moongate
      La structure du serveur et l’approche du scripting étaient fascinantes, et elles ont influencé le projet actuel
      Ces projets occupent une place importante dans l’histoire des émulateurs UO
  • Quelle bouffée de nostalgie. J’avais acheté une petite maison près de Trinsic et j’y tenais une boulangerie
    Je pouvais embaucher des vendeurs NPC pour vendre mes marchandises même quand je n’étais pas là, et un ami vivait dans une tour qu’il avait décorée
    Il a fallu 20 ans à WoW pour introduire un système de logement, mais dans UO, les maisons étaient des lieux vivants intégrés au monde

  • J’ai lu le billet d’analyse de l’architecture de Moongate, et j’ai trouvé impressionnante la manière dont la DI est implémentée avec un Source Generator et dont Lua permet de séparer les comportements sans recompiler le C#
    Il était dit que l’IA des NPC manque encore, mais pourquoi ne pas connecter à Lua un microservice fondé sur des LLM au lieu d’un FSM traditionnel ?
    Les NPC pourraient avoir des conversations contextuelles et une mémoire, et déclencher de véritables événements en fonction des entrées des joueurs
    La couche paquet et l’environnement Lua sont déjà bien en place, donc l’intégration pourrait être propre. J’aimerais bien réfléchir ensemble à la conception de la logique IA

    • C’est une idée vraiment intéressante. Les dialogues des NPC pourraient même évoluer en un système qui transforme le monde lui-même
      Par exemple, si on demande une rumeur, cette rumeur pourrait réellement devenir un événement dans le jeu
    • Ça m’intéresse. Contacte-moi sur GitHub
  • Les serveurs MMO ont tendance à devenir structurellement complexes avec le temps, donc l’approche en clean architecture qui sépare le réseau de la logique de jeu m’a impressionné
    Je me demande surtout, avec la delta sync basée sur des secteurs, comment tu évites une explosion de paquets quand on entre dans une zone très fréquentée
    J’aimerais aussi savoir si l’usage de NativeAOT vise seulement à simplifier le déploiement, ou aussi les performances

    • C’était justement l’une des motivations principales. Les anciens codebases UO mêlaient réseau, persistance et logique, donc j’ai voulu tenter une nouvelle approche basée sur .NET
      Lorsqu’on entre dans un secteur, les items et mobiles des secteurs voisins sont synchronisés, mais les secteurs déjà visibles sont exclus
      Les items qui sortent du champ de vision sont supprimés par le client, donc ils doivent être renvoyés
      L’envoi des paquets passe par une file d’attente, ce qui évite de bloquer la boucle de jeu
      À l’avenir, je prévois d’ajouter un envoi priorisé et une répartition sur plusieurs ticks
      NativeAOT sert aussi à simplifier le déploiement, mais le point clé, c’est une performance prévisible. Il n’y a pas de latence JIT, ce qui aide à maintenir un timing de tick constant
    • On dirait que la prévention des explosions de paquets repose fondamentalement sur le chargement par proximité
      Sur un projet similaire, j’expérimente aussi le spawning basé sur le frustum pour réduire les rafales réseau, donc ça m’a beaucoup intéressé
      Le code est facile à lire, c’est très utile comme référence
  • Par coïncidence, MoonSharp, le moteur Lua utilisé par Moongate, est récemment redevenu actif
    Après 10 ans, une bêta v3.0.0 vient de sortir
    Je ne suis pas le créateur d’origine, mais je participe comme mainteneur sur GitHub, et Tabletop Simulator utilise aussi ce moteur

  • J’aimerais vraiment lancer un serveur. Il y a 15 ans, j’étais admin de SphereServer, mais j’ai perdu tous mes scripts et les données du monde
    Malgré ça, j’aimerais rejouer à UO classique avec d’autres, comme à l’époque

    • Je n’aurais jamais cru voir SphereServer mentionné ici !
      Moi aussi, j’avais écrit beaucoup de scripts personnalisés, et je les ai tous perdus
      C’est grâce à SphereServer que j’ai commencé à apprendre le scripting
  • J’aime beaucoup le logo. Je me demande s’il existe une vidéo YouTube montrant l’avancement du projet

    • Merci ! Le logo est né un peu par hasard, mais je voulais retrouver l’esprit des Moongates d’origine
      Il n’y a pas encore de vidéo, mais le login, la création de personnage, les déplacements dans le monde, le scripting d’items en Lua et une interface d’administration en React fonctionnent déjà
      Je vais bientôt ajouter une courte vidéo de démonstration dans le README
  • J’ai récemment regardé sur YouTube la série de vidéos de Majuular sur Ultima, et ça m’a marqué
    Grâce à ça, j’ai acheté Underworld et VII sur GOG. J’ai l’impression d’avoir raté des chefs-d’œuvre des années 90
    Mon frère a beaucoup joué à UO, et un ami à moi était un griefer notoire sous le nom de SirDarkSpell
    Je pense qu’ils seraient tous les deux ravis de voir ce projet. Ce week-end, je compte me plonger dans Stygian Abyss

    • Ultima Underworld est un jeu fantastique