Journal de l'atelier · · 11 min de lecture
Travailler avec une IA sur un gros mod Total War
Quatre jours, un gros mod, et une IA à l'exécution. Voici la méthode que j'ai mise en place avec Claude, l'assistant IA d'Anthropic, pour porter La Saison de la Révélation dans Warhammer III : les fichiers, les garde-fous et les habitudes qui ont tenu, avec des extraits réels, et par où commencer si vous voulez tenter l'aventure.

Le cerveau et l'exécution
Moi j'ai le cerveau, et toi tu es l'exécution.
Ce partage n'est pas une formule. Je fixais la vision, je prenais les décisions, et surtout je jugeais en jeu, mes captures de Warhammer I et de Warhammer III côte à côte.
Claude faisait le reste. Ce qu'il a produit, et pourquoi un agent de pointe plutôt qu'une IA gratuite, je l'ai raconté dans Une carte entière en quatre jours ; ici, je montre comment on a travaillé ensemble.
Mes décisions sont écrites dans le fichier que l'IA lit en premier, avec la mention « à ne pas rediscuter ». Une IA qui reprend le travail le lendemain ne repropose donc pas une option que j'ai refusée, comme découper la carte des Empires Immortels. On ne rejoue pas les mêmes débats à chaque session.
Le journal des erreurs
Le premier jour, j'ai demandé à Claude : « prends bien note de toutes les erreurs que tu as faites et fais en sorte que ça n'arrive plus ». Il en est sorti un fichier, le journal des erreurs : environ 146 entrées le 23 septembre, plus de 260 deux jours plus tard.
Chaque entrée tient en quatre temps : ce qui a été fait, le symptôme, la cause, la règle. En voici une, telle qu'elle est dans le fichier (lignes recoupées pour le téléphone) :
21. [évitable] Deviner le nom d'un fichier
produit par un outil.
Pour l'aller-retour du map.hex, j'ai passé
Attritions.hex_layer à import-layer alors
que export-layer avait écrit
layer_attritions.hex_layer et l'avait
affiché ; l'import a échoué (« Layer file
not found ») et la comparaison d'octets a
conclu « identique » sur un fichier jamais
réécrit.
→ Règle : réutiliser le chemin imprimé par
l'outil ; un test qui compare deux fichiers
vérifie d'abord que l'écriture a eu lieu
(horodatage ou message « Saved »).
Codée dans le script d'aller-retour.Remarquez le symptôme : un test qui dit « identique » alors que rien n'a été écrit. C'est le genre de faux succès qu'une IA rapporte de bonne foi, et que seule une règle précise empêche de revenir.
Chaque entrée porte aussi une étiquette, décidée par une seule question : quelqu'un l'avait-il déjà écrit quelque part ? Si oui, l'erreur était évitable, et l'entrée donne la règle qui l'évite. Si non, c'était une découverte : l'entrée donne le fait et sa preuve, puis le fait rejoint la liste des pièges de notre guide, qui en comptait 135 le 23 septembre (150 le 25).
Une règle écrite s'oublie : on la code
La leçon la plus nette du journal, c'est qu'une règle seulement écrite se ré-oublie. Quand c'est possible, on la transforme en garde-fou dans un script. Un garde-fou ne se fatigue pas, et il ne compte pas sur sa mémoire.
- La construction du pack refuse de partir si un fichier déclaré dans une table manque.
- Elle vérifie la syntaxe de chaque script Lua avant de l'embarquer.
- L'injection des textes refuse un texte qui contient un caractère de contrôle.
- Un contrôle vérifie que le compteur de sauvegarde du startpos vaut 1.
- Tout pack qui touche une table de base passe un essai de démarrage scripté avant d'être annoncé.
L'inverse est instructif. Une règle toute simple, ne jamais écrire un script par un « heredoc » (un bloc de texte collé dans une commande du terminal), a été enfreinte plus de dix fois en trois jours, par plusieurs sessions. Le plus souvent sans dégât, une fois avec 102 textes français privés de leur ponctuation, réparés ensuite.
Le garde-fou, en vrai
Le 24 septembre au soir, après la neuvième rechute de la journée, on est passé au cran le plus sûr : un crochet (« hook ») de Claude Code. C'est un petit script que Claude Code lance avant chaque commande de l'agent ; si la commande a une forme interdite, elle ne part pas, et l'agent reçoit le conseil à la place.
# .claude/hooks/garde_commandes.py (extrait)
# Claude Code le lance avant chaque commande.
def motif_refus(outil, cmd):
if PYTHON.search(cmd):
if HEREDOC_BASH.search(cmd):
return ("Python passé "
"par heredoc (<<)")
# … python -c composé, sed à antislashs
return None
motif = motif_refus(outil, cmd)
if motif:
sys.stderr.write(
"Commande refusée par le garde de "
f"l'atelier : {motif}. {CONSEIL}")
return 2 # refus : l'agent lit le message
return 0 # sinon, la commande passeIl est déclaré dans le fichier .claude/ du projet, sur les commandes Bash et PowerShell. Avant de le brancher, on l'a essayé sur quinze commandes (sept à refuser, huit à laisser passer). Et une panne du garde laisse passer la commande : un garde-fou ne doit jamais bloquer le travail par sa propre faute.
Les cinq règles qui coûtent le plus
Les cinq premières entrées du journal sont des règles de méthode. Ce sont celles qui ont coûté le plus de temps quand on les a oubliées.
- Ne jamais jeter les messages d'un validateur : les regrouper et les compter. Filtrés trop fort, ils cachent la cause.
- Vérifier la donnée avant de crier au bug : un message d'outil qui cite une table se vérifie dans la table.
- Faire relire un document de référence contre ses sources avant de le livrer : la première version de notre guide contenait neuf erreurs.
- Se demander ce que l'écran apprendrait que le disque ou la ligne de commande ne donnent pas, avant de piloter une fenêtre.
- Ne jamais lancer un outil avec des options devinées : l'option d'aide de BOB ouvre une boîte qui bloque le programme.
Le témoin, toujours le témoin
Une bonne part de nos pannes s'est réglée de la même façon : en comparant avec quelque chose qui marche. Un témoin, c'est un cas connu pour bon, qu'on fait tourner à côté du nôtre. Le projet de terrain de ChaosRobie, copié sous un autre nom, a prouvé en vingt minutes que BOB n'en voulait pas à nos fichiers.
Encore faut-il rejouer le témoin à l'identique. Une nuit, Claude l'a relancé sans un drapeau de la commande d'origine : le jeu sortait en neuf secondes sans rien faire, et six essais ont été perdus à chercher une régression qui n'existait pas. Une autre fois, il m'a annoncé un progrès pendant vingt minutes en comparant deux mesures prises sur deux campagnes différentes.
L'astuce qui rend la deuxième règle facile : nos journaux d'essai ont une section « Ce qu'il faut refaire pour rejouer cet état », avec la commande exacte, prête à copier. Avant de rejouer un témoin, on la relit ; on ne la retape jamais de mémoire.
Plusieurs sessions en parallèle
Claude a travaillé en plusieurs sessions à la fois : plusieurs conversations ouvertes sur le même dossier, chacune avec son domaine, et seule à y écrire. Une session construisait le pack, le startpos et le terrain, et tenait la documentation ; une autre s'occupait des données de jeu, des scripts et des textes.
D'autres ont été ouvertes ensuite : le rendu de la carte, l'extension à toute la Bretonnie, la mise à jour 9.0 et le Duc écarlate, puis les illustrations.
Ces règles sont nées de ratés. Le premier jour, deux sessions ont travaillé sur les mêmes fichiers : une demi-heure de réconciliation. Plus tard, une session a écrasé le script d'une autre, restauré à l'octet près. Et une session a écrit dans le kit avant la fin de son préavis, quatre fois dans la même journée.
Pour ce dernier raté, la réponse a encore été un script : l'heure annoncée aux autres sessions et la fin du minuteur sont maintenant la même valeur, calculée une seule fois, au lieu d'un « environ cinq minutes » réglé à la main.
L'humain devant l'écran
Le point faible, ce n'était pas l'IA seule : c'était l'IA et moi sur le même ordinateur. Une nuit, Claude pilotait l'écran pour placer la caméra de Terry pendant que je travaillais. Ensuite, Windows croyait la touche AltGr enfoncée, et je n'arrivais plus à écrire.
Depuis, Claude demande avant de prendre l'écran et vérifie l'état du clavier après. Dans l'autre sens, j'ai cliqué dans des parties d'essai qui semblaient figées, et on a cru à des plantages. Maintenant, il me prévient avant chaque lancement du jeu, et il lit mes clics dans le journal du jeu avant de conclure.
Le juge, c'est moi
Mon rôle de juge, lui, s'est révélé irremplaçable. Les audits de Claude voyaient 45 objets volants quand j'en voyais partout, et ses chiffres étaient bons quand je ne reconnaissais plus la carte.
Warhammer I
Warhammer III, 24.09Un algorithme ne mesure que ce qu'il croit faire ; mes yeux, face aux captures de Warhammer I, mesuraient ce que le joueur verra. Depuis, la règle est écrite : ce qui se voit en jeu se vérifie en jeu, et l'IA annonce la mesure du résultat, jamais le bilan de son algorithme.
Ce qui a marché
- Le débogueur. Un rapport de plantage lu au débogueur dit quelle donnée manquait. C'est ce qui a débloqué le startpos, le chargement et la fin de tour.
- Les exemples de CA d'abord. Avant d'inventer une convention, on regarde comment CA fait sur une carte qui marche. Les ports de nos villes ont été corrigés en exportant une carte de CA.
- Les captures côte à côte. Warhammer I d'un côté, Warhammer III de l'autre : c'est la référence, pas les chiffres.
- Les sauvegardes horodatées. Une copie avant toute écriture dans les tables du kit. Une panne du premier soir n'a été résolue que parce qu'on pouvait comparer avec le dernier état qui marchait.
- Les parties automatiques. Des parties jouées sans moi, un seigneur choisi et l'IA aux commandes des autres factions : un plantage d'effet visuel a été débusqué ainsi chez trois autres seigneurs, sans attendre qu'un joueur tombe dessus.
- Une photo avant chaque mise à jour du jeu. Avant la 9.0, on a relevé l'état du jeu pour pouvoir comparer après.
Une partie automatique se lance d'une ligne, et rend un bilan qu'on lit comme un rapport de match. Voici celui d'une partie de dix tours avec Morghur, le 25 septembre :
# la commande (sur une seule ligne) :
python essai_tours_auto.py
--seigneur morghur --tours 10
# le bilan.json qu'elle rend (extrait) :
{
"seigneur": "morghur",
"tours_demandes": 10,
"all_players_ai": true,
"issue": "fin",
"dernier_tour": 10,
"compteurs": {
"erreurs": 0,
"blocages": 0,
"chargements_rates": 0,
"executions_ratees": 0
}
}Zéro erreur, zéro blocage, la partie est allée à son terme. Une limite à connaître : dans ce mode, la faction du joueur ne joue pas. Ces parties prouvent que la campagne tient ; les mécaniques des seigneurs se vérifient à la main.
Comprendre, pas seulement faire tourner
Une question qu'on m'a posée cette semaine en présentant le mod : est-ce qu'on finit avec du code que plus personne ne comprend ? La question est juste. Ma réponse : si je ne peux pas résumer ce qu'un script fait en une phrase, je ne l'accepte pas, même s'il tourne.
Chez nous, ça se traduit par des habitudes simples : des noms de scripts et de variables clairs, en français comme le reste du projet ; et en tête de chaque fichier, ce qu'il fait et pourquoi, avec le numéro de l'erreur qui l'a fait naître. Par exemple, le contrôle du startpos (le fichier de départ de la campagne) :
"""
verifier_compteur_startpos.py - le startpos
porte-t-il les valeurs de script d'une
partie neuve ?
Pourquoi (23.09.2026, erreur 112) :
cm:is_new_game() vaut « __save_counter == 1 ».
Le compteur n'est écrit que si les scripts
de la campagne tournent pendant la
génération du startpos. Un startpos plus
ancien que les scripts le laisse à 0 :
chaque nouvelle partie passe pour une
sauvegarde (ni intro, ni missions).
"""Quand un script me revient d'une séance à l'autre, je relis cet en-tête, même sans maîtriser tout le code : c'est aussi ma mémoire du projet, pas seulement celle de l'IA.
L'autre crainte qu'on me pose souvent : est-ce que je ne vise pas trop large ? La Saison de la Révélation est d'abord achevée à l'échelle où elle était dans Warhammer I, avant même de penser à toute la Bretonnie ; et sur le Workshop, deux versions séparées sont prévues, la carte d'origine et une version étendue. Le plus petit projet qui tient debout et qui sort vaut toujours mieux qu'un grand projet qui reste dans un coin.
Mes conseils
- Écrivez vos décisions, avec « à ne pas rediscuter » quand c'est tranché.
- Tenez un journal des erreurs dès le premier jour : quoi, symptôme, cause, règle.
- Codez les règles qui peuvent l'être ; relisez les autres à chaque séance.
- Exigez un témoin et une commande exacte avant toute conclusion.
- Jugez à l'image, en jeu, face à une référence, pas sur un bilan chiffré.
- Découpez le travail en domaines, avec un seul rédacteur par domaine.
- Ne partagez pas l'écran sans prévenir, dans les deux sens.
- Gardez tout : sauvegardes avant écriture, archives rangées, aucune suppression hâtive.
- Ne vous fiez jamais à un résultat que vous ne pouvez pas résumer en une phrase : faites-vous expliquer le script avant de l'accepter.
- Visez petit d'abord : livrez la plus petite version qui tient debout avant de penser à l'étendre.
Lundi matin, par où commencer
Si vous partez de zéro, voici la séquence complète, de l'installation à la première tâche jugée en jeu. Ne sautez pas le septième geste : une consigne qui ne modifie rien. Jugez la réponse, et surtout d'où l'agent dit tenir chaque information, avant de lui confier la moindre écriture.
Le récit complet de ces quatre jours est ici, et les neuf plus gros obstacles là. Et si vous voulez voir cette méthode appliquée à la suite, la carte de la Bretonnie entière se dessine en ce moment, avec vos idées.