Atlas de Bretonnie

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.

La carte de campagne en jeu : le Chêne des Âges, la Clairière Royale et des bois sous la neige
Capture en jeu : la carte de la Saison dans notre Warhammer III, le Chêne des Âges, la Clairière Royale et des bois sous la neige.

Le cerveau et l'exécution

Moi j'ai le cerveau, et toi tu es l'exécution.

Charles, à Claude

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.

Qui décide ?L'IA le fait seuleLire le disque, les journaux, les vidagesÉcrire et corriger ses scripts, dans son domaineLancer ses essais sans fenêtreTenir les documents du projetL'IA demande d'abordLancer le jeu : personne ne touche au PC pendantl'essaiPrendre l'écran, puis vérifier le clavierPublier, poster, envoyer quoi que ce soitJamais à l'IALes mots de passe et les comptesSupprimer : seul l'humain supprimeLe jugement final, en jeu, face à la référenceUn fait de lore sans source
Trois familles de gestes : ce que l'IA fait seule, ce qu'elle demande d'abord, ce qui reste à l'humain. Dans le doute, elle demande. Au début (Premier pas, geste 5), tout passe par « demande d'abord » ; la bande verte s'élargit ensuite, dans les autorisations de l'agent. Ces règles s'écrivent dans le point d'entrée, et ce qui doit tenir à coup sûr, dans les autorisations : une règle écrite oriente, elle ne verrouille pas.

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 erreurquoi → symptôme → causeQuelqu'un l'avait-ildéjà écrite ?ouinonÉvitablela règle qui l'éviteDécouvertela preuveCodéeun script qui refused'avancerLe guidele fait rejoint sespièges : il devientévitablesi possible
Chaque erreur comprise s'écrit : évitable, elle donne une règle, codée si possible dans un script qui refuse d'avancer ; découverte, elle donne une preuve, et le fait rejoint le guide.

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.

Une règle, trois forcesVerrouillée dans l'agentses autorisations (règles « ask », « deny ») ou unhook avant chaque commande : l'agent ne peut pluspasser outre.Claude Code : /permissions, ou.claude/settings.json ; Codex : voyez sa documentationCodée dans un scriptil refuse d'avancer : un fichier déclaré mais absentdu pack, une erreur de syntaxe Lua, un startpos dontle compteur de sauvegarde ne vaut pas 1.Écritedans le point d'entrée : l'agent la lit… et peutl'oublier.« jamais de Python par heredoc » : écrite le 21 septembre,enfreinte plus de dix fois en trois joursplus sûr
Une règle écrite oriente l'agent ; codée dans un script qui refuse d'avancer, ou verrouillée dans ses autorisations, elle l'arrête vraiment.

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 passe

Il est déclaré dans le fichier .claude/settings.json 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.

Le témoinLe témoinun cas connu pour bon :chez nous, le projet deChaosRobie, sous unautre nomNotre casce qui plante, ou nefait rien : notrecarte, nos fichiersLa même commande, recopiée du journaldrapeaux compris, même pack, même moment : une seule différence,le cas essayé.témoinle nôtreLa cause est dans notre cas : on cherche dans nosfichiers, et seulement là.La cause est ailleurs : l'outil, la commande, lamachine. Chez nous, en vingt minutes : nosfichiers étaient hors de cause.Trois règles, payées cher1Rejouer le témoin à chaque essai, pas seulement audébut.oubliée : une dizaine d'essais invalidés2Recopier la commande du journal, drapeaux compris.un drapeau oublié : le jeu sort en 9 s, six essais perdus3Une seule différence entre deux mesures : mêmecampagne, même pack.deux campagnes comparées : un faux progrès annoncé vingtminutes
Un témoin, c'est un cas connu pour bon, rejoué à l'identique à côté du nôtre : s'il passe et pas nous, la cause est chez nous ; s'il échoue aussi, elle est ailleurs. Les trois règles du bas viennent du journal des erreurs (entrées 30, 39 et 35).

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.

Quatre sessions, un chantierLes ressources communesL'Assembly Kit : un préavis d'au moins 5 minutes ;l'heure est calculée par un script.14 h 00on annonce : « à 14 h 05 »au moins 5 min14 h 05on écrit, pas avantLe jeu, Terry, le startpos : on prévient les autressessions.Le pack : jamais reconstruit pendant un essai en jeu.Les documents communs : un seul rédacteur ; les autreslui envoient leurs erreurs.Un fichier neuf : vérifier d'abord que son nom est libre.Pack et startposle pack, le startpos,les essais ; lesdocuments communsDonnées et scriptsles tables, lesscripts, les textesRendu de la carterivières, lacs, ponts,montagnes, texturesExtensionla carte à venir, cesiteRanger, jamais supprimer : seul l'humain supprime.
Chaque session a son domaine et y écrit seule ; ce qu'elles partagent (le kit, le jeu, le pack, les documents communs) obéit à des règles écrites, que chacune relit au début de sa séance.

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.

Sans fenêtre d'abordL'IA à l'écrand'abord, se demander ce que l'écran apprendraitque le disque ne donne pas ; personne ne toucheau PC ; après, vérifier le clavier.seulement avec votre accordVous : à la mainTerry : peindre, poser les objets ; le jugementen jeu.Vous : un clicBOB : Start, ou Process with BOBdans Terry ; CAIME : importer une couche(Tools → Import → Layer data).L'IA seule, sans fenêtrefichiers, tables XML, rules.bob, couches.hex_layer écrits par script ; RPFMpar MCP ; CAIME : process et validate.à préférerplus lent, plus risqué
Plus on monte, plus c'est lent et risqué : ce qui peut se faire sans fenêtre ne se fait pas à l'écran.

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 : la clairière d'hiver, forêt sombre et dense, neige turquoise, grands cristaux clairsWarhammer I
Warhammer III, notre carte le 24 septembre : sol pâle gris-lavande, arbres givrés épars, cristaux lavandeWarhammer III, 24.09
La clairière d'hiver, filmée en jeu le 24 septembre vers 3 h : forêt sombre et neige turquoise dans Warhammer I, sol pâle et arbres épars chez nous. Aucun bilan chiffré ne le disait ; la comparaison côte à côte, si.

Un 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.

Premier pasFaire une copie datée du dossier du modou le mettre sous git : l'agent écrit dans vos fichiers, lacopie permet de revenir en arrière.1Installer l'agentClaude Code ou Codex, depuis leur page officielle ; tousdeux existent aussi en application de bureau.2L'ouvrir dans le dossier du moddans un terminal ; pour Codex, codex au lieu de claude ;dans l'application de bureau, ouvrez ce même dossier.cd mon_modclaude3Écrire le point d'entréeà la racine : vos décisions, vos règles, ce qu'il fautlire ; pour Claude Code, un CLAUDE.md ; pour Codex, unAGENTS.md ; dans Claude Code, /init en propose un premierjet à corriger.CLAUDE.mdAGENTS.md4Garder les autorisationspar défaut, l'agent demande avant chaque commande et chaqueécriture : ne cochez pas « ne plus demander » au début ;/permissions liste les règles.Le point d'entrée oriente l'agent, il ne verrouille rien :un interdit sûr se règle dans ses autorisations.5Brancher RPFMlancer rpfm_server.exe ; l'ajouter à l'agent depuis unautre terminal ; vérifier avec /mcp (pas à pas dans leguide IA de l'atelier).6Première consigne, en lecture seule« Décris-moi mon pack sans rien modifier, et dis d'où tutiens chaque information. »Jugez la réponse avant toute écriture.7Une vraie petite tâche« Change le prix de cette unité, montre-moi la ligne avantet après, et dis-moi comment le vérifier en jeu. »Jugez en jeu : si c'est juste, vous venez de gagnervotre première soirée.8
Huit gestes, de zéro à la première tâche jugée en jeu : une copie pour revenir en arrière, l'agent dans le dossier du mod, un point d'entrée, des autorisations, RPFM branché, une consigne qui ne modifie rien, puis une vraie petite tâche.

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.

Proposer une idéeVoir la carte