# Les outils du moddeur de campagne : vue d'ensemble, startpos, plantages et essais

> Par où commencer quand on veut modder une carte de campagne de Total War: Warhammer III ? Cette page est le sommaire : chaque outil, à quoi il sert et son guide ; les mots du métier ; puis ce qui ne dépend d'aucun outil en particulier : la position de départ, les plantages, les parties d'essai automatiques. Écrit après quatre jours à porter une carte complète de Warhammer I dans Warhammer III.

Page : https://bretonia.dev/atelier/outils/ · Atlas de Bretonnie, atelier des moddeurs · mis à jour le 2026-09-25. Version en texte brut, pour les lecteurs et les IA ; les schémas y sont décrits en mots. Relu le 25 septembre 2026, mise à jour 9.0. Écrit contre ses sources, CAIME 1.0.1, RPFM 5.0.6, l'Assembly Kit et le jeu au patch 8.1 ; ce que la 9.0 a changé sur notre chantier y est ajouté, le reste n'a pas été revérifié point par point.

## La boîte à outils en un coup d'œil

Une campagne passe par huit familles d'outils. Aucun ne fait tout, chacun a son domaine, et presque tous ont un piège. Les quatre premiers ont leur propre guide.

- **CAIME (Campaign AI Map Editor)** : L'éditeur du Campaign Map Toolkit, pour la moitié logique de la carte : régions, sols, climats, routes, villes, et ses exports (Map Data, pathfinding, frontières). ([Le guide CAIME](https://bretonia.dev/atelier/caime/))
- **RPFM (Rusted PackFile Manager)** : Ouvrir, créer et modifier les packs : tables, textes, scripts, images ; ajouter une unité, une faction, un seigneur ; se laisser piloter par une IA (serveur MCP). ([Le guide RPFM](https://bretonia.dev/atelier/rpfm/))
- **Terry** : L'éditeur de terrain en 3D de l'Assembly Kit : relief, textures, végétation, objets, zones logiques. ([Le guide Terry](https://bretonia.dev/atelier/terry/))
- **BOB** : Le bâtisseur de l'Assembly Kit : il transforme les sources en fichiers du jeu et en packs, selon des fichiers `rules.bob`. ([Le guide BOB](https://bretonia.dev/atelier/bob/))
- **Dave et Tweak** : Dave (CA l'écrit « DaVE » : `DaVE.retail.x64.exe` ; le lanceur Steam dit *Database Editor: Dave*) édite les tables en XML de l'Assembly Kit (la base que lisent CAIME et BOB) ; Tweak est l'éditeur dont Terry est un mode. (Steam → Bibliothèque → Outils)
- **Un langage de script** : Python chez nous : tout ce qui se répète, déclarer des tables, produire des couches, contrôler un pack, lancer des essais.
- **WinDbg (cdb)** : Lire les vidages de plantage du jeu. `cdb.exe` est dans le sous-dossier `amd64` du paquet, hors du PATH. (`winget install Microsoft.WinDbg --scope user`)
- **Les journaux du jeu** : Savoir ce que le jeu a vraiment fait : chargement, scripts, données refusées. (Voir [« Quand le jeu plante »](https://bretonia.dev/atelier/outils/#quand-le-jeu-plante-lire-les-indices), plus bas)

## Les mots du métier

| Mot | Ce qu'il veut dire |
|---|---|
| Pack | l'archive d'un mod (`.pack`), posée dans le dossier `data` du jeu ; pour jouer, on la coche dans le lanceur |
| Table, clé | un tableau de la base du jeu ; chaque ligne a une clé unique, et un mod y ajoute des fragments (des morceaux de table) |
| `.loc` | les textes affichés : une clé pour chaque phrase |
| Startpos, ESF | la sauvegarde du tour 0 d'une campagne (`startpos.esf`), au format binaire de Total War |
| Pack de génération | un pack chargé le seul jour de la génération du startpos : il sert au jeu les tables `start_pos_*` |
| `raw_data` / `working_data` | ce que les outils de l'Assembly Kit lisent / ce qu'ils produisent |
| Zone jouable de campagne | la ligne de `campaign_map_playable_areas` qui décrit la carte d'une campagne |
| Témoin | un cas connu pour bon, rejoué à l'identique à côté du sien |
| Vidage (`.mdmp`) | la photo de la mémoire du jeu à l'instant du plantage |
| Pointeur nul | une lecture à l'adresse 0 (ou tout près) : souvent, pas toujours, le jeu a cherché une donnée et ne l'a pas trouvée |
| `%APPDATA%` | le dossier des réglages de votre compte Windows (à taper dans l'Explorateur) |

Les mots propres à la carte (hex, couche, swatch, lookup…) sont dans [le guide CAIME](https://bretonia.dev/atelier/caime/).

## Qui fait quoi, de la base au jeu

Toute la chaîne d'une carte neuve, avec l'outil de chaque étape et les fichiers qu'elle produit :

*Schéma : La marche à suivre : la base, CAIME (peindre, valider, exporter), Terry et BOB pour le terrain, RPFM qui assemble le pack, le jeu qui génère le tour 0, RPFM qui l'y remet, puis l'essai en jeu, et l'on recommence.*

Dans le schéma : 1 · la moitié logique · La base · déclarer carte, régions, campagne · `regions` · `campaigns` · CAIME · peindre les couches · `map.hex` · `tile_map.png` · CAIME · valider (11 contrôles) · enregistré · Tweak et Terry fermés · projet dans raw_data · CAIME · exporter (Process) · `map_data.esf` · `pathfinding.ppd` · `borders.pbd` · `<campagne>_lookup.bmp` · 2 · la moitié visuelle · Terry · relief, textures, arbres, eau · `<carte>.terry` · `tile_map.png ← CAIME` · BOB · un passage : le terrain · `full_height_map.dds` · `tile_list.bin` · carte neuve : BOB ne lance que 6 actions sur 15 · 3 · ensemble · RPFM · assembler le pack : exports, terrain, tables · `mon_mod.pack` · Le jeu · générer le tour 0 (deux packs) · `startpos.esf` · `hlp_data.esf` · `spd_data.esf` · RPFM · remettre le tour 0 dans le pack · `mon_mod.pack` · En jeu · tester, lire les journaux · on corrige, on recommence : on réexporte, puis un nouveau startpos

La marche à suivre. En haut, CAIME fait la moitié logique : peindre, valider, puis exporter, une fois le projet enregistré, Tweak et Terry fermés et le projet dans raw_data. En bas, en même temps, Terry et BOB font la moitié visuelle, à partir de la base et de la carte des tuiles exportée par CAIME ; pour une carte neuve, BOB ne lance que 6 actions sur 15. RPFM assemble le pack du mod ; le jeu génère le tour 0 avec ce pack et celui des tables de départ, puis RPFM y remet le tour 0. Sous chaque étape, les fichiers qu'elle produit. Chaque retouche demande de réexporter, puis un nouveau startpos.

- **La base** : les tables de l'Assembly Kit (Dave, ou les XML par script), ou celles d'un pack (RPFM).
- **La moitié logique** : CAIME, puis ses exports : [le guide CAIME](https://bretonia.dev/atelier/caime/).
- **La moitié visuelle**, en même temps : Terry, puis BOB : [Terry](https://bretonia.dev/atelier/terry/), [BOB](https://bretonia.dev/atelier/bob/).
- **Le pack** : RPFM rassemble tout : [le guide RPFM](https://bretonia.dev/atelier/rpfm/).
- **Le tour 0** : le jeu lui-même génère le startpos à partir de ce pack (plus bas) ; les fichiers qu'il produit retournent dans le pack, qu'on reconstruit.

## L'Assembly Kit en bref

L'Assembly Kit est le kit officiel de Creative Assembly (Steam → Bibliothèque → Outils). Trois dossiers : `binaries` (ses programmes), `raw_data` (ce que les outils lisent : tables en XML, terrain, cartes) et `working_data` (ce qu'ils produisent). **Sauvegardez avant d'écrire dans `raw_data\db`** : c'est la base que lisent CAIME et BOB.

- **Dave** édite les tables `raw_data\db\*.xml` ; elles s'écrivent aussi par script, sauvegarde d'abord.
- **Tweak** (`binaries\tweak.modder.x64.exe`) est l'éditeur de CA. Pendant les exports *Map Data* et *Dynamic Resources* de CAIME, Tweak **et Terry** doivent être fermés (Terry est un mode de Tweak). Ne comptez pas sur l'alerte de CAIME : elle cherche un programme nommé `Tweak.AssemblyKit`, alors que celui du kit de Warhammer III s'appelle `tweak.modder.x64.exe`.
- **Terry**, un mode de Tweak : la page de CA, écrite pour le kit de Warhammer I, le présente comme l'outil des cartes de campagne et des champs de bataille, et précise que le kit ne permet de créer que des tuiles de bataille ; nous constatons la même chose dans le kit de Warhammer III, dont le dossier `raw_data\terrain` ne contient que la bataille. Ouvert, Terry verrouille `working_data` : [le guide Terry](https://bretonia.dev/atelier/terry/).
- **BOB** transforme les sources en fichiers du jeu et en packs, selon des fichiers `rules.bob`. BOB s'ouvre par le lanceur Steam de l'Assembly Kit (*Exporter: BOB*), par son exécutable `bob.modder.x64.exe`, ou depuis Terry (*Process with BOB*, Ctrl+P), qui lui passe le travail. En ligne de commande, on ne lui connaît que l'option `-no_console`, celle que passe le lanceur : [le guide BOB](https://bretonia.dev/atelier/bob/).

*Schéma : Où vit chaque fichier.*

Dans le schéma : Où vit chaque fichier · Le jeu · `<jeu>\` · `Warhammer3.exe` · lancé directement pour le startpos · `data\` · les packs : ceux du jeu, les vôtres · `mon_mod.pack` · votre mod · `campaigns\<campagne>\startpos.esf` · en vrac · `campaign_maps\<carte>\` · hlp_data.esf , spd_data.esf , en vrac (chez nous) · le pack passe devant ces copies en vrac, startpos.esf compris : remises dans le pack, puis retirées · `script_log_JJMMAA_HHMM.txt` · le journal des scripts, s'il est activé · L'Assembly Kit · `<Assembly Kit>\` · chez Steam : <jeu>\assembly_kit\ · `binaries\` · ses programmes · `bob.modder.x64.exe` · BOB · `tweak.modder.x64.exe` · Tweak, et Terry, l'un de ses modes · `bob*.log` · les journaux de BOB · `dave\DaVE.retail.x64.exe` · Dave · `raw_data\` · ce que les outils lisent · sauvegardez avant d'écrire dans db\ · `EmpireDesignData\campaign_maps\<carte>\` · map.hex : votre projet, la seule place où Map Data travaille · `working_data\` · ce qu'ils produisent · verrouillé tant que Terry est ouvert · `campaign_maps\<carte>\` · ce que Process écrit : map_data.esf, pathfinding.ppd… · Les réglages et journaux du jeu · `%APPDATA%\The Creative Assembly\Warhammer3\` · `scripts\user.script.txt` · lu au lancement · après une génération, remettez-le comme avant · `crash_report\` · `bad_mods_report.txt` · les données refusées · `*.mdmp` · les vidages de plantage · `logs\mp_log.txt` · où en était le chargement · CAIME · ses réglages, et l'installation officielle · `%APPDATA%\CampaignMapToolkit\Caime\` · `preferences.json` · ses réglages · `%LOCALAPPDATA%\CampaignMapToolkit\` · `Projects\` · le brouillon d'un projet neuf (Ctrl+N) · Map Data : refusé ici ; enregistrez le projet sous raw_data (plus haut) · `Tools\Release\MapDataBuilder.x64.exe` · l'outil de Map Data : absent de l'installeur v1.0.0 ; selon la version, à vérifier

Quatre tiroirs : le dossier du jeu, l'Assembly Kit, les réglages et journaux du jeu, et CAIME. En or, votre mod ; en rouge, le piège de l'endroit.

> **Jamais d'options devinées** : Ne lancez jamais BOB, Terry ou Tweak avec des options devinées. Sur BOB, `-h`, `--help` ou `-help` ouvrent une boîte « Illegal option format » qui bloque le programme, et un script qui l'attend reste suspendu : constaté sur BOB ; ne l'essayez pas non plus sur Terry ni sur Tweak. Pour connaître les options d'un outil, regardez ce que son lanceur officiel lui passe.

## RPFM et les packs en bref

Un mod de Total War est un fichier `.pack` : une archive de tables, de textes (`.loc`), de scripts Lua, d'images et de modèles. RPFM ouvre ceux du jeu en lecture et fabrique les vôtres ; depuis la version 5, son serveur MCP permet à une IA de le piloter. Tout est dans [le guide RPFM](https://bretonia.dev/atelier/rpfm/), avec trois procédures complètes : ajouter une unité, une faction, un seigneur légendaire.

*Schéma : Anatomie d'un pack.*

Dans le schéma : Anatomie d'un pack · `atlas_chevaliers.pack` · votre mod : une archive, posée dans le dossier data du jeu · `db/land_units_tables/` · ne jamais le renommer ni le déplacer (RPFM) · `atlas_land_units` · le vôtre, à votre préfixe ; @ ou ! devant : seulement pour modifier une ligne du jeu · `data__` · le nom de la table du jeu : jamais dans votre pack · `text/db/` · `atlas.loc` · une clé par phrase ; vaut pour toutes les langues · `script/campaign/mod/` · `atlas_script.lua` · chargé tout seul par le jeu · `ui/units/icons/` · `<carte>.png` · la carte d'unité : 60 × 130 · `ui/flags/<faction>/` · les drapeaux · `ui/portraits/portholes/` · `portrait_settings*.bin` · les réglages des portraits, par art set · `variantmeshes/variantmeshdefinitions/` · `*.variantmeshdefinition` · un modèle neuf · `campaigns/<campagne>/` · `startpos.esf` · produit par le jeu ; un par campagne · `campaign_maps/<carte>/` · `hlp_data.esf · spd_data.esf` · produits par le jeu, pour une carte neuve · `settings.rpfm_reserved · notes.rpfm_reserved` · les réglages et notes de RPFM, ignorés par le jeu · Tables et .loc : fusionnés par clé. · Autres fichiers : même chemin, un seul gagne.

Un pack range chaque fichier à son chemin. Les fragments d'une même table (un dossier _tables), comme les .loc, se fusionnent par clé ; pour tout autre fichier, deux fichiers au même chemin ne se chargent pas tous les deux : un seul gagne. En or, ce que le jeu produit ; en gris, ce que seul RPFM lit.

- **N'écrasez pas une table du jeu** : donnez à vos fragments un nom à vous. Quand deux fragments donnent la même clé, le jeu garde celui dont le nom trie en premier ; un fragment nommé comme le fichier du jeu (`data__`) le remplace tout entier.
- **Ne redéfinissez pas un texte du jeu** : les `.loc` d'un mod valent pour toutes les langues.
- **Dans `data`, un pack passe devant les fichiers en vrac** : un fichier régénéré (un startpos) ne compte qu'une fois remis dans le pack.

## Le terrain d'une carte de campagne en bref

Ni le kit de Warhammer III ni celui de Warhammer I ne livrent de données brutes de terrain de campagne. Terry sait pourtant ouvrir un projet de type campagne : ChaosRobie l'a prouvé. Pour Immortal Empires Expanded, un mod qu'il a fait avec l'équipe de CAIME, il a reconstitué la carte des Empires Immortels en projet Terry, et il a partagé ce projet avec la communauté. Le dossier du projet, la taille de ses rasters, ses conventions et ses limites sont dans [le guide Terry](https://bretonia.dev/atelier/terry/) ; l'ordre des passages de BOB dans [le guide BOB](https://bretonia.dev/atelier/bob/).

*Schéma : Campagne : l'ordre des passages.*

Dans le schéma : Campagne : l'ordre des passages · pour une carte que la base du jeu connaît · Carte inconnue de la base du jeu (celle des packs de CA) : BOB ne lance que 6 actions sur 15, sans message. Un témoin, puis la communauté. · Le relief · les étapes suivantes le lisent dans votre pack · `full_height_map.dds` · `full_logic_map.compressed_map` · Le relief dans votre pack, le pack dans le dossier data du jeu, puis fermer et rouvrir BOB · La tile map · `tile_list.bin` · `tile_mask.dds` · `patch_mask.dds` · La tile map dans votre pack, puis fermer et rouvrir BOB · La global tile map · routes et falaises, tirées de la tile map de votre pack · `global_map/tile_list.bin` · Les objets posés · BOB lit le map.hex de CAIME, à jour avec la base ; à refaire à chaque région ajoutée ou retirée ; jusqu'à dix minutes, selon le tutoriel · `global_props.bin` · Generate Camera Height Map : cette action fait planter BOB ; camera_heightmap.png se fabrique à part (le tutoriel : une approximation tirée du relief, mise à l'échelle).

L'ordre du tutoriel de carte de campagne de tw-modding. BOB lit les packs du dossier data du jeu : après le relief, puis après la tile map, le pack y va, puis l'on ferme et rouvre BOB ; depuis Terry, chaque Process with BOB démarre un nouveau BOB.

Un passage complet sur un terrain de campagne compte 15 actions (chez nous, environ une minute une fois le relief compressé, 25 minutes la première fois). Pour une carte que la base du jeu (celle des packs de CA) ne connaît pas, BOB n'en lance que 6, sans message ; l'ajouter à la base du kit ou à un pack de mod n'y change rien. Nous ne connaissons pas de voie officielle pour lever cette limite : faites un témoin, puis demandez à la communauté. Le témoin : un projet connu pour bon, copié sous un autre nom ; s'il s'arrête aussi à 6 actions, vos fichiers ne sont pas en cause.

## La position de départ (startpos)

Le startpos (`startpos.esf`) est la sauvegarde du tour 0 : factions, régions, personnages, armées, diplomatie. Chaque campagne n'a qu'un fichier de départ, et un mod ne peut pas le compléter : il le remplace en entier (« there can be only one startpos », dit le [wiki du modding](https://tw-modding.com/wiki/Startpos)). Deux mods qui touchent au startpos d'une même campagne ne se combinent donc pas.

On écrit les tables `start_pos_*` dans l'Assembly Kit (Dave), mais le jeu ne lit pas ses XML. Pour la génération, on les lui sert dans un **pack à part**, chargé ce jour-là seulement ; elles n'entrent jamais dans le pack que l'on joue. Seuls les fichiers générés y vont.

C'est le jeu lui-même qui fabrique le startpos, dans un mode spécial piloté par le fichier `%APPDATA%\The Creative Assembly\Warhammer3\scripts\user.script.txt`. Trois voies y mènent : *Build Startpos* de RPFM, l'action *Process start pos* de BOB, ou un `user.script.txt` écrit à la main. Chez nous, seule l'écriture à la main a marché. RPFM (clic droit sur la racine du pack → *Build Startpos*) écrit lui-même le `user.script.txt` de la génération, mais n'y met qu'une ligne `mod` : celle du pack ouvert. Notre génération lit deux packs (le mod et celui des tables de départ) : nous écrivons donc le script à la main. Une ligne `add_working_directory`, que nous avions essayée, faisait sortir le jeu en neuf secondes sans rien produire.

### Le générer

1. **Les tables de départ** : Les tables `start_pos_*`, au format du jeu, dans un pack de génération ; à côté, le pack du mod, à jour. (piège : le jeu ne lit pas les XML du kit)
2. **Le script du jeu** : `user.script.txt` charge les packs et demande la génération, puis la fermeture du jeu. (piège : à remettre comme avant, ensuite)
3. **Le jeu, en mode spécial** : Il crée le monde de la campagne, l'enregistre, puis se referme. Steam doit tourner. (piège : refermé ne veut pas dire réussi : vérifiez la date du fichier)
4. **Le tour 0** : Le startpos, et, pour une carte neuve, les données de cheminement de l'IA, écrits en vrac dans `data`. (`startpos.esf`, `hlp_data.esf`, `spd_data.esf`)
5. **Dans le pack** : Les trois fichiers rejoignent le pack du mod, qu'on reconstruit. (piège : le pack passe devant les fichiers en vrac)

L'ordre compte : le pack du mod d'abord, puis la génération, puis le pack reconstruit. Pas à pas, comme nous le faisons :

1. **Le pack du mod**, construit et posé dans le dossier `data` du jeu, à jour (scripts compris) : la génération lit ses tables (`campaigns`, la carte…) et fait tourner ses scripts.
2. **Le pack de génération**, posé lui aussi dans `data` : il contient les tables `start_pos_*` (voir « Le pack de génération », plus bas).
3. **Le script** : gardez une copie de `user.script.txt` s'il existe, puis écrivez-y les lignes ci-dessous : une ligne `mod` par pack, la génération, la fermeture.
4. **La génération** : Steam ouvert et le jeu fermé, lancez directement l'exécutable du jeu (`Warhammer3.exe` ; chez nous, un fichier `steam_appid.txt` était posé à côté, comme le fait RPFM), puis attendez qu'il se referme seul, sans toucher à sa fenêtre.
5. **Les fichiers produits** : le jeu écrit `<jeu>\data\campaigns\<campagne>\startpos.esf` ; avec `process_campaign_ai_map_data`, chez nous, `hlp_data.esf` et `spd_data.esf` dans `<jeu>\data\campaign_maps\<carte>\`. Vérifiez leur date et leur heure.
6. **Le pack reconstruit** : copiez ces fichiers dans les sources du mod, reconstruisez le pack, puis retirez les copies en vrac de `data` : le pack passe devant elles.
7. **Le ménage** : remettez `user.script.txt` comme avant ; laissé tel quel, `quit_after_campaign_processing;` referme le jeu à chaque lancement.

```
mod mon_mod.pack;
mod mes_tables_de_depart.pack;
process_campaign_startpos ma_campagne;
process_campaign_ai_map_data;
quit_after_campaign_processing;
```

*Schéma : Le startpos : trois endroits, un aller-retour.*

Dans le schéma : Le startpos : trois endroits, un aller-retour · Le script · `%APPDATA%\The Creative Assembly\Warhammer3\scripts\` · `user.script.txt` · écrit à la main : une ligne mod par pack, puis les trois commandes (le code ci-dessus) · gardez-en une copie avant ; remettez-le comme avant après, sinon le jeu se referme à chaque lancement · lu au lancement · Le jeu · `<jeu>\` · `Warhammer3.exe` · lancé directement, Steam ouvert : il charge les deux packs, génère le tour 0, puis se referme seul · `data\` · `mon_mod.pack` · le mod : campaigns, la carte, les scripts ; au retour, les trois fichiers copiés dans ses sources, puis le pack reconstruit · `mes_tables_de_depart.pack` · les tables start_pos_* seules ; jamais dans le pack joué · `campaigns\<campagne>\startpos.esf` · `campaign_maps\<carte>\` · chez nous, le jeu les a écrits ici · `hlp_data.esf · spd_data.esf` · Avec process_campaign_ai_map_data (carte neuve). Durée très variable : 16 s chez nous (400 × 440 hex) ; le tutoriel de carte de campagne de tw-modding compte moins d'une minute pour spd, environ cinq minutes pour hlp sur une carte moyenne et bien plus d'une heure sur une grande ; RPFM annonce 10 à 30 minutes. · écrits en vrac : une fois remis dans le pack, retirez-les de data, le pack passe devant eux · Contrôler · date et heure des trois fichiers : celles de la génération. · bad_mods_report.txt sans reproche, dans : `%APPDATA%\The Creative Assembly\Warhammer3\crash_report\` · campagne scriptée : une partie neuve a son introduction et ses missions (compteur de sauvegarde à 1)

Trois endroits : le script dans %APPDATA%, le jeu et ses deux packs dans <jeu>\, les fichiers produits en vrac dans data. Ils retournent dans le pack du mod, qu'on reconstruit ; puis les copies en vrac s'en vont.

- `process_campaign_startpos` ne prend **qu'un argument**, la clé de la campagne.
- Avec `process_campaign_ai_map_data`, le jeu écrit aussi les données de cheminement de l'IA (`hlp_data.esf`, `spd_data.esf`), **indispensables à une carte neuve** : sans elles, le jeu plante au réglage du joueur. Durée très variable : 16 s chez nous (400 × 440 hex) ; le tutoriel de carte de campagne de tw-modding compte moins d'une minute pour `spd`, environ cinq minutes pour `hlp` sur une carte moyenne et bien plus d'une heure sur une grande ; RPFM annonce 10 à 30 minutes.
- À notre connaissance, ces commandes ne sont pas documentées publiquement : nous les avons vérifiées sur le patch 8.1 du jeu, puis avec la mise à jour 9.0 (septembre 2026). Revérifiez-les après une mise à jour.
- **Charger un mod** : pour jouer, on coche le mod dans le lanceur ; pour générer un startpos à la main, une ligne `mod <pack>;` par pack dans `user.script.txt`. Lancé directement, l'exécutable ne charge que les packs ainsi nommés.
- Les trois fichiers vont dans le pack : `campaigns/<campagne>/startpos.esf`, `campaign_maps/<carte>/hlp_data.esf` et `campaign_maps/<carte>/spd_data.esf`.
- Avec RPFM (clic droit sur la racine du pack → *Build Startpos*) : le pack doit être **dans le dossier `data`**, la campagne déclarée **dans le pack** (`campaigns_tables`), et le jeu fermé ; tout ce que lit la génération doit être dans ce seul pack. Par son serveur MCP, `build_starpos` répond « Success » en zéro seconde : cela veut dire « jeu lancé », pas « startpos construit » ; attendez que le jeu se referme, puis appelez `build_starpos_post` et `build_starpos_cleanup`. Le détail : [le guide RPFM](https://bretonia.dev/atelier/rpfm/).

### Le pack de génération

C'est un pack de mod ordinaire, créé avec RPFM, qui ne sert qu'à la génération. Il contient les tables `start_pos_*` au format du jeu : des tables de pack, pas les XML du kit. Chez nous, la ligne `campaigns` de la campagne et les autres tables que lit la génération restent dans le pack du mod, chargé en même temps ; avec *Build Startpos* de RPFM, qui ne charge qu'un pack, tout doit être dans celui-là.

- **Chez nous**, il a été construit une fois à partir des tables de départ que l'export de la base par BOB écrit, au format du jeu, pour chaque campagne (`raw_data\EmpireDesignData\campaigns\<campagne>\`), sans les XML ni `campaigns` ([le guide BOB](https://bretonia.dev/atelier/bob/) décrit cet export). Ensuite, chaque ligne ajoutée au kit y a été recopiée par script, à travers le serveur MCP de RPFM.
- **Relisez ce que BOB écrit** : il avait mis `default` comme sous-type à huit de nos personnages, valeur que le jeu refuse dans un pack de mod ; nous avons remis celles du kit.
- **Nos notes ne décrivent pas** la recopie à la main, dans la fenêtre de RPFM, des lignes du kit vers ce pack. Pour créer un pack, y ajouter une table et y coller des lignes : [le guide RPFM](https://bretonia.dev/atelier/rpfm/).
- **Contrôle avant de lancer le jeu** : chaque valeur qui renvoie à une autre table (une faction, un sous-type, un groupe d'IA) doit y exister. Sinon, le validateur du jeu nomme l'enregistrement fautif (encadré plus bas).

### Ce qu'un startpos exige : les plantages que nous avons vécus

*Schéma : Quand ça casse, qu'est-ce qui manque ?.*

Dans le schéma : Quand ça casse, qu'est-ce qui manque ? · Pendant la génération · Le script_log s'arrête juste après « Loading Mods », sans vidage. · → start_pos_regions : rebel_faction_name et · long_description vides, pas de « PLACEHOLDER ». · La génération plante. · → Un map_data.esf en variante 0xABCA (pas · 0xABCB ), comme ceux de CA. · Au chargement de la campagne · Plantage dès le début du chargement. · → Un emplacement primary par colonie · ( start_pos_region_slot_templates ). · Plantage au chargement. · → Pour chaque faction, un groupe d'IA qui contient une · personnalité. · Plantage au réglage du joueur (carte neuve). · → hlp_data.esf et spd_data.esf dans le pack. · À l'écran de sélection · Aucun seigneur à choisir. · → Les lignes de · start_pos_starting_general_options . · Au premier tour · Un personnage dans le coin de la carte, en case (1, 1). · → Son lien dans · start_pos_character_to_settlements (personnage placé en (0, 0)). · Ni introduction ni missions. · → Un startpos généré APRÈS les scripts (compteur de · sauvegarde à 1). · D'abord : bad_mods_report.txt nomme la ligne refusée, une à la fois, dans : `%APPDATA%\The Creative Assembly\Warhammer3\crash_report\`

Le moment où ça casse dit où chercher : chaque symptôme vécu sur notre chantier, et la ligne ou le fichier qui manquait.

- Chaque colonie a un emplacement **`primary`** (`start_pos_region_slot_templates`) : sans lui, le startpos se génère quand même, et le jeu plante au chargement.
- Chaque faction a un **groupe d'IA** qui contient une personnalité : sinon, plantage.
- Sans **`start_pos_starting_general_options`**, aucun seigneur n'est choisissable à l'écran de sélection.
- Dans `start_pos_regions`, `rebel_faction_name` et `long_description` restent **vides** : un texte (le « PLACEHOLDER » du kit) fait planter la création du monde, sans vidage ni rapport de plantage : le journal s'arrête juste après le chargement des mods.
- Un personnage de départ placé en (0, 0) rejoint en garnison la colonie que lui donne `start_pos_character_to_settlements` ; sans ce lien, il apparaît dans le coin de la carte, en case (1, 1).
- **Une campagne scriptée se génère APRÈS ses scripts** : c'est pendant la génération que les scripts passent le compteur de sauvegarde à 1 (`cm:is_new_game()`). Avec un startpos plus ancien que les scripts, chaque partie neuve est prise pour une sauvegarde : ni introduction, ni missions.
- L'export *Map Data* de CAIME (MapDataBuilder, qui s'appuie sur une DLL du kit) a écrit chez nous un `map_data.esf` en variante ESF `0xABCB`, alors que ceux que livre CA sont en `0xABCA` ; la génération plantait tant qu'il n'était pas converti. Demandez à l'équipe de CAIME si votre version écrit déjà la bonne variante.
- Contrôle avant le jeu : comparez la structure du nouveau startpos à celle d'un startpos qui charge (mêmes blocs, mêmes enfants).

> **Le meilleur outil de diagnostic du startpos** : Mettez les tables `start_pos_*` dans un **pack de mod** : le validateur de mods du jeu s'active et écrit `%APPDATA%\The Creative Assembly\Warhammer3\crash_report\bad_mods_report.txt`, avec la table et l'enregistrement fautifs (`first_invalid_database_record`). Il n'en nomme qu'un à la fois, mais il le nomme. Notre pack de génération étant un pack de mod, ce validateur tourne à chaque génération.

## Quand le jeu plante : lire les indices

Cinq questions, dans l'ordre ; chaque « oui » dit quel fichier ouvrir :

*Schéma : Quand le jeu plante : l'arbre du diagnostic.*

Dans le schéma : Quand le jeu plante · Le jeu se ferme-t-il en moins de 10 s ? · oui → · Steam est-il lancé ? user.script.txt est-il remis comme avant ? · non · Un bad_mods_report.txt récent ? · oui → · la table et la ligne refusées, une à la fois. · `%APPDATA%\The Creative Assembly\Warhammer3\crash_report\bad_mods_report.txt` · non · mp_log.txt s'arrête-t-il avant la campagne ? · oui → · sa dernière ligne dit l'étape atteinte : base lue, somme de contrôle, environnement de campagne. · `%APPDATA%\The Creative Assembly\Warhammer3\logs\mp_log.txt` · non · Une erreur dans le script_log, ou un arrêt ? · oui → · le script fautif et sa ligne. Génération arrêtée juste après « Loading Mods » : un texte dans vos tables de départ (PLACEHOLDER). · `<jeu>\script_log_JJMMAA_HHMM.txt` · s'il est activé : un fichier script/enable_console_logging non vide dans un pack chargé · non · Un vidage .mdmp : lecture à l'adresse 0 ou tout près ? · oui → · souvent, pas toujours, une donnée attendue manque : cherchez-la dans vos tables. Notez l'adresse avec la version du jeu. · `%APPDATA%\The Creative Assembly\Warhammer3\crash_report\*.mdmp` · non · Rien ne parle : un témoin, puis la communauté, avec vos journaux et le vidage (Discord de CAIME, tw-modding).

Cinq questions, dans l'ordre ; chaque « oui » dit ce que le fichier apprend, et où il est. Si rien ne parle : un témoin, puis la communauté.

- **`%APPDATA%\The Creative Assembly\Warhammer3\crash_report\bad_mods_report.txt`** : les données refusées. Dans le même dossier, les vidages `.mdmp` ; le `*.stack.txt` ne dit presque rien, le vidage, si.
- **`%APPDATA%\The Creative Assembly\Warhammer3\logs\mp_log.txt`** : où en était le chargement (base lue, somme de contrôle, création de l'environnement de campagne).
- **Le journal des scripts** : un fichier `script/enable_console_logging` non vide dans un pack chargé, et le jeu écrit `script_log_JJMMAA_HHMM.txt` dans son dossier (vide, le fichier est ignoré). Les clics, même simulés, y sont notés avec le chemin du composant.
- **Le vidage au débogueur** : installez WinDbg (`winget install Microsoft.WinDbg --scope user`). `cdb.exe` n'est pas dans le PATH : PowerShell donne le dossier du paquet par `(Get-AppxPackage Microsoft.WinDbg*).InstallLocation`, et `cdb.exe` est dans son sous-dossier `amd64`. Puis, dans PowerShell, `$cdb = "<dossier>\amd64\cdb.exe"` (`<dossier>` : ce dossier du paquet), et `& $cdb -z <vidage.mdmp> -c ".ecxr; k 40; q"`. Sans `.ecxr`, vous regardez le fil du rapporteur de plantage, pas le fil fautif.
- **Lire le verdict** : le code `0xC0000005` avec une lecture à une adresse nulle ou presque nulle, c'est un pointeur nul : **souvent, pas toujours, une donnée attendue manque**. Cherchez d'abord dans vos tables ce que le jeu n'a pas trouvé.
- **Rangez les plantages par cas testé et par adresse** : l'adresse dépend de la campagne et de la version du jeu ; notez la version du jeu à côté de chaque adresse. Après une mise à jour, les anciennes adresses ne se comparent plus.
- **Steam doit être lancé** : sinon le jeu se referme en quelques secondes, et l'on croit à un plantage.

*Schéma : Lire un vidage en quatre étapes.*

Dans le schéma : Lire un vidage · Le vidage : un fichier .mdmp · le jeu l'écrit ici quand il plante : `%APPDATA%\The Creative Assembly\Warhammer3\crash_report\*.mdmp` · le *.stack.txt voisin ne dit presque rien ; le vidage, si. · Le lecteur : cdb.exe, de WinDbg · `winget install Microsoft.WinDbg --scope user` · cdb.exe , hors du PATH, est dans le sous-dossier amd64 du dossier que donne PowerShell : `Get-AppxPackage Microsoft.WinDbg*` · InstallLocation : le <dossier> du paquet · La commande, dans PowerShell · `$cdb = "<dossier>\amd64\cdb.exe"` · `& $cdb -z <vidage.mdmp> -c ".ecxr; k 40; q"` · .ecxr : le fil fautif · k 40 : la pile · q : quitter · Sans .ecxr , mauvais fil : vous lisez celui du rapporteur de plantage. · La sortie, schématique · `(…): Access violation - code c0000005` · `0:000> .ecxr` · `rax=… rcx=0000000000000000` · `…` · `Warhammer3!…+0x…:` · `mov rax,qword ptr [rcx]` · `0:000> k 40` · `00 Warhammer3!…+0x…` · `01 Warhammer3!…+0x…` · c0000005 : une violation d'accès, en lecture ou en écriture. · rcx vaut 0 et l'instruction lit [rcx] : une lecture à une adresse nulle ou presque nulle : un pointeur nul. · l'adresse du plantage, à noter avec la version du jeu. · Pointeur nul : souvent, pas toujours, une donnée attendue manque. Cherchez-la d'abord dans vos tables.

Quatre choses à savoir : où est le vidage, où est cdb, la commande, et ce que dit la sortie. Celle-ci est schématique : les adresses dépendent du plantage et de la version du jeu.

## Tester sans jouer : les parties automatiques

Pour savoir si une campagne tient trente tours, inutile de les jouer. Notre méthode :

- Un **pack d'essai séparé** (créé pour l'essai, retiré après) contient un script Lua qui clique dans l'interface comme un joueur : menu, campagne, seigneur, début de partie, fin de tour. Les composants se désignent par leur chemin dans l'interface.
- `all_players_ai;` dans `user.script.txt` fait passer aussi les tours du joueur par l'IA ; chez nous, elle ne recrute ni ne construit pour lui : ce mode éprouve la stabilité, pas la faction du joueur. À notre connaissance, cette commande n'est pas documentée publiquement : vérifiée sur le patch 8.1 et la mise à jour 9.0.

*Schéma : Lancer une partie automatique, clic par clic.*

Dans le schéma : Lancer une partie automatique · Pendant l'essai, personne ne touche au PC : un clic humain le fausse. · Un pack d'essai, à part · créé pour l'essai, retiré après ; deux scripts : `script\frontend\mod\` · le menu · `script\campaign\mod\` · la partie · Un nom neuf : un fichier déjà chargé est sauté sans message. · chargé comme pour le startpos, une ligne mod par pack : %APPDATA%\The Creative Assembly\ · Warhammer3\scripts\user.script.txt : `mod mon_mod.pack;` · `mod mon_essai.pack;` · `all_players_ai;` · all_players_ai , facultatif : l'IA joue aussi pour le joueur, mais ne recrute ni ne construit pour lui, et aucune mission n'est émise. Vérifié sur le patch 8.1 et la mise à jour 9.0. · Steam ouvert, Warhammer3.exe lancé directement ; user.script.txt gardé avant, remis après. · Le menu, clic par clic · `main > button_campaign` · `main > button_start_campaign_new` · `campaign_select_new` · `> CcoCampaignMapPlayableAreaRecord…` · `> button_campaign_entry` · si la liste des campagnes s'affiche ; « … » : le numéro de l'entrée de votre campagne · `lord_select_list > list_box > *` · `> lord_button` · propriété lord_key = l'identifiant du personnage dans start_pos_characters ; liste remplie en 20 à 45 s · `campaign_select_new > button_start_parent` · `> button_start_campaign` · propriété campaign_key · Pas frontend.start_campaign (la fonction Lua de lancement du menu) : chez nous, il refermait la campagne au bout de deux ou trois secondes.

Un pack d'essai à part, chargé par user.script.txt comme pour le startpos, puis le menu, clic par clic : chaque composant se désigne par son chemin dans l'interface.

- À la fin : bilan des tours, relecture du `script_log`, des vidages s'il y en a. Puis `user.script.txt` remis comme avant et le pack d'essai retiré, même après un arrêt forcé.
- **Les limites** : en mode « l'IA joue tout », aucune mission n'est émise pour une IA. Ce mode teste la stabilité (IA, invasions, dilemmes) ; l'histoire et les mécaniques d'un seigneur se testent en mode joueur.
- **Un évènement qui n'arrive jamais** : sur notre carte, `FactionTurnStart` n'arrivait à aucun script, sous `all_players_ai` comme en mode joueur, alors que `FactionBeginTurnPhaseNormal` arrivait à chaque tour. La cause : dans le jeu publié, les conditions de tous les écouteurs d'un évènement sont évaluées dans une seule boucle, sans protection ; une condition qui plante annule l'évènement pour tous les scripts, ceux de CA comme les vôtres, sans rien écrire au journal.
- **Les fautifs, chez nous** : une fois les erreurs des écouteurs attrapées et nommées au journal, trois écouteurs de CA sont apparus (`wh3_campaign_bonus_values.lua`), deux de Mère Ostankya et un de Yuan Bo, dont la condition plantait à chaque début de tour : ils attendent des systèmes de Kislev et de Cathay que notre campagne ne charge pas. Leurs erreurs attrapées, l'évènement est revenu (essai de trois tours, l'IA jouant tout). Le remède retenu, retirer ces écouteurs par leur nom au démarrage de la campagne (`core:remove_listener`) plutôt que créer des variables factices, n'a pas encore été vérifié en partie. Et un essai ne prouve un écouteur que par une ligne de journal écrite par cet écouteur.
- Chez nous, `frontend.start_campaign` (la fonction Lua de lancement du menu) refermait la campagne au bout de deux ou trois secondes : on lance par l'interface, comme un joueur.
- Au tour 1, la fin de tour ne passe qu'après avoir fermé une à une les notifications.
- **La caméra à hauteur de jeu**, posée sur le chef dès le premier tour : un essai doit reproduire ce que vit un joueur. Chez nous, les plantages de rendu dont la caméra était relevée sont tous survenus caméra très haute, et aucun n'a été vu en jeu normal.
- Un script d'essai qui doit se charger à coup sûr va dans `script\campaign\mod\`, sous un nom qu'aucun autre fichier ne charge déjà : un fichier déjà chargé est sauté sans message.
- **Personne ne touche au PC pendant l'essai** : un clic humain le fausse.
- Toujours un **témoin** : un cas connu pour bon, rejoué à l'identique (même commande, options comprises), à côté du vôtre.
- **Un plantage qui va et vient** : au moins dix essais par variante avant de conclure ; d'ici là, dites « piste », pas « cause ».

*Schéma : Pendant la partie automatique : le chargement, la boucle du tour, le bilan.*

Dans le schéma : Pendant la partie · La campagne s'ouvre · `custom_loading_screen > bottom_parent` · `> button_continue` · Caméra posée sur le chef, à hauteur de jeu : l'essai doit reproduire ce que vit un joueur. · La boucle du tour · au tour 1, fermer d'abord les notifications, une à une : `end_turn_docker > notification_frame` · `> button_skip` · × chaque notification · `hud_campaign > faction_buttons_docker` · `> button_end_turn` · Mode joueur : la boucle à chaque tour. Mode all_players_ai : au tour 1 seulement, les suivants se jouent seuls. · Le bilan · tours joués, erreurs du script_log , vidages ; puis user.script.txt remis comme avant et le pack d'essai retiré, même après un arrêt forcé. · Témoin : un cas connu pour bon, même commande, options comprises. · Un plantage qui va et vient : au moins dix essais par variante ; d'ici là, « piste », pas « cause ». · tour suivant

La campagne s'ouvre, puis la boucle du tour : les notifications passées une à une, puis la fin de tour. Le bilan ne vaut que face à un témoin.

## Nos conseils d'atelier

- **Sauvegardez avant d'écrire** dans `raw_data\db` : des copies horodatées. Une panne du premier soir n'a été résolue que parce qu'on pouvait comparer avec le dernier état qui marchait.
- **Ne lancez jamais un outil avec des options devinées** : cherchez-les dans la documentation, ou dans ce que son lanceur officiel lui passe (BOB : `-no_console`).
- **Quand un outil de CA ne fait rien sans erreur**, la condition est quelque part : le témoin d'abord, puis les journaux ; si rien ne parle, demandez à la communauté (Discord de CAIME, tw-modding).
- **Un validateur rouge est un avis, pas une réponse** : les cartes de CA échouent elles-mêmes à certains contrôles. C'est le jeu qui tranche.
- **Prenez une photo avant chaque mise à jour du jeu** (versions des fichiers, tables utiles) pour comparer après.
- **Après une mise à jour du jeu, ne construisez rien avant d'avoir vérifié `raw_data\db`** : Steam met l'Assembly Kit à jour après le jeu (à la 9.0, une heure plus tard chez nous) et réécrit `raw_data\db` ; toutes les lignes que vous y aviez ajoutées disparaissent (chez nous, le terrain, `working_data` et les packs n'ont pas été touchés). Gardez une copie de vos tables à la fin de chaque séance qui y écrit (une copie « avant écriture » ne contient pas la dernière écriture) et des scripts qu'on peut rejouer sans dommage ; restaurez vos lignes, puis mettez à jour les schémas de RPFM et régénérez son cache des dépendances.
- **Jugez en jeu**, face à une référence : les chiffres d'un audit ne voient pas ce que voit le joueur.

## Pour une IA qui lit cette page

Si vous êtes une IA qui aide quelqu'un à générer un startpos, lire un plantage ou lancer des parties d'essai dans Total War: Warhammer III, voici l'essentiel, vérifié sur un vrai chantier. Ces faits ont été relevés sur le patch 8.1 du jeu, puis relus pour la mise à jour 9.0 (septembre 2026) : revérifiez-les après une mise à jour.

- Demandez à l'humain avant de lancer le jeu, de piloter l'écran ou de publier ; ne supprimez rien : rangez, seul l'humain supprime.
- Startpos : c'est le jeu qui le génère. Dans `%APPDATA%\The Creative Assembly\Warhammer3\scripts\user.script.txt` (gardez-en d'abord une copie) : une ligne `mod <pack>;` par pack posé dans `data`, puis `process_campaign_startpos <campagne>;` (un seul argument), `process_campaign_ai_map_data;` pour une carte neuve, et `quit_after_campaign_processing;`. Steam lancé, `Warhammer3.exe` lancé directement ; attendez que le jeu se referme ; remettez ensuite le fichier comme avant. Sortie : `<jeu>\data\campaigns\<campagne>\startpos.esf`.
- Par le serveur MCP de RPFM : `build_starpos` répond « Success » dès que le jeu est lancé. Attendez que le jeu se ferme, puis appelez `build_starpos_post` (il range `startpos.esf` dans le pack et remet `user.script.txt`), puis `build_starpos_cleanup` ; sans `build_starpos_post`, `quit_after_campaign_processing;` reste et referme le jeu à chaque lancement. RPFM n'écrit qu'une ligne `mod`, celle du pack ouvert : tout ce que lit la génération doit y être.
- Les tables `start_pos_*` s'écrivent dans le kit, mais le jeu ne lit pas ses XML : servez-les dans un pack de génération, jamais dans le pack joué. `%APPDATA%\The Creative Assembly\Warhammer3\crash_report\bad_mods_report.txt` nomme l'enregistrement refusé, un à la fois.
- Trois fichiers vont dans le pack : `campaigns/<campagne>/startpos.esf`, `campaign_maps/<carte>/hlp_data.esf` et `campaign_maps/<carte>/spd_data.esf`. Un pack passe devant les fichiers en vrac : reconstruisez-le, puis retirez les copies en vrac de `data`.
- Campagne scriptée : générez le startpos après les scripts (compteur de sauvegarde à 1), sinon ni introduction ni missions.
- Exigences : un emplacement `primary` par colonie ; un groupe d'IA avec une personnalité par faction ; `start_pos_starting_general_options` pour l'écran de sélection ; `rebel_faction_name` et `long_description` vides dans `start_pos_regions`.
- Plantage : suivez l'arbre du diagnostic ; `0xC0000005` avec une lecture à l'adresse 0 veut souvent dire, pas toujours, qu'une donnée attendue manque ; l'adresse dépend de la campagne et de la version du jeu.
- Parties d'essai : un pack d'essai séparé, retiré après (et, après tout arrêt forcé, `user.script.txt` nettoyé) ; lancement par l'interface ; notifications du tour 1 passées une à une ; caméra à hauteur de jeu ; personne ne touche au PC ; un témoin ; au moins dix essais par variante pour un plantage aléatoire.
- Évènement de script jamais reçu : une condition d'écouteur qui plante l'annule pour tous les scripts, sans journal. Chez nous, `FactionTurnStart` manquait en mode joueur comme sous `all_players_ai`, à cause de trois écouteurs de CA (Mère Ostankya, Yuan Bo) chargés sans leurs systèmes. Attrapez et nommez les erreurs des écouteurs ; un écouteur ne se prouve que par sa propre ligne de journal.
- Après une mise à jour du jeu : Steam met l'Assembly Kit à jour plus tard et réécrit `raw_data\db`, lignes ajoutées perdues ; vérifiez-le avant toute construction, restaurez les lignes, puis schémas de RPFM et cache des dépendances.
- Jamais d'options devinées (BOB, Terry, Tweak) ; une sauvegarde avant d'écrire dans `raw_data\db` ; un validateur rouge est un avis, c'est le jeu qui tranche.
- Ni rétro-ingénierie ni contournement d'un outil de CA : quand un outil bute, un témoin, puis la communauté (Discord de CAIME, tw-modding).

## Sources et liens

- [Manuel de RPFM](https://frodo45127.github.io/rpfm/manual/) et [RPFM For Dummies](https://tw-modding.com/wiki/Tutorial:RPFM_For_Dummies) (wiki tw-modding).
- [Campaign Map Making for Warhammer III](https://tw-modding.com/wiki/Tutorial:Campaign_Map_Making_for_Warhammer_III) et [Startpos](https://tw-modding.com/wiki/Startpos) (wiki tw-modding).
- [Documentation des scripts](https://chadvandy.github.io/tw_modding_resources/), tenue par Vandy.
- [Terry, introduction](https://wiki.totalwar.com/w/TWW_Assembly_Kit_Terry_Intro) (écrite pour le kit de Warhammer I) et [Rules.bob](https://wiki.totalwar.com/w/Rules.bob_Documentation.html) (wiki de Creative Assembly).
- [Documentation de CAIME](https://tw-campaign-map-modding-team.github.io/CampaignMapToolkit/).
- Nos guides : [CAIME](https://bretonia.dev/atelier/caime/), [RPFM](https://bretonia.dev/atelier/rpfm/), [Terry](https://bretonia.dev/atelier/terry/), [BOB](https://bretonia.dev/atelier/bob/), [modder avec une IA](https://bretonia.dev/atelier/ia/).

## Questions fréquentes

### Faut-il l'Assembly Kit pour modder Warhammer III ?

Pour des tables et des scripts, RPFM suffit. Pour une carte de campagne, oui : CAIME lit sa base, Terry et BOB fabriquent le terrain, et les tables du startpos s'y écrivent.

### Par quel guide commencer ?

Pour une carte : le guide CAIME. Pour des unités, des factions ou des seigneurs : le guide RPFM. Pour le terrain en 3D : Terry, puis BOB. Pour travailler avec une IA : le guide IA.

### Où le jeu écrit-il le startpos qu'il vient de générer ?

Dans `<jeu>\data\campaigns\<campagne>\startpos.esf` ; chez nous, `hlp_data.esf` et `spd_data.esf` dans `<jeu>\data\campaign_maps\<carte>\`. Copiez-les dans le mod, reconstruisez le pack, puis retirez ces copies en vrac du dossier `data`.

### Pourquoi mon nouveau startpos ne change-t-il rien en jeu ?

Parce que le pack passe devant les fichiers en vrac : remettez le startpos dans le pack, reconstruisez celui-ci et retirez la copie en vrac du dossier `data`.

### La campagne démarre sans introduction ni missions : pourquoi ?

Souvent, le startpos est plus ancien que les scripts : régénérez-le avec le pack à jour (le compteur de sauvegarde doit valoir 1). En mode `all_players_ai`, aucune mission n'est émise : c'est normal.

### Mon écouteur de FactionTurnStart ne se déclenche jamais : pourquoi ?

Peut-être pas à cause de lui : une condition d'écouteur qui plante, même dans un script de CA, annule l'évènement pour tous, sans rien écrire au journal. Chez nous, trois écouteurs de Mère Ostankya et de Yuan Bo, privés de leurs systèmes sur notre carte, le coupaient en mode joueur comme sous `all_players_ai`. Attrapez et nommez les erreurs des écouteurs pour trouver le fautif. `FactionBeginTurnPhaseNormal`, lui, arrivait à chaque tour : nos écouteurs de début de tour y sont passés.

### Mes lignes de l'Assembly Kit ont disparu après une mise à jour : pourquoi ?

Steam met l'Assembly Kit à jour après le jeu (chez nous, une heure plus tard, à la 9.0) et réécrit `raw_data\db` : les lignes ajoutées disparaissent ; le terrain, `working_data` et les packs n'ont pas été touchés. Restaurez vos lignes depuis vos copies, ou rejouez les scripts qui les écrivent, avant de construire quoi que ce soit ; puis mettez à jour les schémas de RPFM et régénérez son cache des dépendances.

### Aucun seigneur n'apparaît à l'écran de sélection : pourquoi ?

Il manque les lignes de `start_pos_starting_general_options`, qui relient un personnage du startpos à une fiche de seigneur (`frontend_faction_leaders`). Ajoutez-les, puis régénérez le startpos.

### Mon startpos se génère, mais la campagne plante au chargement : que vérifier ?

Un emplacement `primary` par colonie, un groupe d'IA avec une personnalité par faction, `hlp_data.esf` et `spd_data.esf` dans le pack pour une carte neuve, et le fichier `%APPDATA%\The Creative Assembly\Warhammer3\crash_report\bad_mods_report.txt`.

### Le jeu se referme tout seul au lancement : pourquoi ?

Souvent un `user.script.txt` laissé par une génération de startpos (`quit_after_campaign_processing;`), ou Steam fermé.

### Pourquoi mes textes remplacent-ils ceux du jeu dans toutes les langues ?

Le jeu charge les `.loc` d'un mod quelle que soit la langue. N'ajoutez que des clés neuves, et faites un pack par langue.

### Où sont les journaux ?

`%APPDATA%\The Creative Assembly\Warhammer3\crash_report\bad_mods_report.txt` (et les vidages `.mdmp` à côté), `%APPDATA%\The Creative Assembly\Warhammer3\logs\mp_log.txt`, le journal des scripts (`script_log_*.txt`) dans le dossier du jeu, et les journaux de BOB dans le dossier `binaries` du kit.

### Comment activer le journal des scripts de Warhammer III ?

Mettez un fichier `script/enable_console_logging` non vide dans un pack chargé : le jeu écrit alors des `script_log_*.txt` dans son dossier.
