Doomformer : faire calculer un réseau neuronal par DOOM
Découvrez Doomformer, qui exécute un réseau neuronal entier dans une carte DOOM. Fonctionnement, vérification exacte, performances et limites du projet.

Faire calculer un réseau neuronal par DOOM : ce que prouve Doomformer
DOOM est connu pour ses couloirs, ses démons et ses cartes personnalisées. Doomformer lui confie une autre tâche : exécuter un réseau neuronal. Le projet prend un réseau à arithmétique entière, le traduit en carte ZDoom, le lance dans ViZDoom, puis compare les valeurs obtenues par le jeu à une référence calculée avec NumPy. Autrement dit, ici, le moteur ne sert pas seulement à « montrer » : ses mécanismes deviennent les briques d'un calcul.
L'idée est aussi ingénieuse que peu pratique. Des « poupées vaudou » - des copies du joueur - font tourner les opérations. Les niveaux de lumière et la hauteur des plans servent à porter des valeurs, et la logique de carte encode les étapes. Pour reconnaître un chiffre manuscrit, le système traite 784 pixels, calcule une couche cachée de 64 unités, puis produit une réponse parmi dix chiffres. Ensuite, il vérifie chaque valeur exposée avec une tolérance de zéro.
Au final, il faut prendre Doomformer pour ce que c'est : une expérience d'informatique créative, pas une nouvelle manière d'accélérer l'IA. Voici comment il fonctionne, ce que signifie son exactitude, ce que coûtent ses performances, et comment le tester sans confondre démonstration et usage « production ».
Pourquoi compiler un réseau neuronal dans une carte DOOM ?
La réponse courte : pour tester une question technique avec une contrainte volontairement absurde. Si un jeu expose des mécanismes déterministes et des variables qu'on peut observer, est-ce qu'on peut « assembler » tout ça pour exécuter un calcul ? Doomformer répond par une démonstration concrète : un réseau neuronal entier peut être traduit en logique de niveau, puis exécuté dans un moteur de jeu.
Mais ce n'est pas pour battre NumPy. Le projet annonce un calcul environ 23 000 fois plus lent que NumPy sur un petit perceptron multicouche, en se basant sur le temps moteur. En mesurant autour de l'appel complet, l'écart grimpe à environ 65 000 fois. Ces chiffres ne sont pas un détail « caché » : ils reflètent surtout le coût de l'exécution détournée, où chaque opération passe par des entités, des changements d'état et des scripts.
Une expérience de compilation, pas un modèle d'IA concurrent
Le mot « compiler » compte. Doomformer prend un réseau entier et le représente sous une forme exploitable par une carte ZDoom. Il ne transforme pas DOOM en plateforme d'entraînement, et il ne prétend pas proposer un modèle rival. Ici, le réseau fait une inférence : on lui fournit des valeurs (les pixels, par exemple) et il calcule une sortie.
Cette distinction évite une confusion fréquente dans les démos « IA ». La question n'est pas seulement : « est-ce que ça donne le bon chiffre ? » Il y a au moins trois étages. D'abord, le réseau peut-il être représenté dans la carte ? Ensuite, le moteur exécute-t-il bien les opérations prévues ? Enfin, le modèle reconnaît-il effectivement l'image ? Doomformer apporte une preuve détaillée pour les deux premiers points. Le troisième dépend de la qualité du réseau et des données, et ne se résume pas à une exécution correcte.
Pourquoi cette contrainte est intéressante
En pratique, on évalue souvent un calcul via des composants optimisés : processeurs, bibliothèques numériques, accélérateurs. Doomformer fait l'inverse. Il prend un système qui n'a pas été conçu pour ça et demande : « qu'est-ce qu'on peut en tirer, sans perdre le contrôle sur le résultat ? »
Le point utile, c'est la différence entre représenter un calcul et le rendre efficace. La carte peut exécuter le réseau de façon vérifiable, mais le coût de l'approche la rend inutilisable en conditions réelles. Là où le projet devient intéressant, c'est dans la traduction, dans la visibilité des états, et dans le test exact - pas dans la vitesse.
Comment vérifier que les résultats sont exacts ?
Une démo visuelle peut donner confiance tout en laissant passer un détail (un signe, un arrondi, une unité). Doomformer vise plus strict : Python lit les valeurs exposées par le jeu et les compare à une référence entière calculée avec NumPy. Tolérance : zéro. Autrement dit, une seule valeur différente suffit à faire échouer l'exécution.
Pour le parcours du chiffre, le projet indique que les 248 valeurs contrôlées correspondent exactement à la référence. Ça couvre les pixels, les valeurs de la couche cachée, les comparaisons et les sorties. Certaines valeurs sont lues avec leur version négative, ce qui permet de contrôler davantage que le seul résultat final.
Ce que « tolérance zéro » garantit
Cette vérification établit que, pour l'exécution testée, DOOM reproduit les valeurs entières attendues par le réseau de référence. C'est une preuve de concordance entre deux chemins de calcul : celui encodé dans le niveau et celui calculé avec NumPy.
Mais ça ne veut pas dire que le modèle est « infaillible », ni que la reconnaissance sera toujours correcte. Si le réseau de référence se trompe sur une image, DOOM peut reproduire exactement la même erreur. En clair : exactitude du calcul et exactitude de la prédiction sont deux sujets différents. Doomformer teste le premier ; le second reste une affaire d'évaluation du modèle.
La preuve reste aussi limitée à ce qui est réellement lu et comparé. Avoir une exécution exacte sur les valeurs exposées ne certifie pas automatiquement que n'importe quelle carte, n'importe quelle entrée ou n'importe quelle configuration de moteur se comportera de la même façon. On valide ici la traduction et l'exécution choisies, pas « tout DOOM, partout ».
Pourquoi comparer les valeurs intermédiaires
Se contenter du chiffre affiché laisse trop de place aux coïncidences. Le résultat peut être correct même si une erreur s'est compensée plus tôt. À l'inverse, un mauvais affichage peut venir du script d'interface, pas du réseau.
Comparer les états intermédiaires rend le diagnostic plus utile. Si une valeur diverge dans la couche cachée, le problème est avant les comparaisons finales. Si les activations concordent mais que les sorties divergent, il faut chercher du côté du classement ou de la sélection. C'est précisément cette approche - validation de traduction - qui fait passer la démo du « spectaculaire » au « testable ».
Quelles performances et quelles limites faut-il attendre ?
Doomformer est lent, et ça ne se cache pas. Pour un chiffre, une lecture peut prendre 5 705 tics de jeu avec le calendrier d'exécution par défaut, soit environ 163 secondes de DOOM en temps réel. Avec --opt 3, la même lecture tombe à 273 tics, soit environ huit secondes de jeu réel. Le temps mural peut varier, parce qu'il inclut aussi le lancement et les échanges avec l'environnement.
L'écart entre les deux modes est net : l'optimisation du calendrier réduit fortement l'attente. Mais même huit secondes pour une inférence minuscule reste très loin d'un calcul « pratique ». La comparaison avec NumPy - environ 23 000 fois plus lent côté moteur, ou jusqu'à 65 000 fois avec la mesure autour de l'appel complet - donne l'ordre de grandeur du compromis.
Ce que l'optimisation change réellement
L'option --opt 3 accélère surtout le déroulement de la carte en modifiant le calendrier d'exécution. Elle ne transforme pas les poupées vaudou en processeur spécialisé, et elle ne change pas la nature de l'approche. À voir comme une optimisation de la démo, pas comme une voie vers une exécution compétitive.
Le compromis reste le même : observabilité contre vitesse. Une exécution lente rend visibles les étapes, facilite le suivi de l'état du niveau et rend la démo interactive. Une exécution plus rapide réduit l'attente, mais ne supprime ni le coût structurel du moteur, ni les limites d'un encodage conçu autour de mécanismes de jeu.
Les limites à garder en tête
Doomformer n'est pas un bon candidat pour entraîner un réseau, faire des prédictions pour des utilisateurs, ou réduire le coût d'un modèle en production. Pour ces besoins, les bibliothèques numériques et les accélérateurs sont faits pour traiter des tableaux et répéter des opérations efficacement.
Le projet demande aussi un environnement spécifique : ViZDoom, Freedoom, et des outils de compilation pour bâtir certains composants. L'installation ressemble donc plus à celle d'un projet expérimental qu'à celle d'une application « prête en deux clics ».
Cela dit, les contraintes collent à l'objectif. Le ralentissement rend visible le prix de la représentation choisie, la carte offre un terrain d'expérimentation atypique, et la vérification stricte empêche de se contenter d'un résultat « plausible ». Pour une démo pédagogique ou un projet ésotérique de calcul, ces limites font partie du sujet.
Comment tester Doomformer et à quels usages le réserver ?
Le dépôt fournit plusieurs commandes pour explorer le projet. doomformer doctor vérifie ViZDoom, Freedoom et une configuration d'affichage. Il construit ACC s'il manque, puis compile une carte de test. C'est un bon point de départ : les dépendances ne se résument pas à installer un paquet Python.
doomformer hello lance un petit réseau et vérifie les valeurs calculées. Pour observer la reconnaissance d'un chiffre dans le jeu, doomformer draw --digit 7 automatise le dessin et la lecture. Sans --digit, vous pouvez dessiner vous-même et lancer la lecture via l'interface.
Préparer l'environnement
Le projet vise Python 3.11 ou plus, sur Linux ou macOS. La première compilation nécessite notamment Git, CMake, un compilateur C et un accès réseau pour récupérer les dépendances. Sur certaines distributions Linux, il faudra aussi installer les outils de compilation via le gestionnaire de paquets du système.
Le plus logique est de lancer le diagnostic avant d'essayer tout le parcours. Si ViZDoom ou Freedoom manquent, ou si l'environnement graphique n'est pas disponible, le problème se verra plus tôt. Le premier lancement peut être plus long : des éléments doivent être construits.
Le projet propose aussi un notebook Colab. Il évite une partie de la configuration locale : vous dessinez sur une zone du navigateur, puis l'image est envoyée au calcul dans DOOM, sans piloter le marine. Pratique pour découvrir, mais ça ne remplace pas l'expérience complète où vous dessinez directement dans la carte.
À qui le projet peut-il servir ?
Doomformer intéressera surtout des développeurs qui veulent étudier une compilation atypique, la représentation d'états dans un moteur, ou la validation d'une traduction entre deux implémentations. Il peut aussi servir à expliquer comment on peut obtenir un calcul exact sans pour autant viser des performances.
Pour une équipe produit, une entreprise ou un laboratoire qui veut exécuter un modèle efficacement, la réponse est plus directe : ne répliquez pas cette architecture. Elle n'apporte pas d'avantage opérationnel établi. En revanche, sa méthode de validation - comparer les valeurs intermédiaires plutôt que le seul résultat final - est une bonne idée transférable à des compilateurs, des moteurs de règles, ou des systèmes embarqués.
Le critère d'évaluation est donc simple : vous voulez apprendre comment un calcul peut être représenté et contrôlé dans un environnement inattendu, ou vous cherchez à optimiser une inférence ? Doomformer répond bien à la première question. À la seconde, il répond... volontairement à côté.
Conclusion
Doomformer montre qu'un réseau neuronal entier peut être traduit en carte DOOM, exécuté par ViZDoom et contrôlé valeur par valeur face à une référence NumPy. Ce n'est pas un projet de vitesse : les temps annoncés sont bien au-dessus d'un calcul numérique classique. Sa force, c'est de rendre concrète une question de compilation et de validation que les abstractions logicielles cachent souvent.
Si vous cherchez une application « réelle », prenez un environnement fait pour le calcul. Si vous voulez comprendre comment des mécanismes de jeu peuvent porter des données, et pourquoi il faut vérifier les états intermédiaires plutôt que le seul résultat final, Doomformer fait une démonstration solide. À tester en gardant cette idée en tête : le jeu peut calculer juste, sans que ce soit une façon raisonnable de calculer.
Comment Doomformer transforme-t-il les calculs en mécanique de jeu ?
La carte n'est pas un simple décor posé sur un programme Python. Les éléments de DOOM servent à transporter des données et à déclencher des opérations. Les poupées vaudou font le travail « actif », tandis que des propriétés de secteurs - notamment l'éclairage et la hauteur des plans - servent à conserver et lire des valeurs. Des lignes au sol et des séquences en escalier servent aussi à représenter des poids ou des activations.
L'idée générale consiste à traduire le réseau en opérations que le moteur sait déclencher, et en états que le moteur sait exposer. Au lieu de demander à DOOM de manipuler directement un tableau comme le ferait NumPy, le compilateur répartit les étapes dans la structure de la carte, et s'appuie sur les scripts ACS et les règles du moteur.
Des poupées vaudou comme unités de calcul
Dans DOOM, des départs supplémentaires permettent d'obtenir des copies du joueur, appelées poupées vaudou. Doomformer s'en sert pour organiser l'exécution du réseau. Selon la démo, une carte peut en mobiliser beaucoup : l'exemple de reconnaissance de chiffres en utilise 1 355.
La métaphore aide à visualiser, mais le point technique est plus concret : le réseau devient un assemblage d'entités, de déclenchements et de lectures de valeurs. Les données ne vivent pas dans un tenseur optimisé ; elles sont encodées dans des propriétés du niveau. Résultat : l'exécution est « lourde » parce qu'un calcul vectorisé en bibliothèque numérique se transforme ici en une série d'états et de cycles de jeu.
Du pixel à la réponse affichée
Dans l'exemple MNIST, les 784 pixels alimentent une couche cachée de 64 unités. Ensuite, le système compare les scores deux à deux : 45 comparaisons suffisent à départager dix chiffres. Ces comparaisons produisent dix comptes de victoires, et le chiffre final vient du vainqueur.
Tout se termine côté niveau. Le chiffre gagnant est associé à une poupée qui traverse une ligne ; ce passage déclenche un script qui allume le chiffre correspondant sur un afficheur à sept segments. Oui, le résultat est visible dans le jeu. Mais l'affichage n'est pas la seule preuve : Doomformer lit aussi les valeurs intermédiaires.
Le contrôle manuel et le mode automatisé
Le projet propose aussi un mode où l'utilisateur dessine directement dans DOOM. En maintenant le tir, le marine colorie une zone de cases au sol avec un pinceau de 3 × 3. Une action de lecture transmet alors les 784 pixels au réseau.
Avec l'option
--digit, Python prend le contrôle du marine et simule les commandes pour dessiner un chiffre, puis lancer la lecture. Le moteur exécute le calcul, et Python récupère les valeurs. Cette séparation est pratique : elle permet de distinguer l'entrée dessinée dans le jeu de la comparaison numérique effectuée en dehors du moteur.