Blog - 13 jours pour coder un émulateur d'arcade avec une IA

Comment un développeur senior et Claude ont construit un émulateur d'arcade jouable dans le navigateur en 13 jours. 22 000 lignes de code, 41 jeux, et beaucoup de leçons.

Par Thibaut Lion7 avril 2026

Street Fighter II tournant dans Sprixe — le résultat final

Un émulateur d'arcade dans un navigateur, codé en 13 jours

Street Fighter II, Final Fight, Cadillacs and Dinosaurs. Ces jeux d'arcade des années 90 tournent sur un hardware spécifique de Capcom, le CPS1. Des circuits imprimés avec deux processeurs, trois puces audio, deux puces vidéo. Un écosystème complexe que des équipes de passionnés mettent habituellement des mois, voire des années, à émuler.

Sprixe — contraction de "sprite" et "pixel" — est né en 13 jours. Un émulateur complet, jouable dans un navigateur, écrit en TypeScript, en pair-programming avec Claude, l'IA d'Anthropic.

22 000 lignes de code. 220 commits. 29 jeux supportés sur 38 au catalogue. 1 016 tests unitaires.

Ce n'est ni un miracle ni un coup de pub. C'est un retour d'expérience honnête sur ce que le développement assisté par IA permet réellement — et sur ce qu'il ne permet pas.

Pourquoi c'est difficile

Émuler un système d'arcade, ce n'est pas afficher des images à l'écran. C'est reproduire fidèlement le comportement de composants électroniques conçus dans les années 80. Chaque puce a son propre fonctionnement, sa propre logique, ses propres particularités. Et elles communiquent entre elles en permanence, à des cadences très précises.

Le CPS1 embarque sept composants majeurs qu'il faut émuler individuellement : deux processeurs, trois puces audio, deux puces vidéo. Chacun a ses règles, ses formats de données, ses timings. Et le moindre écart produit des bugs visibles : des couleurs fausses, des sprites à l'envers, du son silencieux, des jeux qui plantent au démarrage.

En temps normal, un projet de ce type prend des mois à un développeur expérimenté. La documentation est fragmentée, les spécifications sont parfois ambiguës, et les tests passent par la comparaison visuelle avec le hardware original.

Jour 1 : 8 900 lignes et un électrochoc

Le premier jour a été un choc.

En une seule session, Claude a généré 8 900 lignes de code structurées. Pas du code placeholder. Du vrai code d'émulation, avec la logique des deux processeurs, le décodage des graphismes, la gestion de la mémoire vidéo.

Et ça marchait. Partiellement, mais ça marchait.

Street Fighter II démarrait. L'écran titre s'affichait. Avec des artefacts graphiques, certes — des lignes parasites, des couleurs décalées, des zones corrompues — mais l'écran titre était là.

Le premier rendu de Street Fighter II — des artefacts graphiques partout
L'écran titre, à peine reconnaissable sous les glitches

Ce qui a suivi, c'est une cascade. Sept bugs graphiques en chaîne, chaque correction en révélant un nouveau. Les couleurs étaient fausses : le ciel orange au lieu de bleu. Les personnages apparaissaient en miroir. Les contrôles étaient inversés — le joueur 1 contrôlait le personnage du joueur 2.

Le son a demandé trois rounds de debug pour fonctionner. Puis il fallait gérer le plein écran. Quatre tentatives. Les APIs du navigateur pour l'audio et le plein écran sont pleines de subtilités de sécurité que l'IA ne maîtrisait pas du premier coup.

En fin de journée, le jeu était jouable de bout en bout. De l'écran titre au combat, en passant par la sélection de personnage. En un jour.

L'IA se trompe. Souvent. Sur des détails qui comptent.

Il serait malhonnête de raconter cette histoire sans parler des bugs que l'IA a introduits. Pas des oublis mineurs — des erreurs qui cassaient tout.

Le portrait de Ryu avec des artefacts de couleur rouge — un bug d'ordre des données

Le problème le plus récurrent : l'IA inversait l'ordre des octets. Pour comprendre sans entrer dans la technique : c'est comme si elle lisait systématiquement les numéros de téléphone à l'envers. 01 42 devenait 42 01. Ce bug est apparu au moins cinq fois au cours du projet, sous des formes différentes.

Un autre classique : les "protections" non demandées. L'IA ajoutait des gardes-fous dans le code — des vérifications de sécurité — qui changeaient le comportement du système. Dans un cas précis, une de ces protections rendait le son complètement silencieux. L'intention était bonne. Le résultat était catastrophique.

Plus troublant encore : un sous-agent (une instance de l'IA lancée pour traiter un sous-problème) a un jour "corrigé" quelque chose qui fonctionnait parfaitement. Sa correction a cassé le code. Il a fallu identifier le changement, comprendre qu'il était inutile, et l'annuler. L'IA qui défait ce que l'IA a fait — un scénario plus fréquent qu'on ne l'imagine.

12 heures de debug pour 3 lignes de code

C'est le moment qui résume le mieux la réalité du développement avec l'IA.

Cadillacs and Dinosaurs — un beat'em up classique de Capcom — démarrait correctement. Les graphismes s'affichaient. Mais le son était totalement absent. Pas un bruit, pas une note, rien.

L'IA et moi avons passé 12 heures à chercher le problème. Douze heures.

On a tracé l'exécution pas à pas. On a ajouté des logs partout. On a tenté des contournements, des hacks, des approches alternatives. L'IA générait des hypothèses, proposait des corrections. Rien ne marchait.

La solution est venue d'une intuition humaine, pas de l'IA. J'ai eu l'idée d'utiliser un émulateur de référence — MAME, un projet open-source qui fait autorité dans le domaine — pour comparer les traces d'exécution entre leur version et la nôtre. En deux minutes, la comparaison a révélé le problème : une instruction du processeur audio était mal décodée.

La correction tenait en trois lignes. Trois lignes que ni l'IA ni moi ne pouvions trouver sans cet outil externe. L'IA brassait du code à une vitesse folle, mais face à un bug aussi subtil — une erreur au niveau de la simulation hardware — c'est l'expérience du développeur qui a fait la différence. Savoir quel outil utiliser, quand l'utiliser, et comment interpréter ses résultats.

Tout jeter et recommencer : les pivots nécessaires

L'IA génère du code à un rythme impressionnant. C'est sa force. C'est aussi un piège.

Quand une approche ne fonctionne pas, la tentation est de continuer à itérer dessus — l'IA propose des correctifs, des ajustements, des patches. Mais parfois, la bonne décision est de tout supprimer et de repartir de zéro. Ce n'est pas une décision que l'IA prend seule. C'est le développeur qui dit : "On arrête, on change d'approche."

Le système audio a été réécrit trois fois. La première version, construite de zéro avec l'aide de l'IA, produisait du son — mais pas le bon. La deuxième, portée depuis le code de référence de MAME, était plus fidèle mais trop lente pour un navigateur. La troisième version a compilé le moteur de référence directement en WebAssembly — un format qui permet d'exécuter du code à des performances proches du natif dans un navigateur. C'est celle qui a tenu.

Le moteur de rendu — la partie qui affiche les graphismes à l'écran — a suivi le même schéma. La première version utilisait React, un framework web populaire. Après un jour, il est devenu évident que React ajoutait de la complexité sans apporter de valeur pour ce cas d'usage. Il a été supprimé au profit d'une approche plus directe.

Trois pivots majeurs en 13 jours. Chaque fois, du code généré par l'IA qui partait à la poubelle. Sans regret : le coût de génération est si faible que jeter du code n'est plus un frein psychologique.

La session la plus productive : supprimer 3 500 lignes

Jour 8 du projet. Audit du code. Un fichier fait plus de 4 600 lignes avec dix responsabilités différentes. C'est un signe classique de dette technique — du code qui a grandi trop vite sans être restructuré.

Le refactoring a été chirurgical : cinq extractions successives, chacune validée par les 903 tests unitaires existants. Le fichier est passé de 4 629 à 1 454 lignes. Moins 69 %.

Mais le vrai ménage est venu au jour 12. En passant le code au peigne fin, on a découvert des milliers de lignes mortes : des fonctionnalités abandonnées lors des pivots, jamais nettoyées. Du code qui compilait, qui était testé, mais qui ne servait plus à rien.

Bilan : 3 500 lignes de code supprimées, plus 360 lignes de styles orphelins.

La session la plus productive du projet n'est pas celle où le plus de code a été écrit. C'est celle où le plus de code a été supprimé. C'est contre-intuitif, surtout dans un contexte où l'IA pousse naturellement à produire toujours plus. Mais un codebase propre, c'est un codebase maintenable. Et la maintenabilité, l'IA ne la priorise pas spontanément.

Les chiffres, au final

  • 13 jours de développement
  • 220 commits (1 toutes les 45 minutes en moyenne)
  • 22 000+ lignes de TypeScript
  • 7 composants hardware émulés
  • 3 moteurs de rendu différents
  • 41 jeux supportés, 38 au catalogue CPS1
  • 1 016 tests unitaires, 115 tests de bout en bout
  • 8 releases (de la beta 1 à la version 1.0.5)
  • ~22 % de CPU en utilisation moyenne — remarquable pour un émulateur dans un navigateur
L'écran titre de Street Fighter II — rendu parfait après corrections

Sprixe n'est pas qu'un émulateur. C'est aussi un éditeur de sprites : on peut capturer les personnages du jeu, les exporter vers un logiciel de dessin professionnel, les modifier pixel par pixel, et les réimporter dans le jeu. Un outil créatif construit sur une base technique solide.

Ce que ça dit du développement avec l'IA

Après 13 jours intensifs de pair-programming avec Claude, voici ce que je retiens.

Ce que l'IA fait remarquablement bien :

  • Générer du volume. 8 900 lignes cohérentes en un commit, c'est surhumain. Littéralement.
  • Connaître les spécifications techniques. L'IA avait une connaissance encyclopédique des processeurs des années 80-90, de leurs jeux d'instructions, de leurs particularités.
  • Lire et comprendre du code de référence. MAME représente plus de 400 000 lignes de C++. L'IA naviguait dedans comme dans un livre ouvert.
  • Itérer rapidement. Un commit toutes les 45 minutes en moyenne, tests inclus.
  • Écrire des tests en masse. 103 tests pour 10 modules en une seule session.
  • Refactorer méthodiquement, avec validation continue par la suite de tests.

Ce que l'IA fait mal :

  • Les conversions subtiles. À chaque portage de code d'un langage à un autre, elle ajoutait des "sécurités" qui changeaient le comportement. Il fallait relire chaque ligne.
  • Les APIs du navigateur. Plein écran, audio, contraintes de sécurité : elle tâtonnait, essayait, échouait, réessayait. Rarement du premier coup.
  • La cohérence entre sous-agents. Quand plusieurs instances de l'IA travaillaient en parallèle, elles pouvaient se contredire.
  • Les valeurs numériques précises. Pour les constantes hardware, il fallait souvent deux ou trois tentatives avant de tomber juste.
  • Les bugs profonds. Face au problème du son de Cadillacs and Dinosaurs, 12 heures de tâtonnement pour un bug que seule l'intuition humaine et un outil externe ont pu résoudre.

La métaphore qui tient le mieux : l'IA est un développeur junior surpuissant. Elle code à une vitesse et un volume qu'aucun humain ne peut atteindre. Mais elle a besoin d'un senior pour piloter. Pour décider quand pivoter. Pour savoir quel outil utiliser face à un mur. Pour prioriser la qualité sur la quantité.

L'expertise humaine n'a pas été remplacée par l'IA sur ce projet. Elle a été amplifiée. Et c'est probablement la meilleure façon de décrire ce que le développement AI-native permet aujourd'hui : faire plus, plus vite, sans jamais relâcher l'exigence de qualité.

Treize jours pour un émulateur d'arcade complet. Pas parce que l'IA est magique. Parce qu'un développeur senior savait exactement quoi lui demander — et quand ne pas l'écouter.

On en parle ?

Un projet, une question, une idée. On répond sous 48h.

Pas de commercial, pas de chatbot. Vous parlez directement à quelqu'un qui code.