Modders' workshop · guide · 64 min read
CAIME, the guide: creating and editing a Total War: Warhammer III campaign map
CAIME (Campaign AI Map Editor), the Campaign Map Toolkit's editor, builds the logical half of a Total War campaign map: regions, ground types, climates, roads, rivers, settlement slots. This guide starts from scratch: what the tool does, its window, every layer and every rule, the exports, the command line, and the pitfalls that cost us hours while porting The Season of Revelation's map from Warhammer I to Warhammer III.
Reviewed on 25 September 2026, update 9.0. Checked against CAIME 1.0.1's code and documentation (validators unchanged in 1.1.0), the Assembly Kit on patch 8.1. The 9.0 changes that affect our project are included; the rest has not been rechecked. Corrected on 5 October 2026: facts proven since on the game's 9.0.2, and versions released since (CAIME 1.1.0, RPFM 5.1.1). Community corrections from 26 September 2026. When in doubt, check, and tell us.
What CAIME does§
A Total War campaign map has two halves describing the same land. The logical half lives on a grid of hexagons (“hexes”): ground type, region, climate, rivers, roads, beaches, bridges, settlement slots, impassable areas. It is what the game computes: who owns what, who can go where, and at what cost. The visual half is relief, textures, vegetation, water and lighting: what the player sees.
The logical half
CAIME: ground types, regions (borders in red), road, river, settlement slots (schematic: a Warhammer III town covers 19 hexes). This is what the game computes.
The visual half
Terry and BOB: relief, coast, forests, water, set dressing. This is what the player sees. Both must describe the same land.
CAIME handles the logical half. Think of it as a “Photoshop for data”: pick a layer, a value (a swatch), a tool, and paint hexes. Then the Process menu “develops” the layers into files the game reads: map_data.esf, the movement data (pathfinding), the borders (borders.pbd), dynamic_resources.esf, the lookup images and the minimap (Lookup and Minimap images menu; for Warhammer III, a single image, <campaign>_lookup.bmp). As far as we know, no other public tool produces map_data.esf, the pathfinding, borders.pbd or dynamic_resources.esf; the images, however, can be made otherwise (we remade our minimap by script).
Games supported, according to its documentation: Rome II, Attila, Thrones of Britannia, Warhammer I to III, Three Kingdoms, Troy, Pharaoh and Pharaoh Dynasties. The v1.0.0 notes, however, call Pharaoh (2023) “currently unsupported”, and the repository README does not list it. Not Shogun 2.
The words of the trade§
The whole guide uses these words; they are explained once and for all.
| Word | What it means |
|---|---|
| Assembly Kit | Creative Assembly's free tooling, one per game (Steam → Library → Tools). binaries = its programs; raw_data = the sources (XML tables, CA's maps); working_data = what its tools produce |
| Dave, Tweak, Terry, BOB | the Assembly Kit's tools: Dave edits tables, Tweak is the editor of which Terry (3D terrain) is a mode, BOB builds and packs. See the Terry guide and the BOB guide |
| RPFM | Rusted PackFile Manager, the community tool that opens and builds packs: the RPFM guide |
| Pack | a .pack archive the game reads; a mod is a pack |
| Table, key | a table of the game's database; each row has a unique key (regions, campaigns…) |
| ESF | a Creative Assembly binary format (map_data.esf, startpos.esf); the acronym is undocumented |
| Hex | one cell of the grid, flat-topped; odd columns shifted up; row 0 at the bottom |
| Layer | one kind of data, one value per hex (regions, ground, roads…) |
| Swatch | a value you paint: a ground type, a region, a climate… |
map.hex | a map's CAIME project: all its layers |
.hex_layer | a single layer, exported or to import |
| Process, export | turning the layers into game files (Process menu) |
| Pathfinding | the movement computation: who can go where, at what cost |
| Lookup | an image where each region has its RGB colour; the game reads which region lies under a point |
| Logger | CAIME's message window (Ctrl+L) |
| Slot, sprawl | a town's place on the grid; the town's footprint around it |
| Campaign playable area | the map's row in campaign_map_playable_areas: camera limits, minimap files |
is_sea | the regions column that says whether a region is a sea |
| bridge-cliff | the land hex touching a bridge; CAIME works it out itself: neither a layer nor a ground type, nothing to paint |
| Cliff | for CAIME, any land hex touching the sea that is not a beach; it works it out itself |
| Hazard | impassable, rivers and the whole coast (beach or “cliff”): what a town's sprawl must either touch or keep at least 3 hexes away |
| Province, attrition | a group of regions; armies' wear on a terrain |
| Edge mask | six bits per hex telling which neighbours a road, river or border leads to |
| Startpos | startpos.esf, a campaign's starting state, generated by the game; outside CAIME: the tools |
- 1Hexa flat-topped cell; odd columns are shifted up; cell (0, 0) is at the bottom left.
- 2Sea regionthe sea is a region like any other, with is_sea = 1 in the regions table.
- 3Region and borderevery hex has its region; the Region Borders layer draws the border (Auto-generate).
- 4Cliffa land hex touching the sea that is not a beach; CAIME works it out. The coast counts, with rivers and impassable, as a hazard.
- 5Beachpainted (Beaches), on coastal land only: the landings.
- 6Bridgepainted (Bridges) on a sea hex, from one shore to the other; the road stops at both shores.
- 7bridge-cliffevery land hex touching the bridge (hatched); CAIME works it out: nothing to paint.
- 8Slotthe town: a 19-hex disk; for a port, 16 main hexes (brown line) and 3 Port hexes (blue line), two of them at sea and one on the beach, as CA does.
- 9Sprawlthe town's footprint, in ochre: the 19 hexes.
- 10Edge masksix bits per road, river or border hex: the sides towards its neighbours; the gold-ringed hex, magnified on the right, has bits 0 (north) and 3 (south).
From database to game: the full chain§
CAIME is only one link. Here is the whole path of a new map, at a glance. Two tracks move forward at the same time: CAIME for the logical half, Terry and BOB for the visual half. They meet in the mod's pack; the game then generates turn 0 (the startpos) with that pack loaded (for us, with a second pack, the start-table one: the tools guide), and the pack is rebuilt with the startpos.
And each step in detail, under the road map's numbers, with what it produces:
- I · The database
In the Assembly Kit (Dave, or the XML files by script): the map, its regions, its provinces, the campaign that uses it.
regions,campaigns,campaign_map_playable_areas… - II–III · CAIME, the layers
Layers painted or imported, then validated.
map.hex - IV · CAIME, the exports
Process: what the game reads to move, draw borders and colour the map. And, through Tools → Export → Baseline Tilemap image, the tile map for Terry.
map_data.esf,pathfinding.ppd,display\,borders\ borders.pbd <campaign>_lookup.bmp,tile_map.png - V–VI · Terry and BOB, meanwhile
Relief, textures, trees, coasts and water: the terrain the game reads. Careful: as long as the game's database (the one in CA's packs) does not know the map, BOB runs only 6 actions instead of a dozen, with no relief, no textures and no message: see the BOB guide.
full_height_map.dds,tile_list.bin,global_props.bin… - VII · The pack
RPFM gathers the exports, terrain, tables and scripts into the mod's
.pack: the startpos generation needs this pack.my_mod.pack - VIII–IX · The startpos, then the rebuilt pack
The game generates turn 0 with the mod's pack loaded (for us, with the start-table pack as well); for a new map, the AI data too, provided the
<game>\folder exists before the generation (otherwise neitherdata\ campaign_maps\ <map>\ hlp_data.esfnorspd_data.esf, without a message). The pack is then rebuilt with these files: indata, the pack wins over loose files. Redo it after every export and every minimap change.startpos.esf,hlp_data.esf,spd_data.esf - X · In game
Start a game, read the logs, fix, repeat.
Before you start: rights and the team's rules§
- CAIME's code is under a non-commercial licence: modifications allowed, no commercial use, share-alike with public source code if you redistribute, copyright notice kept.
- The files CAIME produces: two texts in the repository contradict each other. The README asks for the express consent of a founder (MrJox, Maruka or Marthenil) before giving away files produced by CAIME, and forbids any commercial use, donations included. The EULA 1.1, which CAIME makes you accept at first launch, leaves you their owner and lets you publish them (Steam Workshop, Nexus Mods, ModDB) without monetising them; it discourages donations without forbidding them. When in doubt, ask the team on its Discord before publishing.
- The EULA also forbids any commercial automated pipeline producing content for third parties.
- The team asks you not to build another universe's map on a Warhammer game: use Troy or Pharaoh, same engine (CAIME team's Discord, 20.09.2026).
- Reusing another CA game's models in a Warhammer game is not allowed (Games Workshop restrictions): you need your own assets (CAIME team's Discord, 20.09.2026).
Sources: the CAIME repository (README, LICENSE, EULA) and, for the team's two rules, its Discord (Campaign Map Modding Team), read on 20 September 2026.
Install and set up§
- Install the game's Assembly Kit from Steam (Library → Tools). For Warhammer III, with Steam in its default location, it installs into
C:\.Program Files (x86)\ Steam\ steamapps\ common\ Total War WARHAMMER III\ assembly_kit\ - Download CAIME from the releases page: the installer is
CampaignMapToolkit-win-Setup.exe. Take the latest version: v1.1.0 of 29 September 2026 ships MapDataBuilder and the templates in the installer, putstile_map.pngback north-up, and makes layer opacity and order adjustable; it touches neither the validators nor the Map Data, Pathfinding and Borders exports. v1.0.1 of 23 September 2026 had brought two fixes: loading the database on any Windows whose decimal separator is the comma, and reading Warhammer I's mini-campaign maps. Updates can be automatic. - At first launch, accept the EULA; after an update, a Changelog window opens. If the view is black when a map opens (known bug), pan or zoom.
- Check after installing: make sure the tool behind the Map Data export,
MapDataBuilder.x64.exe, exists. Since v1.1.0 it ships next toCAIME.exe, inTools\(with the official installer:Release\ %LOCALAPPDATA%\); CAIME looks there first, then at the old path,CampaignMapToolkit\ current\ Tools\ Release\ MapDataBuilder.x64.exe Tools\under the parent of its executable's folder. Before 1.1.0, the installer did not ship it, nor the templates folder (Release\ Templates). If it is missing, ask the team first (Discord, step 8): building the repository takes Visual Studio, with C# and C++. - Settings → Preferences: pick the game first (Base game), then Browse for that game's Assembly Kit. The right folder is
assembly_kit: it holdsbinaries,raw_dataandworking_data. One path per game. Use the menu: it shows Ctrl+P, but according to v1.0.1's code, that shortcut is wired to nothing. - Still in the preferences: Auto-save writes
map_autosave.hexnext tomap.hexevery 5 minutes; Auto-backup storesmap_YYYY_MM_DD_HH_mm_backup.hexinbackups\every 10 minutes (to keep = 0 keeps all: several MB per copy on a large map; set 10 or 20). The Assembly Kit path and the database source apply the next time a project opens; auto-save starts or stops at once. Settings live in%APPDATA%\.CampaignMapToolkit\ Caime\ preferences.json - The database can come from the Assembly Kit (default) or from RPFM (Database source). In RPFM mode, CAIME needs
rpfm_cli.exe, the one from an RPFM version 4 (4.2.7, for example): version 5 no longer ships it. It also needs one Vanilla pack per game (for Warhammer III:db.pack); your mod's packs are added through Settings → RPFM Workflow, with a project open, and CAIME records them incaime_metadata.json, next to themap.hex. - Read the documentation: twelve detailed guides, from getting started to exporting (also through Help → User Guides). For questions, the team's Discord (Campaign Map Modding Team), also through Help → Discord support server.
In Assembly Kit mode, CAIME reads the database (on open and on every Reload) and writes nothing. In RPFM mode it temporarily places tables there and restores the originals when the project closes: don't edit that kit's tables meanwhile, as the restore overwrites whatever is there. If CAIME is killed during an RPFM session, it restores the originals at its next launch (v1.0.1: RpfmRecoveryJournal).
The window and the tools§
With no project open, almost everything is greyed out. Once a map is open, the window has nine areas:
- 1The menusFile, Edit, Process, Tools, Settings, Help.
- 2Quick settingswith Brush, the brush size (Brush size, 1 to 10); the background image opacity (Image opacity) and ✕ to remove it; with Flood Fill, the Flood Fill source list.
- 3The toolsM Pan · Z Zoom · B Brush · F Flood Fill · E Eraser · I Background Image · L Line · P Color Picker; ⚙ Properties, greyed out in v1.0.1.
- 4The canvasthe hex map; the brush circle. Wheel: zoom; middle click: pan.
- 5The minimapthe red frame shows the view; a click there moves the view.
- 6The swatchesthe value to paint, in a drop-down list: the database keys for the active layer (here plains).
- 7The actionsthose of the active layer: Create, Rename, Remove (after the database), Cleanup…; Align, Plug Holes or Auto-generate depending on the layer; Validate.
- 8The layersthe tick box makes a layer visible; the round button makes it active. Ground Types is at the bottom, active on opening.
- 9The status barthe last message (a click opens the Logger), X = column and Y = row under the mouse.
The recipe for painting§
- In Layers, tick the layer's box (it becomes visible) and click its round button (it becomes active: that is the one you paint).
- In Swatches, pick the value: a ground type, a region, a climate…
- In the toolbar, pick the tool (table below), set the brush size, and paint.
- To check: the status bar gives X (column) and Y (row) under the mouse; Ctrl+Z undoes one mouse gesture at a time, up to 1,000 gestures, fewer after large fills (v1.0.1: the history keeps at most 4 million changed hexes).
| Key | Tool | What it does |
|---|---|---|
| M | Pan | move the view (the middle click does it too, whatever the tool) |
| Z | Zoom | zoom (the wheel too) |
| B | Brush | paint; size 1 = 1 hex, 2 = 7, 3 = 19, 4 = 37 |
| F | Flood Fill | fill an area; the Source list offers every layer in the panel, but only Ground Types, Climates, Attritions, Regions, Impassable, Roads and Restrictions act as a border (Trade Routes too, in games that have it) |
| E | Eraser | erase |
| I | Background Image | lay a background image (JPG, BMP, TIFF, PNG), stretched over the map: a working sheet, never saved nor exported |
| L | Line | a first click (in red), the path shows in yellow, a final click |
| P | Color Picker | pick a hex's value; holding Alt gives a temporary picker |
Shortcuts worth knowing§
| Shortcut | Action |
|---|---|
| Ctrl+O · Ctrl+S · Ctrl+Shift+S | open · save · save as |
| Ctrl+X · Ctrl+Q | close the project (not “cut”) · quit |
| Ctrl+R | Reload: reads the database again, and discards anything unsaved |
| Ctrl+Z · Ctrl+Y | undo · redo (1,000 steps at most) |
| Ctrl+Shift+R · Ctrl+Shift+N | resize (margins right, left, top, bottom) · rename the map (the database and the folder under raw_data must follow) |
| Ctrl+L · Ctrl+B · Ctrl+M | Logger · Border Editor · Map Data Editor |
The menus also show Ctrl+N (Create new map) and Ctrl+P (Preferences), but according to v1.0.1's code, these two shortcuts are wired to nothing: use File → Create new map and Settings → Preferences.
The Logger gives faulty hexes as Hex(column, row): move the mouse until the status bar shows that X and Y, and you are on it.
Building a new map, step by step§
Setting up the project§
- Design. Sketch, list of regions and provinces, towns, ports, chokepoints (see below). Even width: CAIME refuses an odd width (“Map's Width needs to be even!”), both at creation and when resizing. The documentation suggests 1016 × 720 and CAIME warns beyond 731,520 hexes (slowness, not a ban). The CAIME team mentions on its Discord (20.09.2026) a ceiling of 2,048 hexes per dimension, beyond which the AI's pathfinding data (hlp, spd) no longer generates; we did not find it in v1.0.1's code. Warhammer III's big map is 1440 × 970. Map name: CAIME lowercases it, turns spaces into underscores and strips punctuation (! @ # - . , etc.) without warning. So write it in lowercase letters, digits and underscores from the start, like CA's maps (
wh3_main_prologue_map), and declare exactly that name in the database: case matters. - Declare the map in the database, with that exact name (Dave, XML by script, or RPFM): see the next section and its column sheet, and, step by step in Dave, the “Setting Up the Database in Dave” part of the official guide Creating a New Map.
- Create the project: File → Create new map (the menu shows Ctrl+N, wired to nothing in v1.0.1 according to the code: use the menu); exact name, Template = None, Game = Warhammer3 (final: the game is baked into the project), even width. CAIME stores the project in its
Projects\folder; with the official installer,<map>\ %LOCALAPPDATA%\. If a project of that name already exists there, CAIME asks “Overwrite?”: Yes deletes its whole folder. Check: when it opens, the Regions layer's Swatches list shows your regions; if it is empty, the database does not know the map (see the FAQ).CampaignMapToolkit\ Projects\ <map>\ - Put it in its place: right away, File → Save as… (Ctrl+Shift+S) to
<Assembly Kit>\, then reopen that copy. Map Data and Dynamic Resources only work there (otherwise: “Map Data Process denied”).raw_data\ EmpireDesignData\ campaign_maps\ <map>\ map.hex
Filling, validating, exporting§
- Add the four support files next to the
map.hex:trees.png,tree_database.xml,dynamic_resources.png,dynamic_resources_database.xml. Without them, Map Data or Dynamic Resources fail. In Warhammer III, copy the XML files from the prologue's folder (wh3_main_prologue_map) and size the images to your map: about 7.04 × 7.37 pixels per hex fortrees.png, 2.54 × 2.40 fordynamic_resources.png.trees.pngalso feeds BOB's trees. Check: the four files sit next to themap.hex, under these exact names. - Save (Ctrl+S), then File → Reload (Ctrl+R) after every database change: CAIME reads again the regions, ground types, climates and attritions declared for this map. Reload discards anything unsaved.
- Paint the layers: every hex needs a region, a ground type and a climate. Land and sea must agree (the ground type, the region's
is_sea, and the hex). - Validate, layer by layer: Tools → Validate → <layer> (eleven entries, one at a time), or the Actions panel's Validate button for the active layer; on the command line,
validate --allchains them. The checks change nothing. Check: the window that follows says “No issues have been found”; otherwise the Logger (Ctrl+L) lists the Errors, Warnings and Info. Fix the Errors (nuances in “Rules for a map that works”), read the Warnings, save. - Export (Process): Map Data, Dynamic Resources, Pathfinding, Borders, Lookup. Save first; Tweak and Terry closed. Map Data success: in the Logger, “MapDataBuilder exited with code 0 (Success)”; the documentation also cites “Finished creating map”, which is written neither by CAIME nor by MapDataBuilder but comes from the kit's output. Check: in
<Assembly Kit>\, dated today,working_data\ campaign_maps\ <map>\ map_data.esf(CAIME treats a file of 10 KB or less as failed),pathfinding.ppd,display\andborders\ borders.pbd <campaign>_lookup.bmp. Details: the “Exporting” section. - Meanwhile, the visual half: export the tile map (Tools → Export → Baseline Tilemap image,
tile_map.png) for the Terry project, then Terry and BOB. Since v1.1.0 the image comes out north-up; up to 1.0.1 it comes out upside down: flip it vertically, with no other retouching. - Build the pack, then generate the startpos once both halves are ready. The three ways to the startpos: RPFM's Build Startpos, BOB's Process start pos action, or a hand-written
user.script.txt. For us, only the hand-written way worked: the tools guide. Then rebuild the pack with the startpos (RPFM) and test in game. Every change to the map means a new export, then a new startpos.
Database tables to declare§
The map's name (here my_map) is the same everywhere, case included; the campaign's name (here my_campaign) links campaigns, campaign_map_playable_areas and campaign_map_roads. Column names come from the Warhammer III kit's schemas (raw_data\).
| Table | What it says | Columns that hold the map together |
|---|---|---|
campaign_maps | the map, in the kit (in the game's packs, Warhammer III no longer has this table: the map is declared there through campaigns.map_name and campaign_map_playable_areas) | mapname = my_map; minx, miny, maxx, maxy |
campaigns | the campaign whose map_name is the map; otherwise the Lookup export refuses (“no campaign uses the map”). Copy a working campaign row, field by field: mask empty, like every campaign in the kit; a non-empty mask crashes the startpos generation (9.0.2) | campaign_name = my_campaign; map_name = my_map; mask empty |
campaign_map_playable_areas | the campaign playable area: camera limits and minimap files (update it before Map Data if the size changes); the selection screen's preview has the world's aspect ratio, height 600 (CA: 750 × 600), otherwise the map looks distorted there | mapname = my_map; campaign_key = my_campaign; minx, maxx, miny, maxy; radar_file (the minimap); preview_width × preview_height; index, an automatic number |
regions | one row per region, land or sea, with a unique RGB colour (used by the lookup images) | key; is_sea (0 or 1); r, g, b |
campaign_map_regions | links each region to the map | campaign_map = my_map; region = a key from regions |
region_to_province_junctions | one row per region, to its province | region; province; is_capital |
provinces | the province, if it is new | key |
campaign_map_roads | road costs, per campaign | key; campaign = my_campaign; threshold; movement_cost |
campaign_map_areas_of_interest | Warhammer III and Three Kingdoms: filtered by map name, otherwise an empty layer | key; campaign_map = my_map |
These tables have other columns, many of them marked as required in the kit: fill them in after a CA row, the prologue's (wh3_main_prologue_map) for instance; the official documentation describes them one by one (Creating a New Map, Dave part). Here, as is, is a row of the Warhammer III kit's campaign_map_regions.xml (read on 25.09.2026, patch 9.0): the Tong-Hall region attached to the prologue map. The record_… attributes are the ones Dave writes; record_key glues the two keys together.
<campaign_map_regions record_uuid="{4ba484b4-177d-4524-833f-fc5907111d3a}"
record_timestamp="1552390918186"
record_key="wh3_main_prologue_mapwh3_prologue_region_broken_lands_tong_hall">
<campaign_map>wh3_main_prologue_map</campaign_map>
<region>wh3_prologue_region_broken_lands_tong_hall</region>
</campaign_map_regions>Global tables (campaign_ground_types, climates, campaign_map_attritions) are already filled. Regions are indexed in the project's order (map.hex: land, then sea), which need not follow regions.xml: only the set of keys must match. For ground types, climates and attritions, however, the project's order must be the database's (otherwise, an Error “name mismatch at index”). A script that encodes a regions .hex_layer in the order of regions.xml therefore comes out wrong. Check: when the project opens (or after File → Reload, Ctrl+R), the Regions layer's Swatches list shows your regions.
Creating, renaming or deleting a region, ground type, climate, attrition or area of interest takes two moves: change the database, then, in the Actions panel, the matching button (Create, Rename, Remove), with the same name. Remove does not clear hexes already painted.
The layers§
A layer is one piece of information per hex. You paint them one by one, like sheets laid over the same grid; a needle stuck through one hex goes through every sheet and reads one value on each.
- 1Ground Typesground type: plain, forest, mountain, sea
- 2Climatesthe climate: required on every hex
- 3Regionseach hex's region, and its borders
- 4Riversrivers, with their directions
- 5Town Sprawl · Town Slotsa town's slot (19 hexes in Warhammer III; a port: 16 + 3) and its sprawl
- 6Roads · Impassableroads, with their directions; what cannot be crossed
The needle goes through one hex: its record
- Ground Types
plains- Climates
emp_lowlands, for example- Regions
my_region- Rivers
- no
- Town Slots
- no
- Roads
- yes, two sides
- Impassable
- no
Warhammer III's layers, with the names the editor shows, in the panel's default order (the top one is drawn over the others). Since v1.1.0 this order can be changed (drag, or menu; Reset order restores it) and each layer has an opacity from 0 to 100%: a display setting, which changes nothing in the exports and is not saved in the project.
| Layer | What you paint | Effect, tool or action |
|---|---|---|
| Impassable | forbidden hexes | Plug Holes action: fills one-hex holes |
| Roads | roads, with their directions | lower cost (campaign_map_roads); rings allowed |
| Town Slots | the slots: Main Settlement, Port, Slot 2… | see “Towns” |
| Town Sprawl | each town's footprint | Align Town Sprawl/Slot action |
| Bridges | bridges, on sea hexes | see “Bridges” |
| Rivers | rivers, with their directions | on land only |
| Beaches | beaches | only on coastal land: landings |
| Restrictions | graded movement restrictions | can be lifted by a Lua script |
| Region Borders | drawn borders | Auto-generate action, to redo (then Ctrl+S) after any change to the regions: nothing recomputes it by itself |
| Areas Of Interest | areas of interest | needs the campaign_map_areas_of_interest table |
| Regions | each hex's region | swatches to create (name + Is sea?) |
| Attritions | armies' wear | swatches to create |
| Climates | the climate: required on every hex | swatches to create |
| Ground Types | ground type: plain, forest, mountain, sea… | sets movement cost; Align Ground/Region Type action: derives land or sea from the regions |
A fifteenth layer, Trade Routes, does not appear in Warhammer III's panel: it only serves Rome II, Attila, Thrones of Britannia and Three Kingdoms. The other layers are two-state (present or not), except those with swatches.
Rules for a map that works§
The eleven checks sort each message into three levels (v1.0.1's code).
- Error, to fix before exporting: database/map mismatch (regions, ground types, climates, attritions), invalid index, misplaced bridge, slot on impassable, town-sprawl rules. Only exception: a sprawl Error on a town in a pass, which CA's map has too (five towns); judge it in game.
- Warning, to read: hex without region, ground or climate, land/sea mismatch, split or empty region, rivers, roads, beaches, slot size…
- Info: a remark.
CAIME does not stop you exporting with Errors (even though the documentation says: “Fix all errors before processing”): read the Logger (Ctrl+L). For reference, CA's Warhammer III map raises hundreds of Warnings, and exports.
Regions§
- Every hex has a region, a ground type and a climate. An empty region endangers the startpos.
- A land region is in one piece: the validator warns that a split region may hinder the startpos generation. A land region without a town is painted entirely impassable.
- A sea region touches at most 5 land regions (advice, Info level); beyond 9, Warning: the AI slows down, especially with hordes.
- Borders are never recomputed by themselves. After any change to the region shapes (brush or import), click Auto-generate on the Region Borders layer, then save, before Pathfinding: neither saving, nor importing, nor the Pathfinding export recomputes the borders (Pathfinding reads the layer as it is). Check:
validate --regionswithout the Info “0 passable region edge hexes” on a region that has land neighbours. For us, a grid whose regions were imported by script had 0 border hexes. - No check makes sure a port's sea reaches the other seas (none of the eleven validators walks the sea). After any change to impassable hexes at sea or any enlargement of the map, check the sea alone yourself, port by port. For us, 434 impassable hexes, the old edge of an enlarged map, closed off a gulf: three ports opened onto a closed sea, without any message.
Towns: slot and sprawl§
Every passable region has at least one town slot; otherwise, Warning. The main slot (Main Settlement) is a perfect 19-hex disk around the town's centre (one click of a size-3 brush); its centre becomes the town's position. An inland town keeps its 19 hexes, with no Port hex. A port town keeps the same disk, split: 16 land hexes in Main Settlement and exactly 3 Port hexes, consecutive on ring 2 (the disk's rim), sea side: two at sea and one on the beach, as at CA (measured on 290 ports of its maps). The Port hexes at sea keep the sea region, not the town's. The sprawl covers the 19 hexes. MapDataBuilder needs the disk: without it the town has no position and the campaign AI crashes. The Align Town Sprawl/Slot action lays the sprawl under each slot.
- The sprawl is one block per region and never sits on impassable (Error). The documentation also forbids river and cliff, but v1.0.1's code does not check it, and a CA port town's sprawl necessarily covers coast hexes.
- A hazard (impassable, rivers and the whole coast) either touches the sprawl or stays at least 3 hexes away; never 2. Only one hazard zone in contact. Both rules are Errors.
- A port's sprawl may spill onto the sea.
- The documentation gives three different rules for Warhammer III; CAIME's code applies 19 and 16 to Warhammer I, II and III. When porting a Warhammer I map (7 hexes, 4 for a port), grow the slots from 7 to 19 hexes (16 + 3 for a port).
Rivers and bridges§
- A river is on land only: it runs towards the coast but stops on the last land hex; no edge points to the sea or off the map.
- A river mouth is marked Beach AND River. When
tile_map.pngis exported (Baseline Tilemap image), every land hex next to the sea that is not a beach becomes a cliff, rivers included; only a hex that is both river and beach gives “river ending at beach” (painted as beach for Warhammer III). Otherwise the river ends on a cliff and never reaches the sea (CAIME's code,BaselineTilemapExporter.cs). - A beach goes on low land only. At CA, a beach sits on low land; on high land the beach profile makes a steep slope (a dark shadow on the preview, a dyke). Workshop rule: a beach whose land rises above 0.8 u within 3 hexes inland becomes a cliff again, except port beaches and river mouths, then runs shorter than 3 hexes are dropped (on Expanded: 909 beaches down to 621,
validatewith no error). - A bridge spans water painted as sea, shore to shore: paint Bridges on those sea hexes and lead the road to the shore. CAIME itself marks the shore hexes touching the bridge (bridge-cliff). Warhammer III's database even has a sea ground type for waterways,
sea_river. - The validator (v1.0.1) raises three Errors: a Bridges hex on land, an impassable Bridges hex, a bridge not joining two separate shores. A Rivers line lies on land: it is not bridged.
Designing a map that plays well§
- Start from gameplay: passes, fords, straits, faction neighbourhoods, invasion routes. Corridors and strongholds, not a uniform plain.
- Biomes in zones: continuous ranges with two or three passes, forests in one block.
- Believable rivers: mountain sources, confluences, deltas.
- Link a province's towns, then the provinces together. Rings and triangles of roads, rivers and trade routes are fine; draw roads as threads with few junctions, like CA's: a densely meshed road network (hundreds of junctions) can block the Pathfinding export for tens of minutes while validation passes (the validator only raises an Info per three-way junction). For us, roads mirrored like an image (331 three-way junctions, 55 four-way): 22 minutes without writing anything; redone as threads (20 junctions): 4 seconds. Count the junctions and put a time limit on the export; mirror a map in the hex grid's frame, never in the image's.
- Compact regions of similar size; ports where trade makes sense.
- Keep the map accessible: every part of it should be close to the action. A corner that is not literally cut off but lies far from everything that happens is boring to play.
- Keep settlements more than 5 hexes apart: within 5 hexes, one settlement's garrison reinforces sieges of the other, an unintended game mechanic.
- Prototype small (200 × 150), validate, export the pathfinding, then go to the final size: resizing (Ctrl+Shift+R) adds empty canvas, it does not scale the drawing.
Layer names are movement rules, not scenery§
The names of the hex layers (river, bridge, road…) do not have to match what the player sees. For the game, they are movement rules, and you can dress them as you like:
- River: a hex where an army loses all of its movement when it crosses it. It can stand for a gateway, a doorway or an elevator on the visual side, or have no visual cue at all: you may simply want to nullify army movement for a game-balance reason, or to steer the AI (the Old World campaign mod does something like this with the Realm of Slaanesh, to stop it from being used as a through-way).
- Bridge: not necessarily a bridge. The bridge trick is another example: it moves an army a long distance while spending almost none of its movement.
- Road: road hexes cost very little movement and usually match roads you can see in game, but they do not have to: you could lay train tracks instead of the usual road tiles.
The visual tile map is not painted by hand either: CAIME's Baseline Tilemap image export draws the roads and the coastlines from the hex map, for every supported game (see the sections on Exporting and on Terry).
Editing an existing map§
Repainting with existing values does not touch the database. Creating, renaming or deleting a type, a region or an area of interest takes the database and the Actions panel button. Workflow: validate → save → re-export → rebuild the pack → regenerate the startpos → rebuild the pack.
| Change | Database? | Exports to rerun |
|---|---|---|
| Repaint ground types, attritions, impassable, restrictions | no | Pathfinding, Map Data |
| Repaint roads, rivers, beaches, bridges, slots and sprawls | no | Pathfinding, Map Data |
| Repaint climates | no | Map Data |
| Region shapes (repaint or import Regions) | no | first Region Borders' Auto-generate and Ctrl+S; then Borders, Pathfinding, Map Data, Lookup |
| Create, rename or delete a ground type | yes (campaign_ground_types) | Pathfinding, Map Data |
| Create, rename or delete a climate or an attrition | yes (climates, campaign_map_attritions) | Map Data |
| Create, rename or delete an area of interest | yes (campaign_map_areas_of_interest) | Map Data |
| Add, rename or delete a region | yes (regions, campaign_map_regions, region_to_province_junctions) | all |
| Resize (Ctrl+Shift+R, with its margins) | campaign playable area (campaign_map_playable_areas) | all; new hexes are empty |
That is what the documentation asks for: the exports of the changed layers, and always Map Data. When in doubt, rerun everything: on its Discord (20.09.2026), the CAIME team explains that changing a single hex means reprocessing almost everything; only borders.pbd and the lookup images, purely visual, can be redone alone. Why: the tw-modding wiki calls pathfinding.ppd and spd_data.esf critical as soon as the map data changes; and for us, Map Data exports run alone left a day-old pathfinding.ppd in place. Then regenerate the startpos.
Exporting: what each export produces§
- Save first: Map Data and Dynamic Resources refuse to run otherwise.
- Map Data goes through the MapDataBuilder tool: the project must sit in its
raw_dataplace, and Tweak and Terry be closed (Terry is a mode of Tweak), for Dynamic Resources too. Don't rely on the warning: CAIME looks for a program namedTweak.AssemblyKit, while Warhammer III's kit shipstweak.modder.x64.exe. Success: “MapDataBuilder exited with code 0 (Success)” in the Logger; amap_data.esfof 10 KB or less is treated as failed. - When Map Data fails (v1.0.1): the Logger gives MapDataBuilder's exit code and its meaning. That code adds up flags: 1 = missing arguments, 2 = the kit's DLL (ToolDataBuilder) does not load (Assembly Kit path,
binariesfolder), 4, 8 and 16 = a function missing from that DLL, 32 = the kit's export failed (themap.hexor the map's regions), 64 = the same for Dynamic Resources, 128 = the DLL cannot be freed. CAIME also copies BOB's logs into it, read from%APPDATA%\(The Creative Assembly\ <game>\ console_spools\ Command.txt,Errors and assertions (in order).txt). After 30 minutes, MapDataBuilder is stopped. - Borders opens a choice window (Land, Sea, TI, MI; according to the documentation, TI = theatre island, a detached island, and MI = Mediterranean island, a smaller island): keep the default boxes.
- Dynamic Resources crashed MapDataBuilder on Warhammer III in our workshop; it is unresolved. If it happens to you, report it to the team.
- Trade Routes: the layer does not exist in Warhammer III, but the game's campaigns ship a
trade_routes.ptd, and--allproduces it.
| Export | File produced |
|---|---|
| Map Data | map_data.esf |
| Pathfinding | pathfinding.ppd (the “Processing & Exporting” page wrongly says .bin) |
| Borders | display\ |
| Dynamic Resources | dynamic_resources.esf |
| Trade Routes | trade_routes.ptd (games that have this layer; not Warhammer III) |
| Lookup | for Warhammer III, a single <campaign>_lookup.bmp image (read in v1.0.1's code; the documentation also mentions a minimap); BMP for Warhammer I to III, Troy and Three Kingdoms, TGA elsewhere |
Everything goes to <Assembly Kit>\. The lookup image, <campaign>_lookup.bmp, comes out as BMP; the game reads the files named in the map's row of campaign_map_playable_areas (on the prologue: overlay_file and minimap_lookup_file as .tga, campaign_overlay_lookup as .dds, radar_file as .png for the minimap). The tw-modding wiki runs that BMP through BOB to get the .dds and .tga files; an out-of-date lookup does not crash the game, but the map overlays look a bit odd.
The Tools → Export menu also gives the borders and the roads as SVG (SVG Borders, SVG Roads), the tile map for Terry (Baseline Tilemap image, tile_map.png) and each layer as PNG or binary; Tools → Import → Layer data reads back a .hex_layer of the same size. The Map Data Editor only serves Rome II, Attila and Thrones: it refuses Warhammer III. Tools → Shader Resolution Corrector is only enabled for Three Kingdoms.
Going further: every project opening also creates working_data\. A CAIME built in Debug from the repository drops its diagnostic files there on every Pathfinding (debug_*.raw, .bmp: areas, edge costs, bridges): the tool's view of your map, readable without the game. The official installer (Release) does not write them (v1.0.1's code).
From the command line§
Started without arguments, CAIME opens the editor; with arguments, it works in the console. The official documentation describes two commands, plus --help:
CAIME.exe process --map <map.hex> (--all | --map-data --dynamic-resources --pathfinding
--borders --trade-routes --lookup)
CAIME.exe validate --map <map.hex> (--all | --rivers --town-slots --roads --bridges --beaches
--regions --attritions --climates --ground-types
--impassable --town-sprawl)
--map shortens to -m · exit codes: 0 success · 1 invalid arguments · 2 failure--allchains Map Data → Dynamic Resources → Pathfinding → Borders → Trade Routes → Lookup; it cannot be combined with individual flags.- The Assembly Kit path is set in the editor first (Settings → Preferences).
processrefuses to run without it;validateruns anyway, but the checks comparing the map with the database then have nothing reliable to compare: don't trust their verdict. validateexits with 2 as soon as one check fails, a single Warning is enough, and even CA's maps fail: read the report rather than stopping a script on that code.- The official command line only does
process(the exports) andvalidate; a.hex_layerlayer is written by script but imported through the window (Tools → Import → Layer data). process --bordersfails without the window in official v1.0.1: the border options (Land, Sea, TI, MI) are only initialised by the Process → Borders data window (BorderExportOptionsViewModel, read in the code); on the command line they stay empty.--all, which includes Borders, therefore always exits with 2; it also includes Dynamic Resources, which crashed MapDataBuilder on Warhammer III for us. List the tasks instead (--map-data --pathfinding --trade-routes --lookup) and run Borders from the Process menu.
Producing layers by script§
For a large map, painting by hand is not enough. A .hex_layer is a simple file: 4 bytes (a little-endian integer: the layer id), then one byte per hex, row by row, from row 0, at the bottom of the map (two bytes per hex for regions). The file is exactly 4 + W × H bytes (4 + 2 × W × H for regions), otherwise the import is refused.
| Id | Layer | Value on disk |
|---|---|---|
| 0 | Impassable | 1 = passable, 0 = impassable (in the file; in the editor, painting Impassable makes the hex impassable) |
| 1, 2, 6 | Trade Routes, Roads, Rivers | the edge mask (six bits) |
| 3 | Town Slots | index + 1: 0 = none, 1 = main (Main Settlement), 2 = Port, 3 = Slot 2… up to 12 (indices 0 to 11) |
| 4, 5, 7 | Town Sprawl, Bridges, Beaches | 1 = yes; any other value means “no” |
| 8 | Region Borders | the edge mask (six bits) |
| 9 | Regions | two bytes: v × 8 in little-endian, with v = index + 1 (first byte = (v × 8) mod 256, second = v // 32, integer division) |
| 10, 11, 12 | Attritions, Climates, Ground Types | index + 1 |
| 13, 14 | Restrictions, Areas Of Interest | no format: neither import nor export of a .hex_layer |
- Edge mask: bit 0 = north, 1 = north-east, 2 = south-east, 3 = south, 4 = south-west, 5 = north-west. On import, only presence counts for roads and rivers (value > 0): CAIME recomputes their masks, linking every painted neighbour except the edge that would close a triangle. Trade-route masks are kept as they are. Region Borders keeps its marked hexes: importing Regions does not recompute it, nor does saving (it only recomputes the masks among hexes already marked as border). After a Regions import: Auto-generate on the Region Borders layer, then Ctrl+S, before Pathfinding. (For us, a verb added to our copy of CAIME,
generate-region-borders, does the same on the command line; it is not in the official release.) - Indices follow the project's order: land first, then sea (a sea type with index j is worth “number of land types + j”).
- Indices change from one game to another (13 land ground types and 24 climates in Warhammer I, 15 and 40 in Warhammer III): match them by name, never by number.
- Only reimport the layers you actually changed: reimporting Roads or Rivers recomputes all their masks, and the original map's links are lost, even though the hex count stays the same.
- CAIME's PNG export flips the image to look like the game: an image drawn “top up” must be flipped before encoding.
Our method: a painted image (one colour = one value) and a legend → one .hex_layer per layer → import into CAIME (through the window: Tools → Import → Layer data) → PNG export to check → validation → fix the image, and repeat. The image and the legend stay the source of truth; the map.hex is the product.
Porting a map from another Total War game§
That is what we did with The Season of Revelation's map (Warhammer I → Warhammer III, 400 × 440 hexes, 61 regions). The steps specific to a port:
- Read the original map's layers (CAIME opens Warhammer I's mini-campaign maps since v1.0.1) and match them by name to the target game's lists.
- Match faction keys on culture and the end of the key, never on the prefix:
wh_dlc05_brt_mini_bastonnein Warhammer I iswh_main_brt_bastonnein Warhammer III. - Grow the settlement slots from 7 to 19 hexes (16 + 3 for a port), as a disk around their centre, and redo the sprawls. A port is never grown to 19 + 3: the game crashes while loading the campaign (box “What the validator lets through”).
- When enlarging the map, open the old map's sea edge (its former non-playable border, often impassable) and check the sea alone, port by port: CAIME does not check that a port's sea reaches the others.
- Keep the file names of the original
campaign_map_playable_areasrow (theradar_filecolumn, for example: the minimap): a column that names a file is checked against the pack's actual contents. - Keep the other game's files out of anything you publish: they belong to CA.
The full story: the porting tutorial and the nine walls of the port.
The pitfalls that cost us the most§
- Reload (Ctrl+R) throws away anything unsaved: Ctrl+S first, always.
- The project's game is final: a project created for the wrong game is redone (see the FAQ).
- Missing support files: Map Data or Dynamic Resources fail. Copy them from the prologue.
- Mistaking painted triangles for exported ones: CAIME drops an edge that would close a road or river triangle; do not erase the network on principle.
- Impassable = 1 means passable, in a
.hex_layer: the opposite of intuition. - Row 0 at the bottom: a map drawn “top up” ends up upside down.
- Tweak or Terry open during Map Data or Dynamic Resources: close both; CAIME's warning does not see them (see “Exporting”).
- Map name: CAIME lowercases it at creation; declared with capitals in the database, it leaves the swatches empty.
- Ctrl+N and Ctrl+P, shown in the menus, are wired to nothing in v1.0.1 (according to the code): use File → Create new map and Settings → Preferences.
- Create new map on a name already taken: “Overwrite?”, and Yes deletes the draft's whole folder.
- Ctrl+X closes the project: it is not “cut”. If unsaved changes remain, a question catches you: answer No.
- Ctrl+Shift+N renames the map, but the database (
campaign_map_regions,campaigns,campaign_map_areas_of_interest) and the folder underraw_datamust follow the new name. - No campaign cites the map: the Lookup export refuses.
- The map's row in last position of
campaign_map_playable_areas: Map Data crashes. - Layer indices shift when the database or the game changes: match them by name.
- A port in 19 + 3, 16 + 1 or 16 + 2 passes validation and crashes the game while loading the campaign: 16 + exactly 3, two at sea and one on the beach (“Towns”).
- **Regions changed without Region Borders' *Auto-generate***: the borders stay the old ones, and Pathfinding reads them as they are, without a message.
- A non-empty
campaigns.mask: the startpos generation crashes (“Database tables to declare”). - A game update wipes your kit rows: Steam updates the Assembly Kit after the game (for us, an hour later, with 9.0), and with every game or kit update (9.0 on 24.09, 9.0.2 on 27.09) it rewrites
raw_data\, which CAIME reads; the rows added for your map disappear. Before reopening the project or exporting, look for your campaign's key indb campaigns.xml, and restore your rows from your copies. - Resizing does not scale: it adds empty hexes to paint.
- The background image is never saved: reload it every session.
- The black view when opening: pan or zoom.
- The Map Data Editor refuses Warhammer III: it only serves older games.
- The repository's Warhammer III templates (
wh3_main_combi_map_1,wh3_main_chaos_map_2) are old versions without support files; the Assembly Kit's current maps are_map_5and_map_4. Since v1.1.0 the installer ships the templates, but they are lost from the install folder at every update (known limitation of the team's PR #15). - The documentation contradicts itself on a few points:
.binor.ppdfor the pathfinding (the code writespathfinding.ppd), the bridge-cliff (“ground type” in the documentation, computed in the code), the sprawl rules (river and cliff forbidden in the documentation, only impassable in the code), slot sizes in Warhammer III, the colours of the severity levels, “more than 9 neighbours” as Warning or Error, the ⚙ button, what Baseline Tilemap image contains (Warhammer III gives ordinary rivers thegenericcolour and river mouths the beach colour), the Map Data Editor configuration as.jsonor.xml, the sample Assembly Kit path, whether you can paint on a hidden layer, and “unlimited” undo (the code caps it at 1,000 steps). Trust the validator and the disk.
For an AI reading this page§
If you are an AI helping someone build a map with CAIME, here are the essentials as checkable rules. These facts were gathered on CAIME 1.0.1 and game patch 8.1 (September 2026), reviewed for update 9.0, then corrected on 5 October 2026 with the facts proven on 9.0.2 and with CAIME 1.1.0 (validators unchanged): check them again after an update.
- Ask the human before launching the game, driving the screen or publishing; delete nothing: tidy away, only the human deletes.
- Reading and documenting a file format, as RPFM and CAIME do: yes. Altering CA's programs or working around their limits: no, with one exception the workshop owns, stated plainly in the BOB guide: BOB run under a debugger for a new map's terrain. When a tool gets stuck, a control case, then the community (CAIME's Discord, tw-modding).
- Chain order: database → CAIME (paint, validate, export) → Terry and BOB → pack → startpos (generated by the game, pack loaded) → rebuilt pack → in-game test.
- Project:
<Assembly Kit>\, saved, withraw_data\ EmpireDesignData\ campaign_maps\ <map>\ map.hex trees.png,tree_database.xml,dynamic_resources.png,dynamic_resources_database.xmlnext to it; Tweak and Terry closed (CAIME's warning does not detecttweak.modder.x64.exe); output inworking_data\:campaign_maps\ <map>\ map_data.esf,pathfinding.ppd,display\,borders\ borders.pbd <campaign>_lookup.bmp. - Map name: CAIME lowercases it and strips punctuation at creation; the database must carry exactly that name, case included. Even width, enforced.
- Interface (v1.0.1, according to the code): Ctrl+N and Ctrl+P are shown but wired to nothing, use the menus; Ctrl+Z goes back 1,000 steps at most (4 million changed hexes at most).
- Backups:
map_autosave.hexnext tomap.hex(5 min),backups\(10 min).map_YYYY_MM_DD_HH_mm_backup.hex - Database: in Assembly Kit mode, CAIME reads
raw_data\without writing to it; in RPFM mode, it places tables there for as long as a project is open and restores the originals on close.db - After every game or kit update (9.0, then 9.0.2), Steam updates the Assembly Kit and rewrites
raw_data\, added rows lost: check the campaign's key indb campaigns.xmlbefore reopening or exporting, and restore from the copies. - New campaign:
campaignsrow copied from a working campaign,maskempty (otherwise the startpos generation crashes);campaign_map_playable_areaspreview (preview_width×preview_height) at the world's aspect ratio, height 600; the<game>\folder created before the generation, otherwise neitherdata\ campaign_maps\ <map>\ hlp_data.esfnorspd_data.esf. - Official command line:
CAIME.exe process|validate --map <map.hex> (--all | flags); codes 0, 1, 2;validate's code 2 is not enough to conclude (a single Warning triggers it): read the report.process --bordersfails without the window in v1.0.1 (border options not initialised), so--alldoes too;--allalso includes Dynamic Resources (MapDataBuilder crash on Warhammer III for us): list the tasks, and Borders from the menu. Failed Map Data: read MapDataBuilder's exit code in the Logger (flags 1 to 128) and the copied BOB logs. A.hex_layeris imported through the window (Tools → Import → Layer data). .hex_layer: 4-byte id (little-endian, 0 to 12), then one byte per hex from row 0 at the bottom (regions: two bytes, v × 8 little-endian, v = index + 1); exact size 4 + W × H (4 + 2 × W × H for regions); edge masks: bits 0 to 5 = N, NE, SE, S, SW, NW; Impassable: 1 = passable; Town Slots: 0 = none, 1 = main, 2 = Port, 3 = Slot 2… up to 12; Restrictions (13) and Areas Of Interest (14): no import or export format.- Import: Roads and Rivers keep only presence (value > 0); CAIME links every painted neighbour except the edge that would close a triangle; Trade Routes masks are kept as they are; Region Borders is recomputed neither by the brush, nor by importing, nor by saving, nor by Pathfinding: after any change to the regions, Auto-generate on the Region Borders layer, Ctrl+S, then Pathfinding; check:
validate --regionswithout the Info “0 passable region edge hexes” on a region that has land neighbours. - Roads:
validate --roadsdoes not see an over-meshed network, which blocks Pathfinding; threads, few junctions (count the hexes with three branches or more), a time-limited export; a mirror in the hex grid's frame, never the image's. - Baseline Tilemap image: a 2 × W by 2 × H + 1 image, exported without manual retouching. With CAIME 1.1.0 or later, the
tile_map.pngimage comes out north-up: use it as is. Up to 1.0.1, it comes out upside down (south at the top): flip it vertically, and only that. Check: the image's coast lies over the PNG export of the Ground Types layer. For Warhammer III: sea, coastal cliffs and transitions, roads and beaches; every coastal land hex that is not Beach becomes a cliff, rivers included; a river mouth is marked Beach AND River (“river ending at beach”, painted as beach); other rivers usegeneric(BaselineTilemapExporter.cs). - Checks, as conditions: every hex has region, ground and climate; the region's
is_sea= the ground's sea or land; land region in one piece; main slot = perfect 19-hex disk, its centre = the town's position; inland town = 19 hexes, no Port; port town = 16 land hexes in the main slot + exactly 3 consecutive Port hexes on ring 2, two at sea and one on the beach, as at CA, the sea hexes keeping the sea region (the validator only asks for one hex at sea and lets 19 + 3, 16 + 1 and 16 + 2 through, which crash the loading on 9.0.2: count for yourself); a port's sea reaches the other seas (no validator checks it: check the sea alone, port by port); sprawl over the 19 hexes, never on impassable; hazard (impassable, river, coast) touching or at least 3 hexes away, only one zone in contact; river with no edge towards the sea or off the map; bridge on sea hexes between two separate shores (CAIME computes the bridge-cliff); Roads, Rivers and Trade Routes may form rings and triangles (CAIME drops the closing edge of road and river triangles). - Severities (v1.0.1): Error = database/map mismatch, invalid index, misplaced bridge, slot on impassable, sprawl rules; Warning = hex without region, ground or climate, land/sea mismatch, split or empty region, rivers, roads, beaches, slot size. Before exporting: zero mismatch, index and bridge Errors; a sprawl Error on a town in a pass also exists on CA's map (five towns): judge it in game. After every export: a new startpos.
- Ground, climate and attrition indices are matched by name, never by number.
- Rights: nothing commercial; before publishing files produced by CAIME, ask the team (the README and the EULA 1.1 contradict each other: see “Before you start”).
Sources and links§
- CAIME documentation (twelve guides, including Creating a New Map and the command line), the repository (and its source code,
mainbranch, which settles it when the documentation contradicts itself), its releases and the team's Discord (Campaign Map Modding Team). - Campaign Map Making for Warhammer III and Startpos (tw-modding wiki).
- RPFM manual and RPFM For Dummies.
- Terry introduction and Rules.bob (Creative Assembly wiki).
- Our other guides: the tools, RPFM, Terry, BOB and modding with an AI.
Frequently asked questions
My swatches are empty after creating the project: why?
CAIME cannot find the map in the database. Check the Assembly Kit path for the right game (Settings → Preferences), and that the map name in campaign_map_regions matches yours exactly, case included: CAIME lowercases the name typed at creation, so the database must write it in lowercase. Then save and do File → Reload.
Why does CAIME open everything read-only?
On any Windows whose decimal separator is the comma (French, German, Spanish, Italian…), versions before the culture fix fail to load the database and open everything read-only. The fix is in v1.0.1.
The map opens all black: what should I do?
It is a known bug: pan or zoom the view.
The Map Data export fails: what should I check?
That the project is saved in its place (raw_data\), that Tweak and Terry are closed, that the four support files are next to the map.hex, that the map's row is not the last one of campaign_map_playable_areas, and that the MapDataBuilder tool is installed (since v1.1.0, next to CAIME.exe; with the official installer: %LOCALAPPDATA%\). Then read MapDataBuilder's exit code and BOB's logs in the Logger (see “Exporting”).
Why does the export run forever?
A road or river loop is allowed, but a densely meshed road network (hundreds of junctions) can block Pathfinding for tens of minutes while validation passes: for us, 331 three-way junctions, 22 minutes without writing anything; redone as threads, 20 junctions, 4 seconds. Draw threads, with few junctions, like CA; count the junctions and put a time limit on the export. Otherwise, read the Logger to find which export step does not finish, compare with a known-good project, then inspect that export's data. MapDataBuilder is stopped after 30 minutes.
Must I re-export everything after a change?
The documentation asks for the exports of the changed layers, and always Map Data. When in doubt, rerun everything: on its Discord (20.09.2026), the CAIME team explains that changing a single hex means reprocessing almost everything. Then regenerate the startpos.
I picked the wrong game when creating the project: what now?
The game is baked into the map.hex. Create a new project of the same size, export each layer as binary (Tools → Export → Layer data), then import them into the new project (Tools → Import → Layer data). Restrictions and Areas Of Interest have no export format: repaint them. If the game changes, first re-match ground, climate and attrition indices by name.
Where are my automatic backups?
map_autosave.hex (every 5 minutes) sits next to the map.hex; every 10 minutes the backups folder gets a copy named map_YYYY_MM_DD_HH_mm_backup.hex. Open them with File → Open, then Save as. During a session, Ctrl+Z goes back up to 1,000 gestures.
Why is my bridge refused?
A bridge is painted on sea hexes, shore to shore. The validator (v1.0.1) raises three Errors: a Bridges hex on land, an impassable Bridges hex, a bridge not joining two separate shores. CAIME works out the shore hexes itself. A Rivers line lies on land: it is not bridged.
What shape should a town's slot take, and a port's?
A perfect 19-hex disk around the town's centre (one click of a size-3 brush): its centre becomes the town's position; an inland town has no Port hex. A port town keeps the same disk, split: 16 land hexes in Main Settlement and exactly 3 consecutive Port hexes on ring 2, two at sea and one on the beach, as at CA (measured on 290 ports); the hexes at sea keep the sea region. The sprawl covers the 19 hexes. The validator accepts 19 or 16 and a single hex at sea: it lets through ports in 19 + 3, 16 + 1 or 16 + 2, which crash the game while loading the campaign. Without the disk, the town has no position and the campaign AI crashes.
I paint and nothing shows: why?
Check the active layer (the round button), the visible layer (the tick box), the chosen swatch, and that the toolbar is not greyed out (no project open).
Hundreds of warnings on a CA map: is that serious?
No: CA's Warhammer III map raises hundreds and exports all the same; it even has five sprawl Errors, on towns in passes. Fix every database/map mismatch, index and bridge Error, read the Warnings; the Info entries are remarks.
What is the maximum map size?
Even width (CAIME refuses an odd width); CAIME warns beyond 731,520 hexes (slowness), and the CAIME team mentions on its Discord (20.09.2026) a ceiling of 2,048 hexes per dimension, which we did not find in the code. Warhammer III's big map is 1440 × 970.
Can a Warhammer I map be ported to Warhammer III?
Yes: that is what we did with The Season of Revelation. Since v1.0.1, CAIME opens Warhammer I's mini-campaign maps; our journal tells the method step by step.
Can I share the files CAIME produces?
The EULA 1.1 lets you publish them without monetising them, but the README asks for a founder's consent before giving them away: ask the team on its Discord before publishing, and nothing commercial. Details: “Before you start: rights and the team's rules”.
This guide as plain text (Markdown), for AIs and offline reading
This is a community guide
A mistake, a pitfall you hit, a tip or a newer tool version: tell us, and every correction will be checked, then added with its source.