Comment c’est fait
Un développeur, un assistant de programmation IA, et beaucoup de règles vérifiées par la machine.
Par Nick
J’écris Prison Life avec Claude Code (l’agent de programmation d’Anthropic). Je décide de ce qu’est le jeu et des options que nous prenons ; l’assistant tape l’essentiel. Comme personne ne relit le code à part moi et un agent IA de relecture, je m’appuie sur l’automatisation : les règles sont imposées par des vérifications automatiques et par le build, pas par les bonnes intentions.
Délégation
La session principale de Claude Code planifie le travail et tient le suivi des tâches, la trace écrite des choix de conception et l’historique des modifications. Elle n’écrit pas de code : elle confie chaque changement, même minuscule, à un agent IA spécialisé. Chacun a sa propre définition écrite qui fixe son rôle et son modèle.
| Rôle | Niveau de modèle | Travail |
|---|---|---|
| Architecture | Opus | modèle de données, tick, threads, recherche de chemin, décisions |
| Code de simulation | Opus | systèmes de simulation, IA des personnages, boucles critiques |
| Performance | Opus | profilage, régressions du banc d’essai |
| Relecture (lecture seule) | Opus | relit un diff ; ne peut pas modifier de fichiers |
| Client et outils | Sonnet | client Godot, interface, outils |
| Tests | Sonnet | tests à partir des critères d’acceptation |
| Données de contenu | Sonnet | définitions JSON selon un schéma |
| Recherche, exécution des vérifications | Haiku | recherche dans le code ; exécution des vérifications et résumé des échecs |
Le travail difficile va au modèle le plus puissant, le travail de routine aux moins chers. Si un agent IA moins cher échoue deux fois aux vérifications, la tâche monte d’un niveau ; si le niveau le plus élevé échoue deux fois, il s’arrête et me demande.
Des hooks qui disent non
Les hooks de Claude Code sont des scripts qui s’exécutent autour des actions de l’assistant. Les miens imposent trois règles :
- Pas de fin sur du rouge. Quand une session ou un agent IA essaie de s’arrêter après avoir modifié du code, un hook lance la vérification rapide (build plus tests rapides). Si elle échoue, l’arrêt est refusé.
- La session principale ne peut pas modifier le code. Un hook rejette les écritures de la session principale dans les sources, les tests, le contenu et les outils.
- Le relecteur est en lecture seule. Ses outils d’édition sont retirés et un hook rejette les commandes qui modifient des fichiers ou l’historique du projet.
Ils protègent contre les erreurs, pas contre un contournement délibéré : une astuce de shell obstinée peut passer outre, et l’un des hooks voit une vérification rouge chez un agent IA sans pouvoir le retenir (le hook d’arrêt de la session principale l’attrape quand même). Je préfère le dire clairement.
Décisions écrites et vérifications
- Chaque choix non trivial est consigné. Les tâches, les jalons et les décisions de conception sont conservés en texte brut à côté du code, dans un outil de suivi des tâches. Quand nous choisissons entre des options qui touchent plus d’une tâche, le choix est consigné avec son contexte et ses conséquences.
- Les vérifications tournent sur ma machine. Pas de CI dans le cloud. Un script local a quatre modes :
fast,test,benchetfull. Les scripts et les hooks sont en PowerShell 7, sous Windows comme sous macOS. - Des vérifications à chaque changement. L’automatisation locale rejette un changement mal décrit ou mal formaté. Pour les changements de code, elle lance aussi la vérification rapide ; les changements qui ne touchent que les notes ou le site sautent le build.
- Les fichiers de référence sont protégés. Les hashes de déterminisme figés, les sauvegardes de référence et la référence du banc d’essai ne changent qu’avec mon accord explicite, jamais en silence.
- Le projet lui-même est la source de vérité. Un outil de mémoire local indexe le projet et les conversations passées pour la recherche, mais tout ce qui compte est aussi une tâche, une décision consignée ou un document.
Le noyau déterministe
La simulation vit dans une bibliothèque .NET pure, sans aucune référence à Godot ; le client Godot se contente de lire son état et d’envoyer des commandes. Le noyau suit des règles fixes : le monde ne change que par des commandes, le temps est fait de ticks entiers, l’aléatoire ne vient que des générateurs à graine du monde. La même graine et le même journal de commandes doivent donner le même monde. Ces règles sont vérifiées par le compilateur et par des tests, pas seulement par la relecture ; voir le devlog #1 pour savoir comment, et le devlog #2 pour le monde, les sauvegardes et les replays.
- Les commandes sont la seule porte d’entrée. Chacune a un identifiant de type stable et un encodage binaire, et chaque commande est journalisée avec son résultat, y compris les rejetées.
- Le tick a trois phases dans un ordre fixe. L’ordre des systèmes est fixé à un seul endroit du code, et le changer change chaque hash.
- L’aléatoire utilise nos propres générateurs (SplitMix64 et xoshiro256**). Des flux nommés sont dérivés de la graine du monde et stockés dans l’état du monde. Un générateur sans état à clé, piloté par un domaine, une clé et le tick, sert le travail indépendant de l’ordre.
- Le hash d’état est un hash de 64 bits sensible à l’ordre, pour les vérifications de déterminisme. Il n’est pas cryptographique.
- Le monde est une grille de tuiles de 1×1 m sur des niveaux distincts ; murs, portes et sols ne changent que par des commandes de construction.
- Les sauvegardes et les replays partagent un même conteneur de fichier vérifié. Un replay, c’est la graine plus le journal des commandes, avec des hashes de contrôle en cours de route, vérifié pas à pas à la relecture.
- Les bancs d’essai viennent d’un lanceur de scénarios sans interface, avec une référence par machine et un seuil de zéro allocation par tick.
L’objectif de conception est jusqu’à 1 000 détenus et membres du personnel à 20 ticks par seconde. C’est un objectif : il n’y a pas encore de personnages, donc le lanceur de bancs d’essai existe, mais rien n’a été mesuré à cette échelle.