Workshop journal · · 10 min read
Tutorial: porting a Warhammer I campaign map to Warhammer III
Moving a campaign map from one Total War to another is not copy and paste: two engines, two formats, two coordinate systems. Here is the order I followed with Claude for The Season of Revelation, why each step matters, and the traps that cost us hours.

Before you start
This tutorial describes a method, not a magic button, and all of it was checked on our port, from 20 to 23 September 2026. You need to be comfortable with the game's files, and patient.
- Warhammer III and its Assembly Kit, CA's official tools (in Steam's Tools section), plus the DLCs for your map's factions: without them, those factions exist in the database but not in game.
- Warhammer I and its Assembly Kit.
- CAIME (Campaign AI Map Editor), the Campaign Map Toolkit's editor, for the logical map, and RPFM for packs and tables.
- A debugger, cdb (it comes with WinDbg): it's what makes crashes talk.
Vocabulary in one minute
- Hex: one cell of the campaign map grid. Our map is 400 × 440 of them.
- map.hex: the CAIME project, i.e. the logical map, layer by layer (regions, ground types, climates, rivers, roads, settlements).
- ESF: CA's binary format, used for the logical map and for the startpos.
- Startpos: the file that freezes a campaign's starting state (factions, characters, settlements, diplomacy).
- Database table: one of the game's data tables (regions, campaigns, factions…).
- Pack: the mod archive, dropped into the game's data folder.
- Terry: the Assembly Kit's terrain editor. BOB: the builder that turns raw data into game files.
Step 0: take inventory
Before touching anything, measure. Warhammer I's kit ships the mini-campaign's logical map (its map.hex) and its database, but not its campaign terrain. So the whole visual side has to be rebuilt as a Terry project.
The inventory also tells you what got renamed. Faction keys change prefix from one game to the next: match them on culture and on the end of the key, never on the prefix. In our case almost everything had a counterpart; only one orc tribe was missing.
Then write a phased plan, with an exit criterion for each phase. Ours aimed first at an in-game test, with the bare minimum of content.
Step 1: the logical map in CAIME
The logical map tells the game where the regions, settlements, rivers, roads and impassable areas are. First declare the map in the database (campaign, playable area, regions, provinces), then bring the layers of Warhammer I's map.hex into CAIME. Use CAIME 1.0.1 (23 September) or later: it includes our two fixes, reading Warhammer I's mini-campaign maps, which 1.0.0 (19 September) couldn't open, and loading the database on any Windows whose decimal separator is the comma (French, for instance), where 1.0.0 opened everything read-only.
Layer indices don't survive the jump between games: Warhammer I has 13 land ground types and 24 climates, Warhammer III has 15 and 40. So remap by name, never by number. Settlement slots grow too: 7 hexes in Warhammer I, 19 in Warhammer III, with 16 on land and 3 on the sea side for a port.
Validate, then export. CAIME's command line does both, and changing a single hex means re-exporting everything:
CAIME.exe validate --map map.hex --all
CAIME.exe process --map map.hex --allYou get the map's game files: map_data.esf, pathfinding.ppd, borders.pbd, trade_routes.ptd and the lookup images. A few traps worth knowing:
- Row 0 of the grid is at the bottom of the map: flip your images before encoding them.
- In the Impassable layer, 1 means passable. Never infer what a flag means from its name.
- If your map's playable area is the last row of its table, the logical map export crashes. One row after yours is enough.
- The settlement sprawl validator is stricter than CA: CA's own Immortal Empires map fails it on five settlements. It isn't a blocker.
Step 2: the startpos
The startpos is generated from the Assembly Kit's start tables: factions, regions, characters, buildings. The game builds it itself, then you ship it in the pack. The start tables themselves never go into the mod.
Our first wall came from here: a logical map file in a variant of the ESF format that the game doesn't read, which had to be converted (see The 9 walls). The rules to follow:
- Every settlement has a primary slot. Without it, the startpos still generates, and the game crashes on loading.
- Every faction has an AI group that actually contains a personality: the one CA gives it in Immortal Empires, otherwise its culture's.
- A character placed at (0, 0) must be linked to its settlement; otherwise the game drops it in the corner of the map.
- Generate with the AI map data (
hlp_data.esfandspd_data.esf): without them, the game crashes while setting up the player. - After each generation: copy it into the project, rebuild the pack, then test. The startpos inside the pack wins over a loose copy next to it.
- Generation makes the game quit on its own: put your original
user.script.txtback afterwards, or the game will close at every launch.
Step 3: terrain with Terry and BOB
Warhammer III's Assembly Kit doesn't ship the raw terrain of its campaigns. ChaosRobie rebuilt it for Immortal Empires Expanded and shared his project: that's the model to follow. A campaign Terry project lives in raw_data/, in a folder named after the map, with a .terry file, rasters at 8 pixels per hex (plus 4 rows) and one layer per region.
In that project, the sea is declared by the tile map (tile_map.png), not by height. BOB compiles it all in about a minute, so you can iterate without launching the game.
- For a map the game's database (the one in CA's packs) does not know, BOB runs only 6 of its 15 actions, without a message; adding the map to the kit's database or to a mod pack changes nothing. It is a limit of the tool: run a control case, then ask the community (the CAIME Discord, tw-modding), without taking CA's tool apart or working around it.
- Its camera height step crashes: make
camera_heightmap.pngyourself. - Warhammer I's normal map can be reused as is (ChaosRobie's advice), as long as you flip its green channel.
- Each compiled file has its own row order, south to north or the reverse: check them one by one.
- A campaign has two terrains: the map's own, and a battle terrain read from the first battle. Without it, the game crashes at end of turn.
- Close Terry before running BOB or building the pack: it locks the files.
Step 4: objects, trees and mountains
This is where the map gets its personality. Warhammer I's ground is made of its meshes, not just its heightmap, and its objects sit on those meshes. Warhammer III still reads Warhammer I's models, but not always their materials.
- Base every conversion on the Warhammer I objects CA converted itself.
- Never overwrite a Warhammer III file: the pack would replace it in every campaign. Keep the Warhammer I versions in their own place.
- Only natural set dressing is visible to everyone; Chaos or vampire dressing shows by culture, the way CA does it.
- Objects live in hex space, terrain in a grid of square pixels: a point (x, z) reads the terrain at row z × √3/2. That was our flying-objects wall.
- Immortal Empires places its mountains as objects: we did the same with Warhammer I's 514 mountains.
- Judge a “floating” object by the real bottom of its bounding box and the surface under it, never by its origin point.
Step 5: rivers, coast and water
Water has two maps: height holds the water surface, sea_height the seabed. If they match, the game draws no sea, no rivers and no lakes, even though Terry shows them. So water gets judged in game.
Warhammer III's rivers are meshes using the sea's water material. We rebuilt Warhammer I's as continuous surfaces, with the water one centimetre below the lowest bank and a current computed along the network down to the river mouth.
On the coast, Warhammer III's shoreline tiles only accept a regular strip: a one-hex spit of land leaves a hole. In the end we took Warhammer I's coastline pixel for pixel, the way that game builds it.
Step 6: scripts and text
Our rule: Warhammer III gameplay, Warhammer I story. The campaign scripts are rewritten in Lua on top of CA's libraries. Nice surprise: the voiced lines of Warhammer I's story are still in Warhammer III's files, in English and in French.
- A mod only sets text keys the game doesn't know. Otherwise it overrides CA's up-to-date text, in every language.
- Two languages, two packs: the second holds only its text and takes priority over the first.
- Check every name against the game's own localisation: in French it's Gasconnie, Aquitanie and Bastogne, not Carcassonne, Aquitaine and Bastonne.
- Use your own keys and never replace a CA table: other campaigns must stay intact with the mod enabled.
- Regenerate the startpos after any script change, or every new game will think it's a save.
Step 7: testing
Any pack that adds or changes a database table gets a startup test before it's announced: the game has to hold for 45 seconds. For us, one table too many was enough to close the game in eight seconds, with no message. After that, read the crash reports every time you pick the work back up.
For long games, Claude set up automated runs. They launch through the interface, like a player, and clear the notifications before each end of turn. The mode where the AI plays everything tests stability, not story: scripts waiting for a faction's turn start never hear about it there.
One last tip: if someone is at the computer, warn them before launching the game. I clicked in test games myself, and we took it for crashes.
The recap
- Inventory and a phased plan.
- Logical map: database declared, CAIME, indices remapped by name, validation, export.
- Startpos: complete start tables, AI data, pack rebuilt, test.
- Terrain: Terry project, BOB, battle terrain.
- Objects and mountains: original files converted the CA way, coordinate frame checked.
- Water: separate surface and seabed, continuous rivers, judged in game.
- Scripts and text: your own keys, names checked, startpos regenerated.
- Testing: startup test, crash reports, automated games.
The story of those four days is in this article, and the lessons on method in this one. What comes next is being drawn on the map of all Bretonnia.