Atlas of Bretonnia

Modders' workshop · guide · 54 min read

BOB, the guide: building terrain and packs with the Total War: Warhammer III Assembly Kit

BOB is the Assembly Kit's builder: it turns what you prepared in Terry and in the kit's database into files Total War: Warhammer III can read. This guide explains its window, its recipes (the rules.bob files), how to launch it, where to read what it did, and the pitfalls that cost us hours while porting a campaign map from Warhammer I to Warhammer III.

Reviewed on 25 September 2026, update 9.0. Checked against the Assembly Kit on patch 8.1, CA's wiki and tw-modding. 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 BOB does§

BOB is the builder of the Assembly Kit, Creative Assembly's official kit (Steam → Library → Tools). It is not for drawing: it transforms. It takes the sources stored in raw_data (the database tables, Terry's terrain projects) and derives the game's files from them, which it writes to working_data; it can also gather them into packs. The tw-modding wiki's Beginner's Guide expands its name as Build-on One Button.

Why this compulsory step? Because the game does not read working formats. A relief painted in Terry is a .tif image; the game wants compiled maps (.compressed_map, .dds, .bin). A table edited in Dave, the kit's database editor (CA writes it DaVE; the Steam launcher says Database Editor: Dave), is an XML file; the game wants its tables in its own format. BOB does the translation.

The diagram below follows a battle map from source to game: the Terry project (the tile map and the tile) in raw_data, BOB and its rules.bob files, the game's files in working_data, then the two routes to a pack: RPFM, the proven one, or a BOB rule, which we have not proven in Warhammer III.

raw_data · your Terry projectTerryterrain/battles/<map>/ (tile map)terrain/tiles/battle/<tile set>/<tile>/ (tile)the tile map (the frame), then the tile (what you paint)Process with BOB (Ctrl+P)the tile map, then the tileBOBreads the rules.bob fileslogs: binaries/bob*.logworking_datatile_map.bmd · tile_list.bin · blend0.dds …the game's files, under the same paths as in raw_data; padlock:an open Terry locks working_data, except for the BOB it startsitself[Pack] rule?[Pack] ruleunprovenin Warhammer IIIprobably in the kit:retail/data/copy by handadd thefolderRPFMthe proven routeworking_data/terrain/without the example mapbattles_tablesyour row, text, imageThe gamedata/ → launcher→ custom battle
A battle map from source to game: Terry has BOB process the tile map, then the tile; BOB follows the rules.bob files and writes the game's files under the same paths, in working_data. The pack is made with RPFM, the proven route; a BOB [Pack] rule would probably put it in the kit's retail folder, a route we have not proven in Warhammer III.

BOB lives in the kit's binaries folder: bob.modder.x64.exe. It opens from the Steam launcher, from its executable or from Terry: see “Opening BOB and giving it work” below. It is made of modules, one per trade; the Warhammer III kit ships, among others, bob_terrain, bob_tile, bob_vegetation, bob_texture, bob_campaign, bob_dbexport, bob_localisation, bob_lua, bob_pack and bob_files.

What BOB does not do: the logical half of a campaign map (regions, roads, pathfinding). That is the job of CAIME (Campaign AI Map Editor), the Campaign Map Toolkit's editor: see the CAIME guide.

Vocabulary§

WordMeaning
raw_datathe sources: what the kit's tools read (database XML tables, Terry projects, images)
working_datawhat BOB produces: files in the game's format, mostly stored under the same path as their source (see “What BOB produces”)
Kit databasethe XML tables in raw_data/db, edited with Dave
Game databasethe one in CA's packs; for a campaign map, it is the one that counts (see “BOB and a campaign map”)
Nodea folder or file in one of the trees of BOB's window
Actiona job BOB can do on a node; each node offers several
Processorthe part of BOB that does one kind of job; bob.log names it in front of each action
Runone execution of BOB, from launch to exit code
Rulea section of a rules.bob, with its Key = value settings; each section sets up one processor
rules.boba text file of rules placed in a folder; it applies to that folder and those below, unless a closer rule takes over
Packthe .pack archive the game reads; a mod is one
<retail>a reserved word in rules.bob files that stands for a destination folder; see below what we know about it
LogBOB's .log files, in binaries, rewritten on every run

Opening BOB and giving it work§

The Assembly Kit installs through Steam (Library → Tools). On a Steam installation, it sits in <Steam>/steamapps/common/Total War WARHAMMER III/assembly_kit/; BOB and its logs are in its binaries folder. The game, for its part, reads packs from <Steam>/steamapps/common/Total War WARHAMMER III/data/.

BOB opens in three ways: from the Assembly Kit's Steam launcher (Exporter: BOB), from its executable bob.modder.x64.exe, or from Terry (Process with BOB, Ctrl+P). Opened from Steam or from its executable, BOB shows its window and waits for you to pick its work (see “BOB's window”, right after). Opened by Terry, it works in the background, and its messages appear at the bottom right of Terry.

Three doors into BOBSteam launcherof the Assembly KitExporter: BOBwhich passes-no_consoleIts executablein the Assembly Kitbinaries/bob.modder.x64.exeTerryin its File menuProcess with BOBor Ctrl+Phands it the workBOB: its windowBOB - Select Data Files To BuildA nodeAn actionStartit waits for you to pick its workbefore Start: Terry and the game closedIn the backgroundMessages at Terry'sbottom rightA new BOB each timeBeyond its launchers' commands (-no_console; Terry's): -h, --helpor -help open "Illegal option format", which blocks BOB. Don't tryit on Terry or Tweak either.
BOB opens from the Assembly Kit's Steam launcher (Exporter: BOB), from its executable or from Terry. The first two doors open its window, where you pick its work; Terry, for its part, hands BOB the work, and each Process with BOB starts a new BOB.

From Terry§

How to check it worked. Follow the messages to the end, then read bob.log: see “BOB's logs” below.

From BOB's window§

Tick the node, pick the action or <All>, then Start: the details are in “BOB's window”, right after. Three typical uses:

JobNode and actionWhat to know
Export the databasedatabase node → <All>for us (20.09.2026, patch 8.1): 3,788 actions in 109 seconds; one folder per table in working_data/db/ (1,694), each with a data file. Useful when a tool wants the database in the game's format: see “Exporting the kit's database” below
Textsthe Retail Pack optiondescribed on the tw-modding wiki's Localisation page (written for several games; in 2019 it reported this feature disabled in the Warhammer II kit); not checked in Warhammer III. For a mod's texts, the recommended route is RPFM (the RPFM guide)
The startposcampaigns node in the Working Data column → Campaign / Process start pos (<campaign>)this action launches the game; for us (20.09.2026, patch 8.1), it failed (“Startpos file not found after running the game!”); at the same date, generation also failed for a CA campaign started another way. The three startpos routes: RPFM's Build Startpos, BOB's Process start pos action, or a hand-written user.script.txt. For us, only the hand-written route worked: the tools guide

Before running BOB from its window, or saving a pack into working_data, close Terry and the game: an open Terry locks working_data (packs placed there, in particular). Process with BOB, run from Terry, is not affected. This rule holds for the whole guide.

How to check it worked. The actions are green, bob.log ends with Exit code: 0, and the expected files have appeared with the run's date.

The command line§

BOB has no command-line help; two official command lines are known, those of its launchers: -no_console (Steam launcher) and the one Terry passes to it. The kit's Steam launcher offers three options:

Steam launcher optionProgram launched
Exporter: BOBbinaries/bob.modder.x64.exe -no_console
Battle Map Editor: Terrybinaries/tweak.modder.x64.exe /standalone TerrainMetadataEditor
Database Editor: Davedave/DaVE.retail.x64.exe, no option

Terry, for its part, launches BOB with a longer command (recorded on 21.09.2026, patch 8.1):

BOB.modder.x64.exe /dont_stop_on_error /nosplashscreen /get_latest_rules -no_console /offline /configuration:_terry_auto /workspace: "/changelist:Terry (<project path>.terry)"

/configuration:_terry_auto names the file binaries/BOB/_terry_auto_configuration.xml, which Terry writes: that file tells BOB what to build (processors, folders, wanted outputs). So the command line does more than open BOB: with /configuration:, it also gives it its work.

For repetitive work, prepare the rules.bob files and the data by script, then start the run with one click on Start, or from Terry.

BOB's window§

Opened from the Steam launcher (Exporter: BOB) or from its executable, BOB displays a window titled BOB - Select Data Files To Build. It shows Raw Data (the sources) and Working Data (what is already built); a third tree, Retail Data, shows the kit's retail folder (with assembly_kit and data in it).

A right-click on a node opens a menu of three entries: View rules, View actions and Select files only. View actions opens a small “BOB” window: the node's two lists of actions, described below. We recorded this window and this menu on screen on 24.09.2026.

BOB - Select Data Files To BuildRaw DataWorking DataRetail Datadatabaseassembly_kitdataBOBProvider actionsMerge ActionsConsumer actionsMerge Actions<All>+ dependenciesCampaign / Build Queried Campaign TablesCampaign / Export XML (…)Campaign / Export XML (…)Startclick elsewhere, no action:unticked, without a messageafter Start, each actionturns green once it is donethen: bob.log123456789
  1. The titleBOB - Select Data Files To Build: the window BOB shows when opened from the Assembly Kit's Steam launcher (Exporter: BOB) or from its executable, bob.modder.x64.exe.
  2. Raw Datathe tree of sources, those in raw_data; a node is a folder or a file.
  3. Working Datathe tree of what is already built, in working_data.
  4. Retail Dataa third tree, which shows the kit's retail folder (with assembly_kit and data in it).
  5. The actions windowa small “BOB” window, opened by ticking a node (here database); a right-click on a node offers View rules, View actions and Select files only, and View actions opens it too. Two lists, Provider actions (empty for database) and Consumer actions, each with a Merge Actions box.
  6. <All>at the top of Consumer actions: all the actions; BOB adds by itself what they depend on (the Database Export node). A single action may produce nothing: Build Queried Campaign Tables alone gives 0 files.
  7. The traptick a node, then click elsewhere without picking an action: it unticks, without any message, and Start will do nothing for it.
  8. Startbottom right; each action turns green once it is done. Database export, for us: 3,788 actions in 109 s.
  9. bob.logthen, in binaries: the number of actions on the first line, one STATUS line per action (Finished when it is done, Failed if it failed), then Exit code: 0.
Schematic: the trees and the actions window as recorded on screen on 24.09.2026, laid out schematically. To export the database: tick database, which opens the actions window (5), pick <All> at the top of Consumer actions (6), Start (8), then read bob.log (9). For a battle map you don't open this window: Terry launches BOB itself (Process with BOB, Ctrl+P).
  1. Tick a node. Its actions show up in two lists: Provider actions and Consumer actions, each with a Merge Actions box. For the database node, the first one is empty.
  2. Pick an action, or <All>, at the top of Consumer actions, to take them all. With <All>, BOB adds by itself what they depend on (for example the Database Export node).
  3. Repeat for each node to process.
  4. Click Start, bottom right. Each action turns green when it is done.

How to check it worked. Every chosen action is green. Then read bob.log: see “BOB's logs” below.

Why so many precautions? Because BOB does not always report what it did not do. A run can end without an error and without producing the file you expected. Hence this guide's rule: after every run, check.

What BOB produces§

For terrain, a BOB output keeps its source's path, under working_data instead of raw_data. A battle tile map stored in raw_data/terrain/battles/my_map/ therefore comes out in working_data/terrain/battles/my_map/. That is how you find what a run wrote.

Example: the example battle map shipped with the kit (assembly_kit_example_tile_map and its tile assembly_kit_example_tile) gives:

Where BOB writesFor terrain: the same pathraw_data/terrain/battles/my_map/a BOB runworking_data/terrain/battles/my_map/the same pathtile_map.bmdtile_list.binmap_info.xml…Three exceptionsThe database exportone folder per table, with a data file insideworking_data/db/<table>_tables/dataand also, into raw_data, start_pos_… tables and a .pack:raw_data/EmpireDesignData/campaigns/<campaign>/[Copy]→ <retail>/…for us:assembly_kit/retail/…[Pack]?→ <retail>/data/its pack;unproven in Warhammer IIIBOB rewrites its outputs on every runA hand edit in working_data vanishes on the next run:fix the source.A fresh output carries the date of the run.
For terrain, a BOB output keeps its source's path, under working_data instead of raw_data: that is how you find what a run wrote. Three exceptions: the database export, and the [Copy] and [Pack] rules, which write under <retail>.
Output folderFiles
working_data/terrain/battles/<map>/: the tile maptile_map.bmd, tile_list.bin, lf_normal.dds, full_lf_logic_map.compressed_map, map_info.xml
working_data/terrain/tiles/battle/<tile set>/<tile>/: the tiletile_height_map.compressed_map, blend0.dds, bmd_data.bin, the grass and tree lists

For a campaign, BOB's outputs go to working_data/terrain/campaigns/<map>/ (relief, logic map, tiles, masks, global_map/). The working_data/campaign_maps/<map>/ folder receives CAIME's files, camera_heightmap.png, which BOB cannot make (see “BOB and a campaign map” below), and the tree list BOB writes there (Campaign Trees action: display/trees/trees.campaign_tree_list): put it in your pack, or the map has no trees.

Three exceptions to the same-path rule:

Two practical consequences:

How to check an output is new. Look at its modification date: it must be the run's. An older file comes from a previous run, and your change was not built.

BOB's logs§

BOB writes its logs to the kit's binaries folder, next to its executable. They only keep the last run: each run wipes the previous one. To compare two runs, copy the logs elsewhere before the next run.

LogWhat you read there
bob.logthe main log. Its first line announces the number of actions selected (N action(s) were selected for execution.); then come one === Processor / Action (…) (STATUS: …) === line per action, the durations (All actions took … msecs), then the exit code (Exit code: 0 on our successful runs, Exit code: 1 when an action failed; the actions that depended on it are then marked DependencyFailed)
bob_warnings.logthe warnings, including the “Failed to find tile”: read it after every terrain run
bob_error.logthe errors, including the message of an action that failed (for example “prefab root …”, see “Messages to know”)
bob_plugin_error.log“Couldn't create all processors…” on every run launched by Terry, with no effect on the terrain
bob_startup_error.log, bob_db.logthe other logs, described by their names

Reading a run in three minutes§

Reading a run in three minutesbob.login binaries/: the last run onlyN action(s) were selected for execution.1=== Terrain / Terry file (…) (STATUS: Finished) ===2Duration: … msec(s)=== Terrain / Tilemap (…) (STATUS: Finished) ===…All actions took … msecsExit code: 011The first line announces N actions; Exit code: 0 must endthe log (Exit code: 1: an action failed).2One STATUS line per action, Finished when it is done(FinishedWithWarnings or Failed flag a problem): you need N.3bob_warnings.log: the Failed to find tile, to be counted.4When in doubt: the other logs in the folder, bob_error.logincluded.bob_warnings.log3Failed to find tile for 'points …', …Failed to find tile for 'points …', …Failed to find valid quadtree node …each Failed to find tile is a hole in the terrain: aim for 0quadtree: an object left out, its pivot is off the mapbob_plugin_error.log4Couldn't create all processors,check that BOB has been built.known: it shows up on every run launched by Terry, with no effect on theterrainExit code: 0 + N STATUS: Finished lines+ 0 Failed to find tile = successCampaign map: Exit code: 0, but only 6 actions(the Terry file and 5 masks) instead of a dozen:the kit's limit; run a control case
Schematic extracts. After every run, in binaries: bob.log (N actions announced, one STATUS: Finished line per action done, Exit code: 0), then bob_warnings.log. The logs only keep the last run.
  1. Open bob.log. The first line says how many actions were selected; the last one must say Exit code: 0.
  2. Count the STATUS: lines: you need one per announced action. Finished: done. FinishedWithWarnings: done, but read bob_warnings.log. Failed: failed; the run then ends with Exit code: 1, and bob_error.log says why. DependencyFailed: not done, because an action it depends on failed; look for the first Failed. Compare with the number you expected too: an incomplete run shows up here, even without an error.
  3. Open bob_warnings.log and count the “Failed to find tile”: each one is a hole in the terrain (except on the last row of a campaign's battle terrain, outside the grid and harmless: 1 for us on the Season, 3 on Expanded).
  4. At the slightest doubt, open the other logs in the same folder.

So Exit code: 0 is not enough on its own: count the actions too. We recorded the first three statuses on 22.09.2026, on patch 8.1, and DependencyFailed on 03.10.2026, on patch 9.0.2.

Messages to know§

Five messages come up often. The “Where” column says which log to look in:

MessageWhereWhat it meansWhat to do
Failed to find tilebob_warnings.logNo tile in the tile database matches the pattern in tile_map.png at that spot: an old road too thin, a one-hex coastal spike… Result: a hole in the terrain.For a campaign, fix the CAIME layers, re-export tile_map.png, rerun BOB and recount (the Terry guide). For a battle map, review its tile map. Aim for zero, except on the last row of a campaign's battle terrain, outside the grid and harmless.
Wrong size, expecting W×Hbob_error.log (and bob.log)A .tif raster of the project does not have the size declared in the .terry: its action ends as Failed, the following ones as DependencyFailed, and the run with Exit code: 1 (03.10.2026, patch 9.0.2).Remake the raster at the size given in the raster table of the Terry guide, or fix the declaration, then rerun.
Failed to find valid quadtree nodebob_warnings.logAn entity (a placed object, a water plane…) has its pivot outside the map. BOB drops it: it is missing from the built files.Bring the pivot back inside the map, in Terry, then do a new run.
Couldn't create all processors, check that BOB has been built.bob_plugin_error.logA requested processor is missing from the kit.Nothing, if the rest of the run completes: we see it on every run launched from Terry, with no effect on the terrain.
prefab root … does not have a valid TargetPathbob_error.log (and bob.log)The Generate Tile Map BMD action ends as Failed, with no tile_map.bmd: the raw_data/art/prefabs/battle/ folder, whose [Prefab] rule carries the TargetPath key, was not part of the run.Bring that folder into the run. For us (22.09.2026, patch 8.1), it was missing from the folder list (the <directories> tag) of a BOB configuration file we had written ourselves; adding it was enough.

For a campaign map, a “Failed to find tile” means BOB could not match a pattern in CAIME's export to a tile. Fix the CAIME layers and re-export; do not retouch tile_map.png by hand (only exception: up to CAIME 1.0.1, the image comes out upside down and is flipped vertically; since 1.1.0 it comes out north-up). Known patterns without a tile: a coast on row 0, the last row or the last column of the grid; a one-hex isthmus where two cliffs cross; and the cliff ends (cliff_gen_ends) CAIME puts around every beach: bound to the beach, they leave a hole on the cliff side (CA's Immortal Empires map has only 36 for 412 beaches; on our Saison Expanded map, we repaint them as cliff_gen, a departure we own). The diagram comes from the Terry guide.

CAIME export: sea, coast, roadstile_map.png: 1 hex = 2 × 2 pixelsThe seasea · 83, 141, 213yellow: the coast(see below)0water plane at 0, pivot inside the map;seabed below 0 wherever there is seaThe coast exported by CAIMECAIME export: coast in wholehexessea spit:"Failed to find tile", a holesea_coast · 255, 255, 0cliff_gen · 253, 3, 1cliff-beach transition: cliff_gen_ends (84, 230, 84).If BOB finds a hole, fix the layers in CAIMERoadsCAIME export: 2 × 2 blockper hexold manual retouch: holesAfter each BOB run, count the "Failed to find tile" linesin bob_warnings.log: aim for 0.Export from CAIME, without manual painting or retouching.
For a campaign map, export tile_map.png from CAIME without painting or retouching it. Sea uses its own colour, coasts and roads occupy whole hexes, and the seabed stays below 0 wherever there is sea. If BOB cannot find a tile, fix the CAIME layers and re-export.

And no message is a message too: for a campaign map the game's database does not know, BOB runs only 6 actions instead of a dozen, without a word. See “BOB and a campaign map” below.

Step by step: three typical jobs§

Three typical jobsBuilding a battle mapin Terry, without opening BOB's windowthe tile mapRun 1: Ctrl+P,then reload itbob.logRead it beforethe next runthe tileMap Properties: legacyvegetation off; run 2: Ctrl+Pbob.logRead it right awayCheck after every run: Exit code: 0, as manySTATUS: Finished lines as the first line announcesactions; 0 "Failed to find tile" in bob_warnings.log.Exporting the kit's databasefirst: Terry and the game closeddatabase → <All>In BOB'swindowStartEverythingturns greenworking_data/db/One folderper tableCheck: Exit code: 0; one folder per table, with its datafile, dated from the run (1,694 for us).Building a packtwo routesRPFMThe proven routeor[Pack] rule?Unprovenin Warhammer IIICheck: open it in RPFM; terrain/battles/<map>/ and thetile, nothing else (neither the example map nor a .pack).
Three typical jobs, each with its check: a battle map (Terry launches BOB), the database export (in BOB's window) and the pack (RPFM, the proven route; BOB's [Pack] rule is unproven in Warhammer III).

Building a battle map§

Painting, zones and creating the tile map are in the Terry guide. Here is BOB's part.

  1. Save, then open the tile map (the project in raw_data/terrain/battles/<map>/) and run File → Process with BOB. Reload it afterwards to check.
  2. Reopen the tile. In Map Properties, untick legacy vegetation generation, then Process with BOB.
  3. Remember the order: the tile map always comes before the tile. After that, when you touch up the tile, only the tile needs re-exporting.
  4. Pack it with RPFM, the proven route: working_data/terrain (without the kit's example map), a row in battles_tables whose specification is terrain/battles/<map>/ (trailing slash included), a text and an image: see the Terry guide.
  5. Put the pack in the game's data/ folder with a square thumbnail of the same name, enable it in the launcher, and test through Custom Battle.

How to check it worked. After every run, since the logs only keep the last one:

Exporting the kit's database§

Why: your tables edited in Dave are XML files in raw_data/db; the export writes them in the game's format, one folder per table in working_data/db/. This is useful when a tool wants the database in the game's format (for us, for the startpos). For a mod, it is not what you pack: see the box below.

  1. Close Terry and the game.
  2. Open BOB from the Steam launcher (Exporter: BOB) or from its executable (bob.modder.x64.exe, in binaries).
  3. Tick the database node and pick <All>: BOB adds the dependencies by itself, such as the Database Export node.
  4. Click Start, and wait until everything is green. For us (20.09.2026, patch 8.1): 3,788 actions in 109 seconds.

How to check it worked. bob.log ends with Exit code: 0, and working_data/db/ holds one folder per table, with its data file, dated from the run (1,694 for us, on 20.09.2026, patch 8.1). The export also writes, for each campaign, starting-position tables (start_pos_…) and one .pack in raw_data/EmpireDesignData/campaigns/<campaign>/: don't be surprised to find them there.

Building a pack§

Two routes lead to a pack, and the diagram at the start of this guide shows them side by side:

How to check it worked. Open the pack in RPFM, which shows what it holds. It must hold your files under the path the game expects (for a battle map, terrain/battles/<map>/, the one battles_tables cites), and nothing else: neither the kit's example map nor another .pack. Finally, check that it is in the game's data/ folder.

rules.bob files: BOB's recipes§

BOB does not decide on its own what to do with a file. It follows rules, written in text files called rules.bob and placed in raw_data and working_data folders. A rule says, for example, where to look for a terrain's prefabs, or which pack a folder goes into.

For a battle map made in Terry, you don't have to write any: the tw-modding tutorial has you write none, the kit's own are enough. This section is for understanding what BOB does, and for writing your own rules.

The syntax§

How BOB finds a file's rule§

  1. BOB looks for a rules.bob in the folder of the file it is processing, and checks whether one of its rules targets that file, filters included.
  2. If not, it climbs up one folder, and tries again.
  3. The first rule that applies wins. If it reaches the top without finding one, it uses its defaults.

A local rule can replace the one above, or only complete it. It all comes down to one sign:

Written asEffect
[Name]replaces the inherited rule entirely: a key you don't copy over is gone
[+Name]keeps the inherited rule and only changes the keys listed

The diagram below follows three files in working_data: each climbs the folder tree up to the first rules.bob that applies, and that rule decides which pack it goes into.

Each file climbs to the first rules.bobworking_data/rules.bob[Pack] <Files> = -*.packPackFile = <retail>/data/mod.packdb/land_units_tables/datamod.pack(CA's default; an exported table is not published as is)terrain/battles/my_map/rules.bob[Pack] PackFile = <retail>/data/my_map.packBasePath = /tile_map.bmdmy_map.packtiles/battle/<tile set>/<tile>/rules.bobthe same rule, to my_map.packblend0.ddsmy_map.pack[Pack] replaces the inherited rule; [+Pack] onlychanges the keys it names.-*.pack excludes; * matches any character but /, so itdoes not cross folders; ... does.
BOB looks for a rules.bob in the file's folder, then climbs folder by folder: the first rule that applies wins. Here, a table goes into mod.pack; the tile map and the tile, which carry the same rule, go together into their own pack, like the kit's example map.

How to check a rule applies. After the run, check that the effect the rule announces took place (for example, the pack the files went into). If not, a rule closer to the file may have won: look for it by climbing its folders.

The kit's rules.bob files, line by line§

Nothing beats real rules. The first four files ship with CA's kit; the last one is a model, based on the example map, for the [Pack] route, unproven in Warhammer III. Each block can be copied as is; the numbered notes below explain it line by line.

First file: working_data/rules.bob§

[Pack]
    <Files> = -*.pack
    PackFile = <retail>/data/mod.pack
    PackType = mod
  1. <Files> = -*.pack: every file except packs; the - sign excludes.
  2. PackFile: the pack to build. For the word <retail>, see below.
  3. PackType = mod: the only value CA's documentation shows.
  4. Sitting at the top of working_data, this rule applies to any file that finds no [Pack] closer to it. CA sums it up this way: everything except packs goes into mod.pack.

Second file: raw_data/terrain/battles/rules.bob§

[Terrain]
    PrefabRoot = art/prefabs/battle
    save_meta_data_map = false
    save_final_tile_map = true
  1. This is a processing rule, not a pack rule: it says where to look for battle prefabs (PrefabRoot), and which maps to write (the two save_… keys).
  2. PrefabRoot = art/prefabs/battle is for a battle. For a campaign terrain, ChaosRobie's project writes art\prefabs\campaign: that is this project's value; follow the one you are building on.
  3. save_meta_data_map and save_final_tile_map: keep them as CA gives them.

Third file: raw_data/terrain/tiles/battle/rules.bob§

[Tile]
    <Files> = ...*.terry, ..._settings.xml
    TileDatabaseType = battle
    PrefabRoot = art/prefabs/battle
  1. <Files>: the .terry projects and the _settings.xml files of every subfolder, thanks to the three dots.
  2. TileDatabaseType = battle: the tile database type, here the battle one.
  3. PrefabRoot: the same prefab folder as the second file's [Terrain] rule.

Fourth file: raw_data/art/prefabs/battle/rules.bob§

[Prefab]
    <Files> = ...*.terry
    TargetPath = prefabs
    RootFolder = true
  1. <Files> = ...*.terry: prefabs are .terry projects, in every subfolder.
  2. TargetPath: the key that the “prefab root … does not have a valid TargetPath” message asks for (see “Messages to know”), when this folder is missing from the run.
  3. RootFolder = true: keep it as CA gives it.
  4. For campaign prefabs, the Custom Campaign Settlement Skins tutorial has you place the same rule in raw_data/art/prefabs/campaign/rules.bob, with TargetPath = prefabs/campaign.

A model: a separate pack for a battle map§

To be placed in the tile map's folder, working_data/terrain/battles/my_map/, and in the tile's folder (see the box):

[Pack]
    BasePath = /
    PackFile = <retail>/data/my_map.pack
    PackType = mod
  1. BasePath = /: according to CA's Rules.bob page, you add it when the rule sits in a subfolder, to send that folder's content to another pack. The example map writes it this way.
  2. PackFile: the map's pack. This [Pack] is closer to the tile map's files than the top one: they go into my_map.pack, no longer into mod.pack.
  3. PackType = mod: as in the first file.
  4. Compression (not tried): the kit's documentation (documentation/pack/pack/compression.txt) describes two keys to add to a [Pack], Compressed = true and CompressionType = LZ4 (or ZSTD). It advises against it for sounds and videos, and urges caution for models (LZ4 if it is really needed). We have not tried it.

That last rules.bob, the one in _tile_database/TILES/, points to assembly_kit_example.pack: if your tile also has an entry in that folder, check in RPFM which pack it went into.

One map, two folders, one packNo rule in the tile's folderThe tile mapterrain/battles/my_map/rules.bobThe tileterrain/tiles/battle/<tile set>/<tile>/no rules.bobmy_map.packthe tile map onlymod.packthe tile, viaworking_data/rules.bobthe map is split in twoThe same rule in both foldersThe tile mapterrain/battles/my_map/rules.bobThe tileterrain/tiles/battle/<tile set>/<tile>/rules.bobmy_map.packthe tile map and the tilethe whole map in a single packThe kit's example map: 3 rules.bob, 1 packtile maptile_tile_database/TILES/→assembly_kit_example.packIn _tile_database/TILES/, the example tile has its entry(test_tiles_assembly_kit_example_tile.bin and .xml), and thatfolder's rule sends it into assembly_kit_example.pack: if BOBwrites your tile's entry there, check in RPFM which pack it wentinto.
The same [Pack] rule in both of the map's folders, or the tile goes into mod.pack.

The word <retail>: what we know, and what we don't§

Pack rules write PackFile = <retail>/data/…. It is tempting to read it as “the game folder”. That is not what we observed:

A pack built by BOB would therefore land in assembly_kit/retail/data/, not in the game's data folder. We have not checked this in Warhammer III for a pack: it is a deduction, and the [Pack] route itself is unproven there. After a run, look for the pack in both places (its modification date gives it away), and copy it by hand into the game's data/ folder if it is not there.

Where did my pack go??A route unproven in Warhammer IIIdeduced from a [Copy] rule and the Rome II guide1Look for it in both placesits modification date gives it away?<Assembly Kit>/retail/data/probably here: <retail>led into the kit for us;Rome II puts its packhere<game>/data/where the game readspacks2Copy it by hand, if it stayed in the kitOpen it in RPFMRPFM shows what the pack holds.terrain/battles/<map>/ and the tile, nothing else:neither the example map nor a .pack3Enable it in the launcherthen test it in game.4The proven route: making the pack with RPFM
If you try the [Pack] rule: find the pack, copy it into the game's data folder, check it in RPFM.

BOB and a campaign map§

CA's documentation warns that the public kit only supports creating battle tiles, and the Warhammer III kit ships no raw campaign terrain data. The community has nonetheless rebuilt a campaign-type Terry project (ChaosRobie, for Immortal Empires Expanded), and BOB has a campaign module, bob_campaign. The project is described in the Terry guide, the map's logical half in the CAIME guide.

The order of runs§

The tw-modding wiki's campaign map tutorial gives this order, for a map the game's database knows (for a new map, see “The limit” below). BOB looks for the first steps' results in your pack, and it must be closed and reopened to see them: hence the back and forth. The tutorial does not say where to put that pack; for us, BOB mounts every pack in <game>\data (mods included) and those in assembly_kit\working_data. A running BOB keeps the packs in <game>\data open: replacing them fails (WinError 32) until it has finished. Mind: that pack gives BOB files; to know whether the map exists, BOB only looks at the database in CA's packs (see “The limit”).

  1. The relief first: the next steps depend on it and read it from your pack. Put it in your pack, then close and reopen BOB.
  2. The tile map: into the pack again, then close and reopen BOB.
  3. The global tile map (roads and cliffs), which BOB derives from the tile map in your pack.
  4. global_props.bin, the placed objects: redo it whenever a region is added or removed (BOB then reads CAIME's map.hex, which must match the database); up to ten minutes, the tutorial says. ChaosRobie's project indeed stores its objects by region, in one .layer each.

“Close and reopen BOB” applies to its window. From Terry, nothing to do: each Process with BOB starts a new BOB.

Campaign: the order of runsfor a map the game's database knowsA map unknown to the game's database (the one in CA's packs): BOBonly runs 6 actions instead of a dozen, without a message. Acontrol case, then the community.The reliefthe next steps read it from your packfull_height_map.ddsfull_logic_map.compressed_map1Relief into your pack, then close and reopen BOBThe tile maptile_list.bintile_mask.ddspatch_mask.dds2Tile map into your pack, then close and reopen BOBThe global tile maproads and cliffs, taken from the tile map in your packglobal_map/tile_list.bin3The placed objectsBOB reads CAIME's map.hex, which must match the database;redo it for every region added or removed; up toten minutes, the tutorial saysglobal_props.bin4Generate Camera Height Map: for us, this action crashes BOB(the tutorial says Terry crashes producing it);camera_heightmap.png is made separately (the tutorial:approximated from the heightmap, scaled, with the PNG's tEXtblock set).
The order from tw-modding's campaign map tutorial. BOB looks in your pack for the first steps' results: after the relief, then after the tile map, they go into the pack, then you close and reopen BOB's window; from Terry, each Process with BOB starts a new BOB.

How to check it worked. In bob.log, compare the number of actions on the first line with the STATUS: lines. For us, a complete campaign run that succeeds counts 12 actions: Terry file, Color Overlay, Color Overlay (Sea), Snow Mask, Campaign Shroud Heights, Patch Visibility Mask, Tilemap, Campaign Global Blendmap, Corruption Mask, Global Tilemap, Campaign Heightmap and Campaign Trees (bob.log of 25.09.2026, patch 9.0; same count on 04.10.2026, patch 9.0.2, code 0). The first attempt, on 21.09.2026, selected 15, including Initialise warscape and Generate Camera Height Map, which crashes BOB (see below). For a map the game's database does not know, BOB only runs 6 (see “The limit”). Then count the “Failed to find tile” in bob_warnings.log, as for a battle.

What the heavy actions (Tilemap, Global Tilemap, Campaign Global Blendmap, Campaign Shroud Heights, Campaign Heightmap) wrote into working_data/terrain/campaigns/<map>/ on our first complete run (21.09.2026, patch 8.1): full_height_map.dds (the built relief), full_logic_map.compressed_map (the logic map), tile_map.tiles, tile_list.bin, tile_mask.dds, patch_mask.dds, shroud_heights.dds, and in global_map/: global_blend.dds, texture_arrays.xml and tile_list.bin; plus the five masks. Campaign Trees writes the tree list into working_data/campaign_maps/<map>/display/trees/. A file missing or older than the run: the action that writes it did not run.

Three things to know before building§

One campaign, two terrainsThe campaign playable areacampaign_map_playable_areasterrain_folder = <folder>The campaign terrainterrain/campaigns/<map>/the map's relief, tiles andplaced objectsThe battle terrainterrain/battles/<folder>/a battle tile map; CA's alsocarries battle locations andcatchment mapsWithout that battle terrain: a crash at the first land battle,even between two AIs, so often at the very first end of turn.
A campaign map has two terrains: its own, and a battle terrain, named by the terrain_folder column of its campaign playable area.

What BOB does not do, or rewrites, for a campaign§

The limit: a map the game's database does not know§

On 21.09.2026 (patch 8.1), our first complete campaign run took about 25 minutes, mostly to compress the relief, before crashing on Generate Camera Height Map; that same evening, a complete run, relief included, took under a minute. Our later runs took 15 seconds to 2 minutes (All actions took in bob.log), 42 seconds on 25.09.2026 on patch 9.0, for 12 actions. For a map the game's database (the one in CA's packs) does not know, BOB only runs 6 of them, without a message; adding the map to the kit's database or to a mod pack changes nothing. We know of no official way to lift this limit: run a control case, then ask the community.

The 6 actions are Terry file, which writes the placed objects (global_props.bin, global_props_sound.bin), and five masks: no relief, no tiles, no textures, no logic map, no shroud (for us, the objects alone take 11 to 24 seconds, not ten minutes). And no message reports it: no error, no warning.

Only six actions?How many actions doesbob.log announce?over 6Not the limit12 for us on acomplete run; thencount theFailed to find tile inbob_warnings.log6Run a control casea project known to begood, copied underanother name, then runthrough BOBAnd the control case?over 6Your projectis to blame: searchyour own files6 tooThe kit's limityour project is not toblame: ask thecommunitydon't force the toolThe 6 actions of an unknown mapthe Terry file and five masks; no relief, no textures,no logic map, no shroud; and no message at all.
Six actions instead of a dozen, without a message: a control case tells whether it is your project or the kit's limit.

The control case, before searching your own files: take a project known to be good, copy it under another name, and do a run on it. If it also gets only 6 actions, your project is not to blame.

If you hit this limit, bring it to the community (the CAIME team's Discord, the tw-modding wiki).

BOB's pitfalls§

The pitfalls, along a runWhile preparingA local [Terrain] without PrefabRootcopy it over, or [+Terrain]The * wildcard stops at foldersstart the filter with ...The tile without the [Pack] rulethe same rule in both foldersA whole exported tableonly your rows, with RPFMA hand edit in working_datafix the sourceA game updaterestore raw_data/db, then a control run1While starting BOB-h, --help, -help: "Illegal option format"no guessed optionsmod <pack>; in bob_project.script.txtremove the line before running BOBTerry or the game openclose them before StartA node ticked, then a click elsewherepick an actionA single actiontake <All>Its window kept open (campaign)close and reopen BOBA window you cannot findAlt+Tab, then Windows + Up arrow2While checkingOverwritten logsread them after every runExit code: 0 alonecount the STATUS lines: Failed, FinishedWithWarningsOnly 6 actions, no messageunknown map: a control case<retail> is not necessarily the gamelook in the kit tooA pack built by BOBopen it in RPFM3
Eighteen pitfalls, sorted by when they bite: while preparing, while starting BOB, while checking. For each, the pitfall, then its fix.

For an AI reading this page§

If you are an AI helping someone use BOB, here are the essentials, as checked facts. They were gathered on the game's patch 8.1 (September 2026), then reviewed for update 9.0, which replaced BOB (its executable and all its modules) and rewrote raw_data\db; 9.0.2 replaced them again, and a terrain run was rechecked there on 04.10.2026 (12 actions, code 0): check them again after an update.

Frequently asked questions

What is BOB in the Total War: Warhammer III Assembly Kit?

The kit's builder: it turns the sources in raw_data (database tables, Terry terrain projects) into game files in working_data, and can gather them into packs. It opens from the Assembly Kit's Steam launcher (Exporter: BOB), from its executable bob.modder.x64.exe, or from Terry (File → Process with BOB, Ctrl+P), which hands it the work.

Do I need to open BOB for a battle map?

No. Terry launches BOB itself (File → Process with BOB, Ctrl+P), on the tile map then on the tile, and RPFM makes the pack. BOB's window is mostly for exporting the kit's database.

Where are BOB's logs?

In the Assembly Kit's binaries folder: bob.log, bob_warnings.log, bob_error.log, bob_plugin_error.log, bob_startup_error.log and bob_db.log. They only keep the last run.

How do I know whether a BOB run succeeded?

The first line of bob.log announces the number of actions selected; there must be as many STATUS: Finished lines, and the log must end with Exit code: 0. A STATUS: Failed line and an Exit code: 1 say an action failed (bob_error.log says why), and the actions that depended on it are then DependencyFailed; FinishedWithWarnings points to bob_warnings.log. That log must hold no Failed to find tile (outside the last row of a campaign's battle terrain), and the output files must carry the run's date. A pack is checked in RPFM.

I ticked a folder and BOB did nothing: why?

A node only stays ticked if one of its actions is: ticking then clicking elsewhere cancels the selection without a message. And a single action may produce nothing; pick <All>, which adds the dependencies.

BOB started but I can't see anything: what now?

Launched from Terry, BOB works in the background: its messages appear at the bottom right of Terry, and bob.log says what it did. Opened from Steam or from its executable, its window once opened tiny, at the bottom of the screen: select it with Alt+Tab, then enlarge it with Windows + Up arrow. If a script launched it with a guessed option, an “Illegal option format” box may be blocking it.

Which command-line options does BOB accept?

BOB has no command-line help; two official command lines are known, those of its launchers: -no_console (Steam launcher, Exporter: BOB) and the one Terry passes to it, /dont_stop_on_error /nosplashscreen /get_latest_rules -no_console /offline /configuration:_terry_auto /workspace: "/changelist:Terry (<project>.terry)", where /configuration: names the file binaries/BOB/_terry_auto_configuration.xml that says what to build. -h, --help and -help open an “Illegal option format” box that blocks it. Don't try guessed options, on BOB, Terry or Tweak.

Where does BOB put the pack it builds?

The [Pack] rule writes it to <retail>/data/. For us, <retail> pointed to a retail folder inside the kit (assembly_kit/retail/), as in the Rome II kit guide; this is not confirmed for a pack in Warhammer III, where this route is unproven. Look for it there, then copy it into the game's data/ folder. The proven route remains RPFM.

My pack only holds the tile map: why?

A battle map spans two working_data folders: the tile map and the tile (terrain/tiles/battle/<tile set>/<tile>/). If only the tile map carries your [Pack] rule, the tile climbs up to the top rules.bob and goes into mod.pack. Put the same rule in the tile's folder, or make the pack with RPFM.

What does “Failed to find tile” mean?

That no tile in the tile database matches the pattern in tile_map.png at that spot. Each occurrence in bob_warnings.log is a hole in the terrain. For a campaign, fix the CAIME layers and re-export tile_map.png without manual retouching; then rerun BOB until the count is zero.

Why doesn't BOB build all the terrain of my new campaign map?

For a map the game's database (the one in CA's packs) does not know, BOB only runs 6 actions instead of a dozen, without a message; adding the map to the kit's database or to a mod pack changes nothing. We know of no official way to lift this limit: run a control case (a project known to be good, copied under another name), then ask the community. Our new maps got their 12 actions with BOB run under a debugger, a method of ours, outside the official routes, described in “The limit”.

Should I close Terry before running BOB?

Before running BOB from its window, or saving a pack into working_data, close Terry and the game: an open Terry locks working_data. Process with BOB, run from Terry, is not affected.

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.

↑ Contents