Atlas of Bretonnia

Modders' workshop · guide · 53 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. Written against its sources, CAIME 1.0.1's code and documentation, the Assembly Kit on patch 8.1; what 9.0 changed on our project has been added, the rest has not been rechecked point by point. 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.

WordWhat it means
Assembly KitCreative 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, BOBthe 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
RPFMRusted PackFile Manager, the community tool that opens and builds packs: the RPFM guide
Packa .pack archive the game reads; a mod is a pack
Table, keya table of the game's database; each row has a unique key (regions, campaigns…)
ESFa Creative Assembly binary format (map_data.esf, startpos.esf); the acronym is undocumented
Hexone cell of the grid, flat-topped; odd columns shifted up; row 0 at the bottom
Layerone kind of data, one value per hex (regions, ground, roads…)
Swatcha value you paint: a ground type, a region, a climate…
map.hexa map's CAIME project: all its layers
.hex_layera single layer, exported or to import
Process, exportturning the layers into game files (Process menu)
Pathfindingthe movement computation: who can go where, at what cost
Lookupan image where each region has its RGB colour; the game reads which region lies under a point
LoggerCAIME's message window (Ctrl+L)
Slot, sprawla town's place on the grid; the town's footprint around it
Campaign playable areathe map's row in campaign_map_playable_areas: camera limits, minimap files
is_seathe regions column that says whether a region is a sea
bridge-cliffthe land hex touching a bridge; CAIME works it out itself: neither a layer nor a ground type, nothing to paint
Clifffor CAIME, any land hex touching the sea that is not a beach; it works it out itself
Hazardimpassable, rivers and the whole coast (beach or “cliff”): what a town's sprawl must either touch or keep at least 3 hexes away
Province, attritiona group of regions; armies' wear on a terrain
Edge masksix bits per hex telling which neighbours a road, river or border leads to
Startposstartpos.esf, a campaign's starting state, generated by the game; outside CAIME: the tools
The words on the map12345678910A road hex,magnified012345bits 0 and 3: 1the others: 0
  1. Hexa flat-topped cell; odd columns are shifted up; cell (0, 0) is at the bottom left.
  2. Sea regionthe sea is a region like any other, with is_sea = 1 in the regions table.
  3. Region and borderevery hex has its region; the Region Borders layer draws the border (Auto-generate).
  4. Cliffa land hex touching the sea that is not a beach; CAIME works it out. The coast counts, with rivers and impassable, as a hazard.
  5. Beachpainted (Beaches), on coastal land only: the landings.
  6. Bridgepainted (Bridges) on a sea hex, from one shore to the other; the road stops at both shores.
  7. bridge-cliffevery land hex touching the bridge (hatched); CAIME works it out: nothing to paint.
  8. Slotthe town: a 19-hex disk; for a port, 16 main hexes (brown line) and 3 Port hexes (blue line), one of them at sea.
  9. Sprawlthe town's footprint, in ochre: the 19 hexes.
  10. Edge 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).
A map extract drawn for the example, with the guide's words laid on it: the grid, the regions, the coast, a bridge, a port town, a road.

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.

1 · the logical halfIThe databasedeclare map, regions, campaignregionscampaignsIICAIMEpaint the layersmap.hextile_map.pngIIICAIMEvalidate (11 checks)savedTweak and Terry closedproject in raw_dataIVCAIMEexport (Process)map_data.esfpathfinding.ppdborders.pbd<campaign>_lookup.bmp2 · the visual halfVTerryrelief, textures, trees, water<map>.terrytile_map.png ← CAIMEVIBOBa run: the terrainfull_height_map.ddstile_list.binnew map: BOB runs only 6 of its 15 actions3 · togetherVIIRPFMbuild the pack:exports, terrain, tablesmy_mod.packVIIIThe gamegenerate turn 0 (two packs)startpos.esfhlp_data.esfspd_data.esfIXRPFMput turn 0 back in the packmy_mod.packXIn gametest, read the logsfix and repeat: export again, then a new startpos1 · the logical halfIThe databasedeclare map, regions, campaignregionscampaignsIICAIMEpaint the layersmap.hexIIICAIMEvalidate (11 checks)IVCAIMEexport (Process)map_data.esfpathfinding.ppdborders.pbd<campaign>_lookup.bmpsavedTweak and Terry closedproject in raw_data2 · the visual halfmeanwhile: starts from the database (I),gets tile_map.png from CAIMEVTerryrelief, textures, trees, water<map>.terrytile_map.png ← CAIMEVIBOBa run: the terrainfull_height_map.ddstile_list.binnew map: BOB runs only 6 of its 15 actions3 · togetherVIIRPFMbuild the pack:exports, terrain, tablesmy_mod.packVIIIThe gamegenerate turn 0 (two packs)startpos.esfhlp_data.esfspd_data.esfIXRPFMput turn 0 back in the packmy_mod.packXIn gametest, read the logsfix and repeat:export again (IV), then a new startpos (VIII)
The road map. On top, CAIME builds the logical half: paint, validate, then export, once the project is saved, Tweak and Terry are closed and the project sits in raw_data. Below, meanwhile, Terry and BOB build the visual half, from the database and the tile map CAIME exports; for a new map, BOB runs only 6 of its 15 actions. RPFM builds the mod's pack; the game generates turn 0 with it and the start-table pack, then RPFM puts turn 0 back into it. Under each step, the files it produces. Every change means exporting again, then a new startpos.

And each step in detail, under the road map's numbers, with what it produces:

  1. 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…

  2. II–III · CAIME, the layers

    Layers painted or imported, then validated.

    map.hex

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

  4. V–VI · Terry and BOB, meanwhile

    Relief, textures, trees, coasts and water: the terrain the game reads.

    full_height_map.dds, tile_list.bin, global_props.bin…

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

  6. 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. The pack is then rebuilt with these files: in data, the pack wins over loose files. Redo it after every export and every minimap change.

    startpos.esf, hlp_data.esf, spd_data.esf

  7. X · In game

    Start a game, read the logs, fix, repeat.

Before you start: rights and the team's rules§

What CAIME allows, what to ask firstAllowedmodify CAIME's codenon-commercial licence:share-alike, copyrightnotice keptmake your own mapsthe files it produces areyours (EULA 1.1)publish the files itproduces, withoutmonetising themSteam Workshop, Nexus Modsor ModDB (EULA 1.1)Ask first, or don'tgive away the files itproducesREADME: a founder's consent(MrJox, Maruka or Marthenil)any commercial usedonations included,per the READMEanother universe's map ona Warhammer gamestart from Troy or Pharaohanother CA game's modelsyou need your own assetsThe last two: the team's rules,stated on its Discord on 20.09.2026The README and the EULA 1.1 contradict each other.When in doubt, ask the team on its Discord beforepublishing.
CAIME's code is under a non-commercial licence. For the files it produces, the README (a founder's consent before giving them away) and the EULA 1.1 (publishing allowed, without monetising) contradict each other: when in doubt, ask the team. The team stated the last two rules on its Discord on 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§

  1. Install the game's Assembly Kit from Steam (Library → Tools).
  2. Download CAIME from the releases page: the installer is CampaignMapToolkit-win-Setup.exe. v1.0.1 of 23 September 2026 includes two fixes from our workshop: loading the database on any Windows whose decimal separator is the comma, and reading Warhammer I's mini-campaign maps. Updates can be automatic.
  3. 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.
  4. Settings → Preferences (Ctrl+P in CAIME): pick the game first (Base game), then Browse for that game's Assembly Kit. The right folder is assembly_kit: it holds binaries, raw_data and working_data. One path per game.
  5. Still in the preferences: Auto-save writes map_autosave.hex next to map.hex every 5 minutes; Auto-backup stores map_YYYY_MM_DD_HH_mm_backup.hex in backups\ 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.
  6. 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 (for us, 4.2.7): 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.
  7. Read the documentation: twelve detailed guides, from getting started to exporting.
Setting up CAIMESettings → Preferences (Ctrl+P) · diagramPreferencesBase gameWarhammer 3Assembly kit path<game>\assembly_kitBrowseAuto-saveEnabledDisabledAuto-backupEnabledDisabledAuto-backups to keep10Database sourceAssembly Kit1234The game before Browse: one path per game.1assembly_kit\Browse: this folderbinaries\raw_data\working_data\2Auto-save →map_autosave.hexevery 5 minAuto-backup →backups\every 10 minAuto-backups to keep: 0 keeps all; set 10 or 203Assembly Kit: the defaultRPFM: rpfm_cli.exe from a version 4and a Vanilla pack: db.packversion 5 no longer ships it4
In Settings → Preferences (Ctrl+P): the game first, then its Assembly Kit path, the automatic saves and the database source. The path and the source apply the next time a project opens, auto-save at once. A diagram, not a screenshot: only the settings this guide discusses.

Seen in v1.0.0 (20 September 2026), not checked in v1.0.1: the installer shipped neither the templates folder (Templates) nor the MapDataBuilder tool. Check: CAIME looks for that tool in Tools\Release\MapDataBuilder.x64.exe, under the parent of its executable's folder; with the official installer, that is %LOCALAPPDATA%\CampaignMapToolkit\Tools\Release\MapDataBuilder.x64.exe. If it is missing, ask the team first: building the repository takes Visual Studio, with C# and C++ (the solution holds both).

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.

The window and the tools§

With no project open, almost everything is greyed out. Once a map is open, the window has nine areas:

Campaign AI Map EditorFile Edit Process Tools Settings HelpBrush size: 3Image opacity:✕MZBFEILP⚙MinimapSwatchesplainsActionsCreateRenameRemoveValidate…Layers…RegionsAttritionsClimatesGround TypesFinished creating mapX 212 Y 87 · 60 FPS · v1.0.1123456789
  1. The menusFile, Edit, Process, Tools, Settings, Help.
  2. Quick 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.
  3. The 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.
  4. The canvasthe hex map; the brush circle. Wheel: zoom; middle click: pan.
  5. The minimapthe red frame shows the view; a click there moves the view.
  6. The swatchesthe value to paint, in a drop-down list: the database keys for the active layer (here plains).
  7. The actionsthose of the active layer: Create, Rename, Remove (after the database), Cleanup…; Align, Plug Holes or Auto-generate depending on the layer; Validate.
  8. The layersthe tick box makes a layer visible; the round button makes it active. Ground Types is at the bottom, active on opening.
  9. The status barthe last message (a click opens the Logger), X = column and Y = row under the mouse.
Diagram of the usual layout. To paint: pick the layer (8), then the value (6), then the tool (3), and paint on the canvas (4). The Logger (Ctrl+L) gives faulty hexes as Hex(column, row): move the mouse until the status bar (9) shows that X and Y.

The recipe for painting§

  1. In Layers, tick the layer's box (it becomes visible) and click its round button (it becomes active: that is the one you paint).
  2. In Swatches, pick the value: a ground type, a region, a climate…
  3. In the toolbar, pick the tool (table below), set the brush size, and paint.
  4. To check: the status bar gives X (column) and Y (row) under the mouse; Ctrl+Z undoes without limit, one mouse gesture at a time.
KeyToolWhat it does
MPanmove the view (the middle click does it too, whatever the tool)
ZZoomzoom (the wheel too)
BBrushpaint; size 1 = 1 hex, 2 = 7, 3 = 19, 4 = 37
FFlood Fillfill an area; the Source list says which layer acts as the border (Ground Types, Climates, Attritions, Regions, Impassable, Roads, Trade Routes, Restrictions)
EErasererase
IBackground Imagelay a background image (JPG, BMP, TIFF, PNG), stretched over the map: a working sheet, never saved nor exported
LLinea first click (in red), the path shows in yellow, a final click
PColor Pickerpick a hex's value; holding Alt gives a temporary picker
The brush: 1, 7, 19, 37 hexesSize 11 hexradius 0: the clicked hexSize 27 hexesradius 1Size 319 hexesradius 2A Warhammer III townSize 437 hexesradius 3One click paints every hex at most size − 1 steps from theclicked hex. The Brush size slider goes from 1 to 10: 271hexes at most.
The brush size is a radius: size 1 paints the clicked hex, each extra size adds a ring. Size 3 lays, in one click, the 19-hex disk of a Warhammer III town.

Shortcuts worth knowing§

ShortcutAction
Ctrl+N · Ctrl+O · Ctrl+S · Ctrl+Shift+Snew map · open · save · save as
Ctrl+X · Ctrl+Qclose the project (not “cut”) · quit
Ctrl+RReload: reads the database again, and discards anything unsaved
Ctrl+Z · Ctrl+Yundo · redo (no limit)
Ctrl+Shift+R · Ctrl+Shift+Nresize (margins right, left, top, bottom) · rename the map (the database and the folder under raw_data must follow)
Ctrl+L · Ctrl+B · Ctrl+M · Ctrl+PLogger · Border Editor · Map Data Editor · 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§

  1. Design. Sketch, list of regions and provinces, towns, ports, chokepoints (see below). Even width: a requirement of the hex grid, says the documentation, which suggests 1016 × 720 and 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: letters, digits and underscores (CAIME silently strips the rest), and case matters.
  2. Declare the map in the database, with that exact name (Dave, XML by script, or RPFM): see the next section and its column sheet.
  3. Create the project: File → Create new map (Ctrl+N); exact name, Template = None, Game = Warhammer3 (final: the game is baked into the project), even width. CAIME stores the project in its Projects\<map>\ folder; with the official installer, %LOCALAPPDATA%\CampaignMapToolkit\Projects\<map>\. 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).
  4. Put it in its place: right away, File → Save as… (Ctrl+Shift+S) to <Assembly Kit>\raw_data\EmpireDesignData\campaign_maps\<map>\map.hex, then reopen that copy. Map Data and Dynamic Resources only work there (otherwise: “Map Data Process denied”).
Two copies of your projectThe draftCtrl+N creates it hereMap Data: denied here%LOCALAPPDATA%\CampaignMapToolkit\Projects\<map>\map.hexFile → Save as…Ctrl+Shift+Sreopen this copyThe real placethe only place Map Data works<Assembly Kit>\raw_data\EmpireDesignData\campaign_maps\<map>\map.hexthe projectSupport filestrees.png≈ 7.04 × 7.37 px per hextree_database.xmlfrom the prologuedynamic_resources.png≈ 2.54 × 2.40 px per hexdynamic_resources_database.xmlfrom the prologueAutomatic savesmap_autosave.hexevery 5 minbackups\every 10 minmap_YYYY_MM_DD_HH_mm_backup.hexBefore ProcessSavedTweak and TerryclosedProject inraw_dataProcessWhat Process writesone file per export<Assembly Kit>\working_data\campaign_maps\<map>\map_data.esfpathfinding.ppddisplay\borders\borders.pbddynamic_resources.esf<campaign>_lookup.bmp
CAIME creates the project in its own Projects folder: that is a draft. Map Data and Dynamic Resources only accept the copy saved (Save as) into raw_data, with its support files: reopen it and work in that one; Process then writes into working_data.

Filling, validating, exporting§

  1. 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 for trees.png, 2.54 × 2.40 for dynamic_resources.png. trees.png also feeds BOB's trees. Check: the four files sit next to the map.hex, under these exact names.
  2. 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.
  3. 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).
  4. 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 --all chains 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.
  5. Export (Process): Map Data, Dynamic Resources, Pathfinding, Borders, Lookup. Save first; Tweak and Terry closed. Map Data success: “Finished creating map”. Check: in <Assembly Kit>\working_data\campaign_maps\<map>\, dated today, map_data.esf (CAIME treats a file of 10 KB or less as failed), pathfinding.ppd, display\borders\borders.pbd and <campaign>_lookup.bmp. Details: the “Exporting” section.
  6. Meanwhile, the visual half: export the tile map (Tools → Export → Baseline Tilemap image, tile_map.png) for the Terry project, then Terry and BOB.
  7. 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\db\TWaD_<table>.xml).

TableWhat it saysColumns that hold the map together
campaign_mapsthe 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
campaignsthe campaign whose map_name is the map; otherwise the Lookup export refuses (“no campaign uses the map”)campaign_name = my_campaign; map_name = my_map
campaign_map_playable_areasthe campaign playable area: camera limits and minimap files (update it before Map Data if the size changes)mapname = my_map; campaign_key = my_campaign; minx, maxx, miny, maxy; radar_file (the minimap); index, an automatic number
regionsone 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_regionslinks each region to the mapcampaign_map = my_map; region = a key from regions
region_to_province_junctionsone row per region, to its provinceregion; province; is_capital
provincesthe province, if it is newkey
campaign_map_roadsroad costs, per campaignkey; campaign = my_campaign; threshold; movement_cost
campaign_map_areas_of_interestWarhammer III and Three Kingdoms: filtered by map name, otherwise an empty layerkey; campaign_map = my_map
Declaring a mapmy_map: the same name everywhere, case includedcampaign_mapsin the kit onlymapnamemy_mapminx · miny · maxx · maxycampaignscampaign_namemy_campaignmap_namemy_mapwithout it: the Lookup export refusescampaign_map_roadscampaignmy_campaignkey · threshold · movement_costcampaign_map_playable_areasmapnamemy_mapcampaign_keymy_campaignminx · maxx · miny · maxyradar_file · index<mapname>wh3_main_chaos_map_4</mapname><mapname>my_map</mapname>not the last<mapname>wh3_main_combi_map_5</mapname>never the last row: Map Data crashescampaign_map_regionscampaign_mapmy_mapregionmy_regiondifferent case: empty swatchesregionskeymy_regionis_sea · r · g · bunique r g b colour: the lookup uses itregion_to_province_junctionsregionmy_regionprovincemy_provinceis_capitalprovincesif it is newkeymy_provincecampaign_map_areas_of_interestkeycampaign_mapmy_mapGlobal tables, already filledcampaign_ground_types · climates · campaign_map_attritionsCheck: the regions show up in Swatches
Each card is a table from Warhammer III's kit; the dotted line runs from the parent card to the column that links them, and the same label carries the same value. The map's name comes back in five tables, spelt exactly the same, capitals included.

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. Global tables (campaign_ground_types, climates, campaign_map_attritions) are already filled. Region order matters: the exports read land first, then sea, in the order of regions.xml. 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.

654321
  1. Ground Typesground type: plain, forest, mountain, sea
  2. Climatesthe climate: required on every hex
  3. Regionseach hex's region, and its borders
  4. Riversrivers, with their directions
  5. Town Sprawl · Town Slotsa town's slot (19 hexes in Warhammer III; a port: 16 + 3) and its sprawl
  6. Roads · 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
Each layer is a sheet laid over the same grid: for a given hex, one value per layer. The sheets follow the order of CAIME's panel, where the top layer is drawn over the others. Schematic: Warhammer III has fourteen layers, and a town covers 19 hexes.

Warhammer III's layers, with the names the editor shows, in panel order (the top one is drawn over the others):

LayerWhat you paintEffect, tool or action
Impassableforbidden hexesPlug Holes action: fills one-hex holes
Roadsroads, with their directionslower cost (campaign_map_roads); never a ring
Town Slotsthe slots: Main Settlement, Port, Slot 2…see “Towns”
Town Sprawleach town's footprintAlign Town Sprawl/Slot action
Bridgesbridges, on sea hexessee “Bridges”
Riversrivers, with their directionson land only
Beachesbeachesonly on coastal land: landings
Restrictionsgraded movement restrictionscan be lifted by a Lua script
Region Bordersdrawn bordersAuto-generate action
Areas Of Interestareas of interestneeds the campaign_map_areas_of_interest table
Regionseach hex's regionswatches to create (name + Is sea?)
Attritionsarmies' wearswatches to create
Climatesthe climate: required on every hexswatches to create
Ground Typesground 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 validation checks give three levels; here they are as v1.0.1's code assigns them. Error: database/map mismatch (regions, ground types, climates, attritions), invalid index, misplaced bridge, slot on impassable, and the town-sprawl rules. Warning: hex without region, ground or climate, land/sea mismatch, split or empty region, rivers, roads, beaches, slot size… Info: remarks. Fix every mismatch, index and bridge Error before exporting; a sprawl Error on a town in a pass also exists on CA's map (five towns): judge it in game. CAIME does not stop you exporting with Errors (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.

Error, Warning, Infofrom the code of CAIME v1.0.1Errormost seriousFix before exportingDatabase ≠ map: regions, ground types, climates,attritionsInvalid indexBridge on land, impassable or without two shoresTownsSlot on impassable (Impassable check)Sprawl on impassable or outside its regionSprawl in several blocksHazard 2 hexes awayTwo hazard zones touchingWarningworth readingHex without region, ground or climateLand and sea disagreeSplit or empty regionPassable region without a slotSea: more than 9 neighbouring land regionsRiver into the sea; misplaced road or beachMain slot ≠ 19 or 16 hexes; port without seaSprawl without a slotInfoa remarkIsolated hex: road, river, beach, region…Sea: more than 5 neighbouring land regionsThree mutually adjacent road hexes (tight junction)Region without a town, all impassableSlot on impassable (Town Slots check)CA's own map has 5 sprawl Errors:judge in game.validate exits with 2 on a single Warning: read the report.
The eleven v1.0.1 checks sort each message into Error, Warning or Info, and CAIME exports anyway: fix the mismatch, index and bridge Errors, read the Warnings, and judge a town in a pass in game.

Regions§

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. A port town keeps the same disk, split: 16 land hexes in Main Settlement and 3 consecutive rim hexes, sea side, in Port (at CA: two on land, one at sea). The sprawl covers the 19 hexes. The validator counts (19 or 16); 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.

Inland town: 19 hexes11Impassable touching: fine22River 2 hexes away: Error33Impassable 3 hexes away: finePort town: 16 + 3 hexes11Port: 3 rim hexes, 1 of them at sea22Main: 16 land hexes33The sprawl covers the 19 hexes
CA's model: a perfect 19-hex disk (one click of a size-3 brush), whose centre becomes the town's position. Inland town: the whole disk as the main slot (brown line); a hazard (impassable, river, coast) either touches the sprawl or stays at least 3 hexes away, never 2. Port town: the same disk, split between 16 land hexes in the main slot and 3 consecutive rim hexes, sea side, in the Port slot (blue line); the sprawl (ochre) covers the 19 hexes.

Rivers and bridges§

A bridge, seen from aboveRoadShore: worked out by CAIMESea, painted BridgesSea, painted BridgesShore: worked out by CAIMERoadRiver crossed: a crossingpenaltyBridge on a Rivers line:Error
A bridge spans water painted as sea, from one shore to the other: paint Bridges on those sea hexes and lead the road to the shore; CAIME itself marks the shore hexes touching the bridge (bridge-cliff, hatched): nothing to paint. A Rivers line lies on land and is not bridged: a bridge on land is an Error. Warhammer III's database even has a sea ground type for waterways, sea_river.

Networks: trees, never rings§

Roads, rivers and trade routes form trees, with dead ends. A ring (a circuit with no end at all, such as a road looping around a province) makes the export run forever: that is the real danger, since nothing cuts it for you. Erasing a single hex is enough to cut it. The documentation also forbids the triangle of three mutually adjacent hexes; for roads and rivers, CAIME already drops one edge of every triangle when it computes their masks, but avoid it anyway.

A treea junction, dead endsA ringthe export never endsThe ring, cutone hex erased: two dead endsA trianglethree mutually adjacent hexes
Roads, rivers and trade routes: a tree, with dead ends. The ring (a circuit with no end) is the real danger: the export runs forever, and CAIME never cuts it; erasing a single hex is enough. The documentation also forbids the triangle of three mutually adjacent hexes; for roads and rivers, CAIME already removes one of its edges when it recomputes the links. A tight junction (three mutually adjacent road hexes) forms that triangle: CAIME flags it as an Info.

Designing a map that plays well§

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.

After an edit, what to redo?first validate and save; then re-export:Repaintthe database does not changeAlwaysGround types, attritions,impassable, restrictionsMap DataPathfindingRoads, rivers, beaches, bridges,slots and sprawlsMap DataPathfindingClimatesMap DataRegion shapes (the Regions layer)Map DataBordersPathfindingLookupCreate, rename, deletethe database first, then the Actions buttonA ground typeMap DataPathfindingA climate, an attrition, an area of interestMap DataA regionall exportsResize (Ctrl+Shift+R)the playable area first, in the databaseNew hexes are emptyall exportsThen, alwaysRebuildthe packRegeneratethe startposRebuild itwith the startposWhen in doubt, rerun everything: only Borders and Lookup,purely visual, can be redone alone.
Each edit means rerunning the exports of what it touches, and always Map Data (the gold column); creating, renaming or deleting goes through the database first. Then always come the pack, a new startpos and the rebuilt pack.
ChangeDatabase?Exports to rerun
Repaint ground types, attritions, impassable, restrictionsnoPathfinding, Map Data
Repaint roads, rivers, beaches, bridges, slots and sprawlsnoPathfinding, Map Data
Repaint climatesnoMap Data
Region shapes (repaint Regions)noBorders, Pathfinding, Map Data, Lookup
Create, rename or delete a ground typeyes (campaign_ground_types)Pathfinding, Map Data
Create, rename or delete a climate or an attritionyes (climates, campaign_map_attritions)Map Data
Create, rename or delete an area of interestyes (campaign_map_areas_of_interest)Map Data
Add, rename or delete a regionyes (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§

Process: each export and its filesSavedfirstTweak and TerryclosedProject inraw_datafor Map Dataand Dynamic resourcesProcessMap DataPathfinding dataBorders dataDynamic resourcesTrade RoutesLookup andMinimap images<Assembly Kit>\working_data\campaign_maps\<map>\map_data.esfsuccess: the message"Finished creating map"10 KB or less: failedpathfinding.ppdthe docs wrongly say .binborders.pbdin display\borders\its window: default boxesdynamic_resources.esfcrashed for uson Warhammer IIItrade_routes.ptdthe layer does not existin Warhammer III<campaign>_lookup.bmpa single image, no minimap;the game reads.tga, .dds, .png
Each Process menu entry writes its file, and they all land in the same working_data folder. Map Data and Dynamic resources want a saved project, in its raw_data place, with Tweak and Terry closed (the padlocks).
ExportFile produced
Map Datamap_data.esf
Pathfindingpathfinding.ppd (the “Processing & Exporting” page wrongly says .bin)
Bordersdisplay\borders\borders.pbd
Dynamic Resourcesdynamic_resources.esf
Trade Routestrade_routes.ptd (games that have this layer; not Warhammer III)
Lookupfor 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>\working_data\campaign_maps\<map>\. 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 as SVG, 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.

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
One command, piece by pieceCAIME.exe process -m <map.hex>--map-data --pathfindingCAIME.exeThe program; with noarguments, it opensthe editorprocessThe verb:process exports,validate checks-m <map.hex>The map: --mapor its short form -m--map-data --pathfindingThe tasks: one flagper export, or --all aloneExit codes0success1invalidarguments2failurevalidate exits with 2 on a single Warning, even on CA's maps:read the report.--all includes Dynamic Resources (a crash for uson Warhammer III): list the tasks--map-data --pathfinding --trade-routes--lookupand Borders from the Process menu
A command line reads in pieces: the program, the verb, the map, then the tasks. The exit code tells whether it all worked; read the report anyway.

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.

06121817131928142039152141016225111723Row 0Row 1Row 2Row 3012345Columnindex = row × width + columnThe .hex_layer fileone byte per hex (two for regions)id (4 bytes)0123456…23012345Edge maskBit 0 = north
CAIME's grid: row 0 at the bottom, odd columns shifted up, hexes read row by row from the bottom left; a .hex_layer file starts with a 4-byte id, then one byte per hex. The six bits of an edge mask (roads, rivers, borders) follow the sides, 0 at the north.
IdLayerValue on disk
0Impassable1 = passable, 0 = impassable (in the file; in the editor, painting Impassable makes the hex impassable)
1, 2, 6Trade Routes, Roads, Riversthe edge mask (six bits)
3Town Slotsindex + 1: 0 = none, 1 = main (Main Settlement), 2 = Port, 3 = Slot 2… up to 12 (indices 0 to 11)
4, 5, 7Town Sprawl, Bridges, Beaches1 = yes; any other value means “no”
8Region Bordersthe edge mask (six bits)
9Regionstwo bytes: v × 8 in little-endian, with v = index + 1 (first byte = (v × 8) mod 256, second = v ÷ 32)
10, 11, 12Attritions, Climates, Ground Typesindex + 1
13, 14Restrictions, Areas Of Interestno format: neither import nor export of a .hex_layer

Our method: a painted image (one colour = one value) and a legend → one .hex_layer per layer → import into CAIME (in the official version, 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.

From image to .hex_layerAn image, north upone pixel per hex, one colour per valueNStart from the bottom: row 0the file begins with the image'sbottom rowrow 0One colour, one valuethe layer's legend; here, Roadsroad → 1none → 0Write the bytesHeaderOne byte per hex02000000010100000000…2 = Roadsrow 0 firstexact size: 4 + W × H bytes, or it is refusedRegions: 2 bytes per hex, so 4 + 2 × W × HTools → Import → Layer dataRoads: only presence counts;CAIME redoes the directionsCheck, then validateTools → Export → Layer data:the PNG comes out north up;compare it with the drawing,then run Validate=drawingPNG123456Encodings that biteImpassable (0)1 = passable, 0 = impassableRegions (9)two bytes: v × 8, with v = index + 1v = 5 →2800v = 40 →4001Town Slots (3)0 = none · 1 = main · 2 = PortRestrictions (13), Areas Of Interest (14)no .hex_layer file
A layer by script: the painted image, read from the bottom row, translated through its legend, written byte by byte after a 4-byte header; then the import, the PNG export to compare it with the drawing, and the validation.

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:

From Warhammer I to Warhammer IIICAIME 1.0.1 opens Warhammer I's mini-campaign mapsWarhammer IWarhammer IIITowns7 hexesport: 419 hexesport: 16 + 3Grow each slot into a disk around its centre, then redo the sprawlsGround types and climates13 land ground types24 climates15 land ground types40 climatesRe-match the indices by name, never by numberFaction keyswh_dlc05_brt_mini_bastonnewh_main_brt_bastonneSame culture (brt), same end of key (bastonne): never the prefixThe minimapradar_filefrom the original rowThe same name,checked in the packA column that names a file is checked against the pack's contentsWarhammer I files: never published, they belong to CA.
Porting a map is mostly re-matching: towns as 19-hex disks, ground types and climates by name, faction keys on the culture and the end of the key; the file names of the original row are kept. And nothing from Warhammer I gets published.

The full story: the porting tutorial and the nine walls of the port.

The pitfalls that cost us the most§

Where the traps bite1The databaseA different case in the name: empty swatchesThe map as the last row ofcampaign_map_playable_areas: Map Data crashesNo campaign cites the map: Lookup refusesRenaming the map (Ctrl+Shift+N): the database and thefolder must follow2The project in CAIMEThe project's game is finalReload (Ctrl+R) throws away anything unsavedCtrl+X closes the projectThe background image is never savedResizing does not scale the drawing3The layers, painted or scriptedA ring with no end: the export runs foreverA .hex_layer starts from row 0, at the bottomImpassable = 1 means passableIndices are matched by name, never by number4ProcessTweak or Terry open: close bothSupport files missing: Map Data failsDynamic Resources: a crash for usThe Map Data Editor refuses Warhammer III5The startposEvery export needs a new startposThe exported map_data.esf in ESF 0xABCB: generationcrashed, on one projectThe documentation contradicts itself in places: trust thevalidator and the disk.
The guide's main traps, at the step where they bite: the database, the project, the layers, Process, the startpos. The details, and the reasons, in the list below.

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), then reviewed for update 9.0: check them again after an update.

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 (Ctrl+P), and that the map name in campaign_map_regions matches yours exactly, capitals included. 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\EmpireDesignData\campaign_maps\<map>\map.hex), 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 (with the official installer: %LOCALAPPDATA%\CampaignMapToolkit\Tools\Release\MapDataBuilder.x64.exe).

Why does the export run forever?

Most often a ring: a circuit of roads, rivers or trade routes with no end at all. Cut it by erasing one hex. The documentation also names the triangle of three neighbouring hexes; for roads and rivers, CAIME already drops one of its edges when computing their masks.

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

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 without limit.

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. A port town keeps the same disk, split: 16 land hexes in Main Settlement and 3 consecutive rim hexes, sea side, in Port (at CA, two on land and one at sea). The sprawl covers the 19 hexes. The validator only counts 19 or 16; 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; the documentation 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?

CAIME: code under a non-commercial licence. Files it produces: the README asks for a founder's consent before giving them away, the EULA 1.1 lets you publish them without monetising them; when in doubt, ask the team before publishing; nothing commercial.

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.

Suggest an idea
↑ Contents