Réécrire le moteur de Quake en Rust sûr : la vérification pixel par pixel comme boussole

Réécrire le moteur de Quake en Rust sûr : la vérification pixel par pixel comme boussole

Refactorisation de moteur de jeuVérification automatiséeMigration de codeWebAssembly

Sources:HN + web research

Un développeur répondant au pseudonyme d’ilreb a porté le moteur de jeu Quake de 1996 directement au cœur des navigateurs web modernes. Baptisé Quake-SRP (pour « slop rust port »), le projet est totalement dépourvu de dépendances externes et proscrit formellement la moindre ligne de code unsafe sur l’ensemble de son dépôt. Trente ans de code source en langage C ont été méthodiquement traduits fichier par fichier en un Rust sûr, compilés vers WebAssembly et exécutés au sein d’un Web Worker dédié. Les utilisateurs peuvent glisser-déposer sans aucune modification leurs fichiers pak1.pak, les packs de missions officiels ou encore les pistes audio de CD directement dans la fenêtre du navigateur : l’ensemble des calculs s’opère localement sur l’appareil, sans qu’aucun octet ne quitte la machine.

Compiler l’intégralité du C en WASM au sein d’un Web Worker

Le code source de Quake, publié sous licence libre par id Software en 1996, constitue un dédale de gestion manuelle de la mémoire, d’arithmétique de pointeurs brute et d’astuces au plus près du silicium. Dans ce portage, l’auteur a délibérément choisi de préserver le rastériseur logiciel CPU d’origine de WinQuake et sa palette de couleurs 8 bits emblématique, plutôt que d’opter pour une accélération matérielle moderne via WebGL ou WebGPU. WebGL2 n’intervient qu’à l’étape ultime de transfert (blit), se contentant de recopier à l’écran les pixels finaux calculés dans le tampon d’affichage. Les épisodes 2 à 4 contenus dans pak1.pak, les extensions de pak0.pak et les bandes-son sur CD se déposent d’un simple geste sur la page.

Isoler dans un Web Worker un moteur d’ancienne génération, autrefois intimement intriqué au matériel, relève d’une refonte architecturale profonde. La totalité de la logique WebAssembly s’exécute sur un thread d’arrière-plan en mobilisant à plein régime un unique cœur de processeur, tandis que le thread principal du navigateur se limite à relayer les saisies clavier-souris et à extraire l’image et l’audio depuis la mémoire partagée (SharedArrayBuffer). Renoncer aux pipelines modernes des cartes graphiques pour confier à la force brute d’un cœur CPU le moteur de rendu logiciel d’il y a trente ans réduit à néant les imprévus liés aux disparités d’environnements d’exécution. Ce parti pris d’une grande frugalité transforme une refonte multiplateforme périlleuse en un problème déterministe de traduction d’entrées et de sorties.

La comparaison visuelle trame par trame comme étalon absolu

Le véritable pivot technique de Quake-SRP réside dans son banc d’essai automatisé. Pour garantir l’exactitude de la migration menée par grand modèle de langage, le développeur a compilé une version sans interface (headless) du code source C original de WinQuake, érigée en oracle de référence absolu. La suite de tests traverse neuf cartes sous deux résolutions différentes pendant plusieurs centaines de trames alors que les monstres sont en pleine activité. Elle confronte pixel par pixel l’image 3D calculée, les éléments d’interface, les échantillons audio mixés ainsi que l’état interne de la partie lors de la relecture de démos par rapport à l’oracle en C. La documentation consigne avec transparence les divergences connues, sans s’attribuer prématurément une fidélité aveugle.

Dans le domaine de l’émulation, le test de régression visuelle est une pratique bien rodée — des projets tels que Dolphin s’appuient depuis longtemps sur des chaînes d’intégration continue graphique. Néanmoins, comparer des séquences 3D complètes trame par trame en tenant compte de l’échantillonnage des mipmaps et des variations subtiles d’éclairage dépasse de loin les exigences des habituels instantanés DOM du développement web. La quantité de code qu’un modèle peut générer en une seule passe n’a jamais été la clé du succès ; la véritable ancre retenant le code synthétique dans le réel réside dans la capacité de la machine à identifier de manière autonome les écarts au niveau du pixel. Faute d’un feu vert délivré par l’oracle de référence, le code le plus élégant ne saurait franchir la rampe.

E1M1 sous le profil Classic Figure : E1M1 rendu sous le profil Classic (1280×960), reproduisant à la perfection le comportement du WinQuake original. Source : capture d’écran du dépôt quake-srp.

Le même niveau sous le profil par défaut Figure : Le même niveau sous le profil par défaut (1920×1080), bénéficiant d’un champ de vision panoramique et d’un taux de rafraîchissement débloqué. Source : capture d’écran du dépôt quake-srp.

Un agent coordinateur qui ne fusionne les branches qu’après validation intégrale

Le fichier README du dépôt détaille avec soin la répartition des rôles entre l’humain et la machine. Claude (au travers de l’interface Claude Code) a officié comme l’auteur principal du code, des refactorisations et de la documentation. L’ingénieur humain a endossé le rôle d’architecte : définition des contraintes, tests manuels en jeu, signalement des anomalies et coordination des tâches réparties sur des branches Git distinctes. De surcroît, un agent coordinateur (« chair ») assurait l’arbitrage final, ne fusionnant les branches sur le tronc principal qu’après le succès absolu de l’ensemble des tests et des vérifications visuelles.

Cette organisation a délégué la lourde tâche de valider l’exactitude du programme à une implémentation de référence déterministe, déchargeant l’humain de la relecture ligne à ligne de la syntaxe générée par la machine. Le portage propose un paramètre ?classic reproduisant fidèlement le comportement historique du jeu, tandis que le mode par défaut ?slop active l’affichage panoramique et débloque le taux de rafraîchissement. L’humain ne répond ainsi que de la qualité finale de l’expérience de jeu, tandis que l’usure répétitive liée à la correction des erreurs de compilation, des fuites de mémoire et des dépassements de pointeurs est entièrement absorbée par la boucle du générateur.

Diff visuel de l'alignement de textures en perspective Figure : Capture issue du banc de comparaison visuelle illustrant l’alignement des textures en perspective. Source : capture d’écran du dépôt quake-srp.

De l’émulation 3D aux mainframes : transposer le modèle au COBOL

Au-delà de la prouesse rétrogaming, la méthodologie mise en lumière par Quake-SRP a immédiatement interpellé les ingénieurs confrontés aux dettes techniques les plus massives de l’industrie. Sur Hacker News, plusieurs développeurs ont fait part d’expériences analogues : l’usage de Claude pour rétro-concevoir des moteurs propriétaires en laissant le modèle lancer des scripts de rejeu, capturer des images à intervalles réguliers pour une validation croisée, disséquer les binaires d’origine et corriger les machines à états pour en garantir le déterminisme. La viabilité d’une réécriture supervisée par la machine étant désormais démontrée, la réflexion s’est naturellement déplacée vers les systèmes bancaires sous COBOL qui constituent encore l’épine dorsale des institutions financières.

Les coûts exorbitants de validation humaine et l’infinité de cas particuliers non documentés expliquent pourquoi ces applications critiques n’ont jamais pu être migrées vers le cloud. Bien que les règles métier soient exhaustivement inscrites dans le code hérité, l’entrelacement des dépendances dissuade toute équipe de prendre le risque d’une réécriture manuelle. C’est précisément dans cette brèche que les systèmes d’oracles parallèles révèlent toute leur puissance. Dès lors qu’un banc de comparaison automatisé des entrées-sorties est opérationnel, la modernisation des mainframes cesse d’être une aventure risquée pour la carrière d’une équipe et devient une couverture de code méthodique troquée contre du temps et de la puissance de calcul.

Du portage vertueux au détournement d’interfaces industrielles

Cette dynamique technologique ne s’exprime toutefois pas dans une seule direction. Si une boucle intégrant modèles génératifs et bancs de vérification automatisés parvient, à force d’itérations et de rectifications d’écarts, à traduire sans perte un moteur 3D complexe des années 1990, elle dispose tout autant des moyens d’analyser et de cloner les règles de transition d’état de systèmes fermés propriétaires. Les échanges communautaires ont mis en exergue un revers bien plus sombre : appliquée à des infrastructures critiques, cette ingénierie inverse en boîte noire permettrait de forger des séquences de commandes illicites et des interfaces leurres capables de tromper les défenses périmétriques. Aux arguments estimant que les architectures exposées ne reposaient que sur une fragile « sécurité par l’obscurité » et que leur vulnérabilité accélérerait leur indispensable remplacement, d’autres ont répliqué sans détour que la compromission des protocoles de contrôle industriel et des interfaces IHM entraînait des conséquences sans commune mesure avec de simples anomalies de grand livre comptable.

Un modèle entraîné à traquer les disparités et à combler les failles logiques n’est rien d’autre qu’un approximateur convergeant vers une logique calculable, sans égards pour la nature de sa cible — qu’il s’agisse d’un jeu vidéo historique ou des verrous d’une installation industrielle. Pour en revenir à Quake-SRP, la démonstration offerte par ce code en Rust sans unsafe est limpide : face à des labyrinthes logiciels gigantesques et immémoriaux, plutôt que d’épuiser des équipes humaines à repêcher des bugs dans des flots de code synthétique, l’urgence absolue consiste à concevoir un banc de comparaison visuelle d’une rigueur absolue. Un tel instrument ne se contente pas de ressusciter les architectures du passé : il trace la frontière inviolable qui encadre l’action des générateurs de code.

Liens de référence :

  • Présentation du dépôt GitHub
  • Démonstration en ligne de Quake-SRP
  • Discussion sur Hacker News