Rétro-ingénierie du serveur de démo d’Ultima Online de 1998
(draxinar.github.io)- OUO est un projet qui a entièrement rétroconçu le serveur de démo de
Ultima Onlinede 1998, en désassemblant environ 5 000 fonctions d’un binaire MSVC x86 pour les porter en C99 portable UoDemo.exeétait une démo autonome incluse dans la première version deUltima Online: The Second Age, contenant à la fois le client et l’intégralité du code et des données du serveur portés sous Windows- Chaque fonction a été comparée au binaire d’origine au niveau des instructions, puis convertie manuellement afin de conserver la hiérarchie de classes et l’agencement des vtable, ainsi que le même flux de contrôle, la même disposition des structures et les mêmes branchements que l’original
- La version restaurée est très proche du code des véritables serveurs live de
Ultima Onlineau milieu de 1998, mais des problèmes de stabilité comme les crashs, débordements et variables non initialisées, ainsi que des problèmes de gameplay comme la progression des compétences ou la densité de spawn, y ont été corrigés avec des tags explicites - La démo d’origine ne prenait en charge que le client 1.25.33, mais la version restaurée supporte les clients de la 1.25.30 à 5.0.9.1, avec ou sans chiffrement, et recherche aussi les fichiers de données serveur de 1997 à 2003
Origine et portée des fichiers de démo
- Chaque fonction a été comparée au binaire d’origine au niveau des instructions, et ce travail intermittent sur dix ans a pu être achevé récemment grâce aux progrès des LLM
UoDemo.exeest daté du 1998-09-02, et les données serveur provenaient d’un serveur en production extrait le 2 juin 1998- Certaines fonctionnalités ont été remplacées par des stubs pour la démo et la carte jouable a été réduite à l’île d’Ocllo, mais le reste correspondait au code du serveur de production réellement utilisé sur
Ultima Onlineau milieu de 1998 Ultima Onlineétait un MMORPG de 1997 développé par Origin Systems Inc., et l’un des premiers MMORPG à succès commercial- Le client tournait sous Windows, tandis que les serveurs, appelés « shards », fonctionnaient sur plusieurs machines Solaris, avec une carte découpée par régions
- La démo proposait une quête simple consistant à tuer un dragon sur l’île d’Ocllo, pensée pour faire découvrir les mécanismes de base du jeu comme le dialogue, le commerce et le combat
- Plusieurs émulateurs de serveurs
UOont réutilisé une partie de cette démo, mais aucun ne l’avait jusqu’ici entièrement rétroconçue UoDemo.exea été compilé avec Microsoft Visual C++ 5.0, c’est-à-dire Visual Studio 97, et ciblait un dialecte de C++ antérieur à C++98
Méthode de rétro-ingénierie
-
Désassemblage et estimation des symboles
- Le désassemblage a été réalisé avec radare2
- Les noms de symboles ont été déduits à partir du client
UO1.25.37 issu d’un port Linux expérimental contenant des symboles C++
-
Conversion manuelle en C99
- Chaque fonction a été traduite à la main en C99 en conservant le même flux de contrôle, la même disposition des structures et les mêmes branchements que dans le binaire d’origine
- Les différences correspondent soit à de vraies corrections de bugs de la démo, soit à des adaptations de plateforme, et elles sont signalées dans le code source
-
Méthode de validation
- Le build C a été à nouveau désassemblé avec
r2, puis comparé à l’original - Une fonction n’était considérée comme terminée que lorsque les deux résultats correspondaient
- Les fonctions utilitaires n’ont été utilisées que pour des motifs inline répétitifs, et seulement lorsqu’elles pouvaient être redéployées en code identique à la version inline
- Le build C a été à nouveau désassemblé avec
-
Restauration de la hiérarchie de classes
- L’une des étapes les plus importantes au début a été de reconstituer précisément la hiérarchie de classes
- La hiérarchie principale était
CEntity (0x10) -> CResourceEntity (0x1C) -> CItem (0x50) -> CContainer (0x5C) -> CMobile (0x37C) -> CPlayer (0x458) - Le dispatch virtuel passait par des slots de vtable ; par exemple
vtable[0x18]correspondait àIsPlayer,[0xD0]àIsMobileet[0xE4]àIsNPC - Une fois cet agencement établi, il a été possible de traduire assez directement l’essentiel du binaire
Résultat de la restauration et différences avec l’original
- Le résultat est proche d’une copie presque parfaite du serveur
Ultima Onlinede 1998, avec toutefois quelques différences - Des problèmes de stabilité comme les crashs, les débordements et les variables non initialisées ont été corrigés par rapport au code d’origine
- Des problèmes de gameplay comme la progression des compétences, le sens fame/notoriety ou la densité de spawn ont également été corrigés
- Chaque correction est balisée dans le code source, afin que toute personne comparant avec
UoDemo.exepuisse voir précisément ce qui a changé et pourquoi - Certaines fonctionnalités, comme le système de spawn et le système de decay, étaient cassées et ont pu être partiellement désactivées ou remplacées par des stubs pour la sortie de la démo
- Le code de ces fonctionnalités était toujours présent, mais les points d’appel live n’étaient pas atteignables ; il a suffi de les décompiler séparément puis de reconnecter le dispatch pour les remettre en service
- Certaines données manquaient, notamment une carte du jeu limitée à la seule île d’Ocllo
- Une suite complète d’outils a été créée pour manipuler le format des données serveur, et reconstituer entièrement les portes, panneaux, décorations, téléporteurs, pièges, coffres et positions de spawn du reste du monde
Systèmes d’écosystème encore présents
- Le célèbre ecology system, aujourd’hui abandonné, était toujours présent dans le code bien que les appels de fonctions aient été coupés
- Les systèmes de prédateurs, proies et charognards ont été reconnectés, permettant de voir des loups poursuivre des lapins ou des corbeaux ramasser des objets
- En revanche, faute de données précises, l’ensemble du système de ressources et de production n’a pas été réimplémenté
- En documentation connexe, l’article de Raph Koster sur l’
UOecology system ainsi que ses billets sur le système de ressources deUO1, 2, 3 sont liés
Fonctions supplémentaires et compatibilité client
- Les compétences Meditation, Stealth et Remove Trap, ajoutées par OSI en février 1999, ont été intégrées
- Certaines traces initiales de ces fonctionnalités étaient déjà présentes dans le code
- La plupart des nouvelles fonctions peuvent être activées ou désactivées au démarrage via le paramètre
-features - Comme le serveur de démo n’avait absolument aucun système de comptes, celui-ci a été réimplémenté sous une forme légèrement modernisée, à partir d’une estimation de la manière dont les développeurs d’origine l’auraient conçu
- Alors que le serveur de démo d’origine ne supportait que le client 1.25.33, il a été étendu pour prendre en charge tous les clients de la 1.25.30 à la 5.0.9.1, soit jusqu’au 2007-03-27, avec ou sans chiffrement
- Comme cinq schémas de chiffrement complètement différents ont existé au fil des ans, chacun a dû être rétroconçu à partir des binaires clients
Original 32 bits et build par défaut en 64 bits
- Le binaire d’origine était en 32 bits, mais le build par défaut actuel cible le 64 bits
- La hiérarchie de classes reproduit l’héritage C++ d’origine à l’aide d’un embedding de structures C
- Cette approche permet de passer un
CMobile*là où unCContainer*est attendu - Comme l’élargissement de la taille des pointeurs en 64 bits peut décaler la position des champs hérités, certaines structures ont été volontairement paddées afin que l’héritage et l’agencement des vtable correspondent au binaire, en 32 bits comme en 64 bits
Ressources publiques
- https://github.com/draxinar/ouo : code
- https://github.com/draxinar/rundir : données basées sur
UoDemo.dat, modifications, données complétées et nouvelles fonctionnalités - https://uo.serpent-isle.com/ : Test Center, pas un véritable shard mais un environnement permettant de tester une reconstitution très fidèle du serveur
Ultima Onlinede 1998 - UO:98 : projet de Batlin et Derrick, source d’inspiration qui a lancé ce travail en 2016
OUOen est encore à un stade précoce et peut contenir des problèmes- Les problèmes détectés peuvent être signalés via les issues, et les contributions sont bienvenues
Appel à la communauté Ultima Online
- Toute personne possédant les fichiers
dynamic0.mul,dynamic0.bkp,regions.txt,resbank.muld’un serveurUltima Onlineoriginal des années 1997 à 2003 est invitée à les transmettre dynamic0.muletdynamic0.bkpsont des fichiers de sauvegarde serveur,regions.txtcontient les définitions de spawn, etresbank.mulest le fichier de définition des ressources- Il semble peu probable que les fichiers originaux
dynamic0.muloudynamic0.bkpaient entièrement disparu - Des outils existent déjà pour supprimer les données des joueurs du fichier
dynamic0.mulafin de préserver la vie privée avant diffusion - Ces fichiers ont une grande valeur pour reconstituer avec une très grande précision le contenu du monde d’
Ultima Online
1 commentaires
Commentaires sur Hacker News
Si quelqu’un possède les fichiers
dynamic0.mul,dynamic0.bkp,regions.txtetresbank.muldu serveur Ultima Online d’origine, je lui serais vraiment très reconnaissant de me les envoyerCe sont des fichiers de sauvegarde serveur, de définitions de spawn et de ressources datant d’environ 1997 à 2003, et surtout
dynamic0.muloudynamic0.bkpont probablement été sauvegardés dans plusieurs endroits sûrs, donc il est difficile de croire qu’ils aient complètement disparuCes fichiers ont une valeur extrêmement importante pour recréer avec une très grande fidélité le contenu du monde d’Ultima Online
Vraiment génial. C’est drôle, je suis tombé là-dessus justement alors que j’écoutais une ancienne bande-son des jeux Ultima
Je me demande s’ils ont envisagé d’écrire le résultat de la désassemblage dans le dialecte C++ d’avant C++98 utilisé à l’origine, et de cibler le compilateur d’époque
J’ai déjà désassemblé des binaires tournant sur des systèmes vintage, et si c’était possible j’aurais sans doute visé la toolchain d’origine. C’est une question philosophique assez intéressante
En tant que dernier développeur survivant d’eqclassic, j’ai trouvé ça intéressant à lire, mais j’espérais une histoire plus approfondie sur les outils utilisés et le déroulé complet du processus. Cela dit, c’est un bon article
À l’époque, il n’y avait pas de LLM, mais on avait quelques symboles de debug provenant d’un binaire PowerPC sorti trois ans plus tard, donc ça a un peu aidé
Des noms de fichiers comme
packet_handlerouentitylistme semblent étrangement familiers :DLe dernier obstacle, c’est d’avoir un code réseau pratiquement parfait avant de peaufiner le reste, et j’y ai déjà perdu des centaines d’heures
Je n’ai fait que survoler le code source, mais tout semble reposer sur TCP, donc on dirait qu’ils n’ont pas ajouté de mécanisme de fiabilité par-dessus. Si c’est bien le cas, c’est intéressant, car pour un MMO de l’époque cela paraît un choix assez « lent »
Pour ceux qui voudraient essayer UO, c’est toujours un jeu avec une base de joueurs active. Des serveurs tiers comme UO Outlands sont plus proches du gameplay original, mais selon les standards des MMO modernes, c’est assez brutal
D’autres joueurs peuvent arriver, vous ganker, et vous pouvez perdre votre équipement
Il y a encore plus de 2 500 personnes connectées sur ce serveur en ce moment, donc c’est toujours très vivant
Mon premier vrai accomplissement en programmation a été de créer un site web de shard Ultima Online
C’était du PHP et du HTML médiocres, mais il a ensuite fonctionné pendant plus de 20 ans. De très bons souvenirs
J’ai été surpris de voir qu’il existait encore une communauté aussi active autour de UO, et quoi qu’il en soit, ce projet est vraiment génial
J’avais 12 ou 13 ans à l’époque, fin des années 90 ou début des années 2000. Je ne me souviens plus du nom de l’émulateur, mais c’était probablement POL
Le but du shard était d’être aussi proche que possible des serveurs officiels d’avant UO:Renaissance, donc on a pas mal travaillé pour que ça ressemble à T2A et en ait les sensations
J’ai énormément appris, puis quand RunUO est arrivé et s’est plus ou moins stabilisé vers 2003, j’ai aussi aidé à porter vers du code C# pour RunUO ce qu’on avait fait sur POL, et il a fallu que j’apprenne encore davantage pour suivre
Les gens avec qui je travaillais sur ce shard faisaient tous des études d’informatique à l’université ou étaient déjà développeurs, et moi je n’étais qu’un gamin qui savait écrire quelques scripts
Je pense que cette expérience a été déterminante pour devenir pro plus tard. Mon premier emploi dans une vraie entreprise tech, je l’ai d’ailleurs obtenu parce que l’un d’eux m’a recommandé quand un stage s’est libéré
D’une certaine manière, c’est grâce à UO et aux shards privés que j’ai la carrière que j’ai aujourd’hui
J’ai commencé à programmer uniquement par nécessité
J’ai oublié le nom du jeu, mais c’était peut-être City of Heroes, qui avait été arrêté pendant quelques années avant qu’un jour quelqu’un ne remette en ligne un serveur privé
Même pour d’anciens jeux en ligne Shockwave, des communautés de niche reconstruisent des serveurs et créent un runtime Shockwave ainsi que des décompilateurs
Comme elles résolvent des problèmes similaires, les communautés finissent aussi par se recouper ;)
Le deuxième a été de modifier la carte, avec la suppression d’objets statiques, l’ajout de nouvelles îles et de bâtiments
Le troisième a consisté à modifier
verdata.mulpour ajouter de nouvelles animations et de nouveaux graphismes d’objetsC’est littéralement grâce à Ultima Online sur un serveur POL non officiel que je suis entré dans l’IT. Avant ça, j’étudiais pour devenir comptable
C’est comme ça que je suis entré sur IRC pour la première fois, puis plus tard sur freenode
La scène des émulateurs UO m’a amené vers la programmation réseau
Je n’ai jamais vu d’autre jeu en ligne capturer aussi bien autant de mécaniques de gameplay secondaires, émergentes et accidentelles
Les MMO 3D qui ont suivi semblent avoir fortement réduit les aspects d’économie, de construction et d’exploration intéressants que proposait UO
Le PvP ou les quêtes sont peut-être mieux réussis ailleurs, mais UO restait captivant, et on pouvait passer naturellement du solo au jeu en groupe, ou à de petites interactions improvisées avec des inconnus, selon l’humeur
La plupart des gens ne veulent pas de ça et préfèrent rester sur des rails prédéfinis
Et les deux groupes les plus attirés par ce type de jeu tombent dans une dynamique où la présence de l’un fait fuir l’autre. Or le second groupe a besoin que le premier continue à jouer
Par exemple, Asheron’s Call avait une communauté de modding très active et dispose maintenant aussi d’une scène d’émulation. Mais la popularité des serveurs ne semble pas atteindre celle de UO
Shadowbane était très centré sur les guildes, mais c’était amusant de jouer un peu en hors-la-loi et de faire du PvP contre des joueurs ou des guildes pris au hasard
En dehors de WoW, Old School RuneScape et Final Fantasy Online, il n’y a pas énormément de choses majeures auxquelles jouer
J’ai trouvé marquant le passage où, après avoir travaillé de façon intermittente sur ce projet pendant 10 ans, il a enfin été possible d’achever ce qui semblait être une tâche sans fin grâce aux progrès récents des LLM
Moi aussi, je travaille sur un projet de décompilation C++ MFC, et les LLM sont ridiculement utiles pour ce genre de travail
J’ai joué à Ultima Online autrefois
Ces derniers temps, je m’amuse bien avec le scripting Python dans le client de jeu TazUO. C’est une version un peu ancienne de Python 3, mais c’est bien meilleur que d’écrire des scripts dans Razor ou SteamUO
Si vous voulez expérimenter tranquillement sur un shard solo, Memento m’a semblé pas mal
Je cherchais une version mobile localisée en espagnol ou en français de la version NES d’Ultima 4. Pareil pour les autres épisodes
J’aimerais quelque chose traité comme les Pixel Remaster de la série FF
Pour l’instant, on ne peut y jouer qu’avec un émulateur
Les RPG localisés avec beaucoup de texte sont un moyen très simple d’« apprendre en jouant » une langue étrangère, et ils sont aussi agréables à lire
Ce serait bien que ça existe
Ah, UO… vraiment de très bons souvenirs. Je me rappelle qu’avant d’avoir l’âge pour avoir une carte, j’allais à vélo jusqu’à Cybersmith à Palo Alto pour acheter du temps prépayé
À l’époque, je jouais pas mal sur le shard Napa Valley. Je n’étais pas assez courageux pour aller sur Catskills
Aujourd’hui, ce type d’expérience à la UO me manque, mais je n’ai tout simplement plus le temps d’investir dans un jeu pareil