30 août 2026

Code généré : six jeux, six défauts que la relecture a trouvés

Plusieurs des jeux du labo ont été produits avec de l'assistance à la génération de code. Je l'ai fait par curiosité professionnelle: je voulais savoir ce que ça donne vraiment sur un exercice contraint — un seul fichier, pas de bibliothèque, du canvas et rien d'autre — plutôt que d'en juger par ce qu'on en dit.

Puis j'ai relu chaque fichier ligne par ligne, comme je relirais le code d'un fournisseur avant de le certifier sur un décodeur. Ce texte rassemble ce que cette relecture a trouvé. Ce n'est ni un plaidoyer ni un réquisitoire: c'est un relevé de défauts, avec ce qu'ils m'apprennent sur ce genre d'outil.

Ce qui marche remarquablement bien

La structure est toujours correcte. Boucle de rendu avec requestAnimationFrame, séparation entre mise à jour et dessin, machine à états pour les phases de jeu, gestion propre du redimensionnement: rien de tout ça n'a jamais manqué. Sur des mécaniques bien documentées — la rotation d'une pièce qui tombe, la détection d'alignement dans une grille, un labyrinthe garanti connexe — le résultat est juste du premier coup et souvent élégant.

Le pointage du bowling est l'exemple le plus frappant. Les règles du dixième carreau sont un classique des entretiens d'embauche parce qu'elles piègent presque tout le monde. La version obtenue aplatit les lancers en une seule suite en mémorisant l'indice de départ de chaque carreau, ce qui règle les bonus d'abat et de réserve en deux lignes. C'est la bonne solution, pas une solution laborieuse qui fonctionne.

Ce qui casse, et pourquoi c'est toujours le même genre de chose

La friction qui dépend de l'écran

Dans le bac à sable physique, l'amortissement de l'air est appliqué une fois par image, sans être normalisé par le temps écoulé. Les balles perdent donc leur énergie deux fois plus vite sur un écran à 120 Hz que sur un écran à 60 Hz. Le jeu reste parfaitement jouable, et c'est exactement le problème: rien ne signale l'erreur tant qu'on ne change pas de machine. Sur un décodeur, ce genre de défaut se manifeste des mois plus tard, sur un modèle précis, et coûte une semaine à diagnostiquer.

L'état ressuscité par le redimensionnement

Dans le casse-briques, la fonction de redimensionnement rappelle celle qui construit la grille de briques. Redimensionner la fenêtre en pleine partie fait donc réapparaître toutes les briques déjà détruites, sans toucher au score. La cause est structurelle: la géométrie des briques et leur état vivant ou détruit partagent le même tableau, si bien qu'on ne peut pas recalculer l'une sans écraser l'autre. C'est une faute de conception des données, pas une étourderie.

La boîte de collision fantôme

Toujours dans le casse-briques, la capture d'un bonus teste un cercle de rayon 4 autour de son centre alors que le bonus est dessiné comme un rectangle de 26 sur 14. On attrape donc une pastille beaucoup plus petite que ce qu'on voit. Le joueur ressent le jeu comme injuste sans pouvoir dire pourquoi. C'est le type d'écart entre le dessin et la logique qu'aucun test automatisé ne détecte, parce que les deux moitiés du code sont correctes prises séparément.

Le commentaire qui décrit une intention plutôt que le code

Le cas le plus intéressant. Dans le bac à sable, un commentaire affirme que la pente de plots évite soigneusement les lettres du décor. En réalité le filtre porte sur la boîte englobante complète du mot: il y a un trou franc au milieu de la diagonale, pas un contournement des glyphes. Ailleurs, un commentaire annonce qu'il n'y a pas de plancher sur l'espacement, juste au-dessus de la ligne qui en impose un.

Ces commentaires ne sont pas des mensonges, ce sont des descriptions de l'intention formulée, pas du code livré. Et c'est le piège réel de ce type d'outil: le code est plausible, le commentaire est rassurant, et les deux se contredisent. Un relecteur pressé lit le commentaire.

Le motif commun

Aucun de ces défauts n'est une erreur de syntaxe ou d'algorithme. Tous relèvent de la même famille: un couplage implicite entre deux morceaux qui semblaient indépendants, une constante appliquée dans la mauvaise unité, un écart entre ce qui est affiché et ce qui est calculé. Ce sont précisément les erreurs qu'un humain fatigué commet aussi — sauf qu'ici elles arrivent enveloppées dans du code propre, bien nommé et bien commenté, ce qui les rend nettement plus difficiles à voir.

Ma conclusion pratique est la même que pour n'importe quel code que je n'ai pas écrit: il faut le relire en entier avant de le mettre en service, et se méfier davantage de ce qui est lisible que de ce qui est confus. Le code confus se fait relire. Le code élégant se fait croire.

Ça n'a rien enlevé à l'exercice. J'ai appris la génération procédurale de labyrinthe, le pointage officiel du bowling et l'intégration semi-implicite en lisant ces fichiers, ce qui était le but. Et j'ai retrouvé, sur des jeux de quelques centaines de lignes, exactement la discipline qu'on applique en intégration: on ne certifie jamais sur la foi de la démonstration.

Annexe : les demandes formulées

Par transparence, voici les demandes qui ont servi de point de départ à chacune des pages concernées. Elles étaient toutes en anglais et volontairement courtes.

Labyrinthe néon

Write a complete game in a single HTML file. Include CSS and JavaScript. Create a retro maze chase game. Control with the mouse. Include power-ups. Ensure smooth 60fps rendering using HTML5 Canvas.

Blocs néon

Write a complete game in a single HTML file. Include CSS and JavaScript. Create a retro falling-blocks game. All blocks should alternately have JF then So written on them. Control the blocks with left, right, down arrow keys. You can rotate the blocks with spacebar. Ensure smooth 60fps rendering using HTML5 Canvas.

Quatre en ligne néon

Write a complete game in a single HTML file. Include CSS and JavaScript. Create a retro four-in-a-row game. Control with keyboard arrow keys. Ensure smooth 60fps rendering using HTML5 Canvas.

Casse-briques néon

Write a complete game in a single HTML file. Include CSS and JavaScript. Create a retro brick breaker game. Add a glowing neon theme. Control the paddle with the mouse. Include power-ups like extra balls and wider paddles. Ensure smooth 60fps rendering using HTML5 Canvas.

Balles rebondissantes

Build a casual physics game in one HTML file. Use the HTML5 Canvas API. Drop colorful bouncy balls by clicking the screen. Place stationary pegs that balls bounce off. Include gravity and friction. Add a clear-all button.

Arbre fractal

Create a single HTML page that draws a beautiful, organic recursive fractal tree using the Canvas API. The main function must branch recursively, altering length, stroke width, and angle at each iteration level. When the recursion reaches the tips of the branches, draw tiny soft-pink leaf clusters using the arc() method. Include a native HTML range slider that allows a user to dynamically adjust the branching angle multiplier in real time.

Les défauts décrits plus haut sont tous encore dans les pages. Je les corrigerai au fur et à mesure, et je le noterai ici plutôt que de réécrire l'historique — un relevé de défauts sans les défauts ne vaudrait plus grand-chose.