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.
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§
| Word | Meaning |
|---|---|
raw_data | the sources: what the kit's tools read (database XML tables, Terry projects, images) |
working_data | what BOB produces: files in the game's format, mostly stored under the same path as their source (see “What BOB produces”) |
| Kit database | the XML tables in raw_data/, edited with Dave |
| Game database | the one in CA's packs; for a campaign map, it is the one that counts (see “BOB and a campaign map”) |
| Node | a folder or file in one of the trees of BOB's window |
| Action | a job BOB can do on a node; each node offers several |
| Processor | the part of BOB that does one kind of job; bob.log names it in front of each action |
| Run | one execution of BOB, from launch to exit code |
| Rule | a section of a rules.bob, with its Key = value settings; each section sets up one processor |
rules.bob | a text file of rules placed in a folder; it applies to that folder and those below, unless a closer rule takes over |
| Pack | the .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 |
| Log | BOB'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>/; BOB and its logs are in its binaries folder. The game, for its part, reads packs from <Steam>/.
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.
From Terry§
- In Terry: File → Process with BOB (Ctrl+P), or the globe button with an arrow pointing right. It is the tutorials' route for terrain.
- Terry writes what it asks for (processors, folders, wanted outputs) into a configuration file,
binaries/, then launches BOB in the background with that file (see “The command line” below). Each Process with BOB starts a new BOB.BOB/ _terry_auto_configuration.xml - What it offers to build depends on the project type (tile, battle tile map, campaign tile map).
- No need to close Terry: it launches BOB itself. Save your project first.
- Tutorials often say “export” a map: in Warhammer III it is Process with BOB, then the pack (see “Building a pack” below).
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:
| Job | Node and action | What to know |
|---|---|---|
| Export the database | database node → <All> | for us (20.09.2026, patch 8.1): 3,788 actions in 109 seconds; one folder per table in working_data/ (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 |
| Texts | the Retail Pack option | described 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 startpos | campaigns 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 option | Program launched |
|---|---|
| Exporter: BOB | binaries/ |
| Battle Map Editor: Terry | binaries/ |
| Database Editor: Dave | dave/, 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)"/ names the file binaries/, which Terry writes: that file tells BOB what to build (processors, folders, wanted outputs). So the command line does more than open BOB: with /, 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.
- 1The 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.
- 2Raw Datathe tree of sources, those in raw_data; a node is a folder or a file.
- 3Working Datathe tree of what is already built, in working_data.
- 4Retail Dataa third tree, which shows the kit's retail folder (with assembly_kit and data in it).
- 5The 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.
- 7The traptick a node, then click elsewhere without picking an action: it unticks, without any message, and Start will do nothing for it.
- 8Startbottom right; each action turns green once it is done. Database export, for us: 3,788 actions in 109 s.
- 9bob.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.
- Tick a node. Its actions show up in two lists: Provider actions and Consumer actions, each with a Merge Actions box. For the
databasenode, the first one is empty. - 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). - Repeat for each node to process.
- 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/ therefore comes out in working_data/. 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:
| Output folder | Files |
|---|---|
working_data/: the tile map | tile_map.bmd, tile_list.bin, lf_normal.dds, full_lf_logic_map.compressed_map, map_info.xml |
working_data/: the tile | tile_height_map.compressed_map, blend0.dds, bmd_data.bin, the grass and tree lists |
For a campaign, BOB's outputs go to working_data/ (relief, logic map, tiles, masks, global_map/). The working_data/ 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/): put it in your pack, or the map has no trees.
Three exceptions to the same-path rule:
- The database export writes one folder per table,
working_data/, with adb/ <table>_tables/ datafile inside; and also, for each campaign, starting-position tables (start_pos_…) and one.pack, inraw_data/, so intoEmpireDesignData/ campaigns/ <campaign>/ raw_data. - A
[Copy]rule writes under<retail>: for us, into the kit'sassembly_kit/folder.retail/ … - A
[Pack]rule writes its pack under<retail>/: see “The word <retail>” below.data/
Two practical consequences:
- BOB rewrites its outputs on every run. A hand edit in
working_data(a texture list, a lighting collection…) disappears on the next run. Fix the source, or make the edit with a script you rerun after every run. - An open Terry locks
working_data: see “From BOB's window” above.
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.
| Log | What you read there |
|---|---|
bob.log | the 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.log | the warnings, including the “Failed to find tile”: read it after every terrain run |
bob_error.log | the 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.log | the other logs, described by their names |
Reading a run in three minutes§
- Open
bob.log. The first line says how many actions were selected; the last one must sayExit code: 0. - Count the
STATUS:lines: you need one per announced action.Finished: done.FinishedWithWarnings: done, but readbob_warnings.log.Failed: failed; the run then ends withExit code: 1, andbob_error.logsays why.DependencyFailed: not done, because an action it depends on failed; look for the firstFailed. Compare with the number you expected too: an incomplete run shows up here, even without an error. - Open
bob_warnings.logand 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). - 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:
| Message | Where | What it means | What to do |
|---|---|---|---|
Failed to find tile | bob_warnings.log | No 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×H | bob_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 node | bob_warnings.log | An 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.log | A 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 TargetPath | bob_error.log (and bob.log) | The Generate Tile Map BMD action ends as Failed, with no tile_map.bmd: the raw_data/ 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.
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§
Building a battle map§
Painting, zones and creating the tile map are in the Terry guide. Here is BOB's part.
- Save, then open the tile map (the project in
raw_data/) and run File → Process with BOB. Reload it afterwards to check.terrain/ battles/ <map>/ - Reopen the tile. In Map Properties, untick legacy vegetation generation, then Process with BOB.
- 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.
- Pack it with RPFM, the proven route:
working_data/(without the kit's example map), a row interrain battles_tableswhosespecificationisterrain/(trailing slash included), a text and an image: see the Terry guide.battles/ <map>/ - 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:
bob.logends withExit code: 0, holds oneSTATUS: Finishedline per action announced on its first line (forFinishedWithWarningsandFailed, see “BOB's logs”), and its actions concern the project you just processed;bob_warnings.logholds no “Failed to find tile”;- after the tile map run,
working_data/holdsterrain/ battles/ <map>/ tile_map.bmd,tile_list.bin,lf_normal.dds,full_lf_logic_map.compressed_mapandmap_info.xml, dated from the run; - in game, the map appears in Custom Battle, and the terrain has no holes.
Exporting the kit's database§
Why: your tables edited in Dave are XML files in raw_data/; the export writes them in the game's format, one folder per table in working_data/. 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.
- Close Terry and the game.
- Open BOB from the Steam launcher (Exporter: BOB) or from its executable (
bob.modder.x64.exe, inbinaries). - Tick the
databasenode and pick<All>: BOB adds the dependencies by itself, such as the Database Export node. - 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/ 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/: 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:
- RPFM, the proven route. You create the pack and add the wanted
working_datafolder to it. It is the route of the tw-modding wiki's battle map tutorial (the RPFM guide). - BOB's
[Pack]rule, unproven in Warhammer III. Arules.bobwith[Pack](see “The kit's rules.bob files, line by line” below) tells BOB whichworking_datafiles to gather, and into which pack; a battle map needs it in both its folders. We don't know which node to tick for BOB to build that pack in Warhammer III (in the Rome II kit, you tickedmod.packin the retail tree; Warhammer III's, Retail Data, showsassembly_kitanddata, and we have run nothing from it), and<retail>may make it land in the kit'sretailfolder.
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/, 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§
- Each
[Section]stands for a processor; below it, one line per setting:Key = value. - The
<Files>key filters the files concerned: comma-separated lists, exclusion with a leading-, and the wildcard*, which matches any character but/: it does not cross folders. - Three dots,
..., match any character,/included:...*.terrytherefore also reaches the.terryfiles in subfolders (CA's Attila BoB page). The kit's[Tile]and[Prefab]rules use it (see below). - Sections in the
rules.bobfiles CA ships:[Pack],[Terrain],[Tile],[Prefab],[Copy]and[+AssetGraph]. ChaosRobie's campaignrules.bob(raw_data/, the maps' parent folder) addsterrain/ campaigns/ rules.bob [Prop],[Entity],[Mesh]and[Texture]. [Copy]and[+AssetGraph]seem to serve CA for shipping the example map: they copy the raw data into the kit'sretailfolder (IncludeInRetail = true). A mod does not need them.- Don't invent sections or keys: stick to those shown by the kit and CA's documentation.
How BOB finds a file's rule§
- BOB looks for a
rules.bobin the folder of the file it is processing, and checks whether one of its rules targets that file, filters included. - If not, it climbs up one folder, and tries again.
- 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 as | Effect |
|---|---|
[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.
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<Files> = -*.pack: every file except packs; the-sign excludes.PackFile: the pack to build. For the word<retail>, see below.PackType = mod: the only value CA's documentation shows.- 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 intomod.pack.
Second file: raw_data/terrain/battles/rules.bob§
[Terrain]
PrefabRoot = art/prefabs/battle
save_meta_data_map = false
save_final_tile_map = true- This is a processing rule, not a pack rule: it says where to look for battle prefabs (
PrefabRoot), and which maps to write (the twosave_…keys). PrefabRoot = art/is for a battle. For a campaign terrain, ChaosRobie's project writesprefabs/ battle art\: that is this project's value; follow the one you are building on.prefabs\ campaign save_meta_data_mapandsave_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<Files>: the.terryprojects and the_settings.xmlfiles of every subfolder, thanks to the three dots.TileDatabaseType = battle: the tile database type, here the battle one.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<Files> = ...*.terry: prefabs are.terryprojects, in every subfolder.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.RootFolder = true: keep it as CA gives it.- For campaign prefabs, the Custom Campaign Settlement Skins tutorial has you place the same rule in
raw_data/, withart/ prefabs/ campaign/ rules.bob TargetPath = prefabs/.campaign
A model: a separate pack for a battle map§
To be placed in the tile map's folder, working_data/, and in the tile's folder (see the box):
[Pack]
BasePath = /
PackFile = <retail>/data/my_map.pack
PackType = modBasePath = /: 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.PackFile: the map's pack. This[Pack]is closer to the tile map's files than the top one: they go intomy_map.pack, no longer intomod.pack.PackType = mod: as in the first file.- Compression (not tried): the kit's documentation (
documentation/) describes two keys to add to apack/ pack/ compression.txt [Pack],Compressed = trueandCompressionType = LZ4(orZSTD). It advises against it for sounds and videos, and urges caution for models (LZ4if it is really needed). We have not tried it.
That last rules.bob, the one in _tile_database/, points to assembly_kit_example.pack: if your tile also has an entry in that folder, check in RPFM which pack it went into.
The word <retail>: what we know, and what we don't§
Pack rules write PackFile = <retail>/. It is tempting to read it as “the game folder”. That is not what we observed:
- On our installation, a
[Copy]rule aimed at<retail>/wrote intoassembly_kit/ … assembly_kit/: into aretail/ assembly_kit/ … retailfolder inside the kit. - The Rome II Assembly Kit guide likewise finds the finished pack in
assembly_kit/.retail/ data - BOB's window also has a Retail Data tree, which shows that
retailfolder of the kit (withassembly_kitanddatain it; recorded on 24.09.2026). On our disk, on 25.09.2026,assembly_kit/nonetheless held onlyretail/ assembly_kit/.
A pack built by BOB would therefore land in assembly_kit/, 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.
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>\ (mods included) and those in assembly_kit\. A running BOB keeps the packs in <game>\ 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”).
- 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.
- The tile map: into the pack again, then close and reopen BOB.
- The global tile map (roads and cliffs), which BOB derives from the tile map in your pack.
global_props.bin, the placed objects: redo it whenever a region is added or removed (BOB then reads CAIME'smap.hex, which must match the database); up to ten minutes, the tutorial says. ChaosRobie's project indeed stores its objects by region, in one.layereach.
“Close and reopen BOB” applies to its window. From Terry, nothing to do: 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/ 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/. A file missing or older than the run: the action that writes it did not run.
Three things to know before building§
- Terry needs already-built terrain to open a campaign project in 3D: without it, it crashes on opening. As long as nothing is built, open the project with 3D View unticked in Open…
- For us, the Generate Camera Height Map action crashes BOB (the tutorial says Terry crashes producing it).
camera_heightmap.pngis therefore made separately (the tutorial: approximated from the heightmap, scaled, with the PNG'stEXtblock set). - A campaign also needs a battle terrain: the
terrain/folder named by thebattles/ <folder>/ terrain_foldercolumn of its campaign playable area. Without it, the game crashes at the first land battle, even between two AIs, so often at the very first end of turn. It is a battle tile map, which BOB builds as such; CA's also carries battle locations and catchment maps.
What BOB does not do, or rewrites, for a campaign§
- No
lf_normal.dds(the relief's distant lighting): BOB does not produce one for a campaign (seen on 21.09.2026, patch 8.1). It is made separately (the tutorial has it exported from Terry as a.bmp, then converted by BOB: not tried by us); either way, it follows the relief and has the size offull_height_map.dds. - Clipped trees: Campaign Trees places no tree beyond z =
world_width× 2/√3 (world_width: the.terryattribute, see the Terry guide). On a map deeper than that, trees get squashed onto a single row (54,027 on a single row for our Saison Expanded map): check the tree list after every run. - No
camera_heightmap.png: see above. It goes intoworking_data/, next to CAIME's files.campaign_maps/ <map>/ - The shroud (
shroud_heights.dds): it follows the project'sHeightShroudlayer (Fill from terrain in Terry, according to the tutorial); for our map, BOB wrote it flat, at 1.0 everywhere (22.09.2026, patch 8.1). We recompute it after every run. - The ground texture list and the lighting collection (
environment_collection.xml): BOB writes them from the Terry project (for lighting, from its zones, theECEnvironmentVolumeentities) and rewrites them on every run. A hand edit inworking_datavanishes: put it in the project, or redo it by script after every run. Two traps: the texture list (global_map/) always cites Warhammer III's 144 groups, not your project's textures, and a group the variation catalogue (texture_arrays.xml .assetdb) does not declare takes the last texture (grey ground); with noEnvironmentVolumezone at all, BOB does not writeenvironment_collection.xml, and the map has no lighting. - The corruption mask, on the other hand, BOB builds from the project's
CorruptionMasklayer (the Corruption Mask action of our runs).
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.
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§
- Guessed options (
-h,--help,-help): an “Illegal option format” box blocks BOB and the script waiting for it. Don't try it on Terry or Tweak either. - A
mod <pack>;line inbinaries/orbob_project.script.txt binaries/: BOB reads these files if they exist, and that line makes it crash at startup (21.09.2026, patch 8.1). Remove it before running BOB.project.script.txt - A node ticked, then a click elsewhere: selection cancelled, without a message.
- A single action may produce nothing (Build Queried Campaign Tables): take
<All>. - Terry or the game open during a run started from BOB's window: Terry locks
working_data. - A local
[Terrain]replaces the parent's: copyPrefabRootover, or write[+Terrain]. - A wildcard
*does not cross folders: to reach subfolders too, start the filter with.... - A battle map split in two: the tile, without the tile map's
[Pack]rule, goes intomod.pack. - An exported table carries all its rows: bad for compatibility between mods.
- A hand edit in
working_datavanishes: BOB rewrites its outputs. - A pack built by BOB is checked in RPFM, which shows what it holds.
<retail>is not necessarily the game folder: look inassembly_kit/too.retail/ data/ - Overwritten logs: they only keep the last run.
- A
FailedorFinishedWithWarningsaction: count theSTATUS:lines inbob.log, not justExit code: 0. - BOB kept open between two campaign steps, when you work from its window: after putting the relief, then the tile map, into the pack, close and reopen BOB. From Terry, nothing to do.
- A campaign map unknown to the game's database: 6 actions instead of a dozen, without a message.
- After a game update: Steam updates the Assembly Kit after the game (for us, an hour later, with 9.0) and rewrites
raw_data\, where BOB takes the database from; the rows you had added there disappear. Check and restore them before running BOB again. Every update can also replace BOB and Terry: 9.0 did (BOB's executable and all its modules), then 9.0.2 (binaries dated 01.10.2026, new fingerprint of the terrain module). Count your rows, then make a control run before the first long build (kit 9.0.2: terrain run rechecked on 04.10.2026, 12 actions, code 0).db - A
datapack to replace during a run: BOB keeps the packs in<game>\open; replacing one fails (WinError 32). Wait for the run to end.data - A window you cannot find: BOB once opened tiny, at the bottom of the screen. Select its window with Alt+Tab, then enlarge it with Windows + Up arrow.
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\; 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.
- Executable:
binaries/in the Warhammer III Assembly Kit (Steam:bob.modder.x64.exe <Steam>/). The kit's Steam launcher offers Exporter: BOB (steamapps/ common/ Total War WARHAMMER III/ assembly_kit/ bob.modder.x64.exe -no_console), Battle Map Editor: Terry (tweak.modder.x64.exe /) and Database Editor: Dave (no option). Terry launches BOB withstandalone TerrainMetadataEditor /; the filedont_stop_on_error / nosplashscreen / get_latest_rules -no_console / offline / configuration:_terry_auto / workspace: "/ changelist:Terry (<project>.terry)" binaries/says what to build (recorded on patch 8.1). BOB has no help:BOB/ _terry_auto_configuration.xml -h,--helpand-helpopen an “Illegal option format” box that blocks the process; try no other option, on Terry or Tweak either. Amod <pack>;line inbinaries/orbob_project.script.txt project.script.txtmakes BOB crash at startup. - Driving it: the window (tick a node, pick an action or
<All>, Start) or Terry (File → Process with BOB, Ctrl+P; a new BOB every time). For a battle map, BOB's window is not needed: Terry starts the runs, RPFM makes the pack. Prepare everything else outside the window (rules.bob, tables, images). - The window, recorded on screen on 24.09.2026: three trees, Raw Data, Working Data and Retail Data (the kit's
retailfolder); right-click on a node: View rules, View actions, Select files only; a node's actions in two lists, Provider actions and Consumer actions, each with a Merge Actions box;<All>is at the top of Consumer actions, and Provider actions is empty fordatabase. rules.bob: sections = processors,Key = valuelines,<Files>filter (commas, exclusion with-); the wildcard*does not cross folders,...does. Lookup: the file's folder, then upwards; the first rule that applies wins;[Name]replaces,[+Name]completes. CA's sections:[Pack],[Terrain],[Tile],[Prefab],[Copy],[+AssetGraph]; ChaosRobie's campaign file adds[Prop],[Entity],[Mesh],[Texture].- A battle map spans two
working_datafolders, the tile map and the tile: the same[Pack]rule must sit in each, or the tile goes intomod.pack. - Packs: the proven route is RPFM. BOB's
[Pack]route is unproven in Warhammer III (node to tick unknown;<retail>observed:assembly_kit/). Check where the pack appeared, then open it in RPFM.retail/ … - Outputs: for terrain, same path as the source, under
working_data. Exceptions: the database export writesworking_data/, and also per-campaign starting-position tables indb/ <table>_tables/ data raw_data/(with oneEmpireDesignData/ campaigns/ .packper campaign);[Copy]and[Pack]write under<retail>. Campaign:working_data/;terrain/ campaigns/ <map>/ working_data/receives CAIME,campaign_maps/ camera_heightmap.pngand, from BOB, the tree list (display/, to put into the pack).trees/ trees.campaign_tree_list - Logs:
binaries/and its neighbours, last run only. First line ofbob.log bob.log:N action(s) were selected for execution., to compare with theSTATUS:lines (Finished,FinishedWithWarnings,FailedorDependencyFailed); last line:Exit code: 0, orExit code: 1if an action failed (bob_error.logsays why; a.tifraster without the declared size gives “Wrong size, expecting W×H” there). “Failed to find tile” and “Failed to find valid quadtree node” are inbob_warnings.log; “Couldn't create all processors…” inbob_plugin_error.log, harmless. Success:Exit code: 0and the right number of actions and zero “Failed to find tile”. - Before running BOB from its window, or saving a pack into
working_data, close Terry and the game; Process with BOB, run from Terry, is not affected. - Campaign: order from the tw-modding tutorial: the relief, put into your pack, then close and reopen BOB; the tile map, into the pack, then close and reopen BOB; the global tile map;
global_props.bin(reads CAIME'smap.hex, redo it for every region added or removed, up to ten minutes). Generate Camera Height Map crashes BOB. A complete run that succeeds counts 12 actions for us. BOB does not producelf_normal.ddsfor a campaign, writes the shroud flat for a new map, and rewrites the ground texture list andenvironment_collection.xmlfrom the Terry project on every run (noEnvironmentVolume, no collection; a ground group not declared in an.assetdbtakes the last texture). Campaign Trees writes no tree beyond z =world_width× 2/√3, and writes the tree list intoworking_data/. A running BOB keeps the packs incampaign_maps/ <map>/ display/ trees/ <game>\open (WinError 32).data - Limit: 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 (the placed objects and five masks), without a message; adding the map to the kit's database or to a mod pack changes nothing. No known official way to lift it: a control case, then the community. Our method, outside the official routes and owned: BOB run under a debugger, Terry's command, a record handed over with the kit's
minxandmaxxwhen the map lookup fails; DLL fingerprint checked for each version. - Startpos: three 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). - Database export: it rewrites some characters' subtype as
defaultin the starting-position tables, a key Warhammer III's mod validator rejects; for a mod, only your rows, with RPFM. - Tutorials say “export” a map: in Warhammer III it is Process with BOB, then a pack.
- Ask the human before launching the game, driving the screen or publishing; delete nothing: tidy away, only the human deletes.
- Reading and documenting a file format, as RPFM and CAIME do: yes. Altering CA's programs or working around their limits: no, with one exception the workshop owns: BOB run under a debugger for a new map's terrain (above). When a tool gets stuck, a control case, then the community (CAIME's Discord, tw-modding).
- See also: the Terry guide, the RPFM guide, the modder's tools, modding with an AI.
Sources and links§
- Creative Assembly wiki: Rules.bob, BoB (Attila) and Terry introduction. The “TWW” pages date from the Total War: WARHAMMER kit (2016): some labels have changed since.
- tw-modding wiki: Map Making for WH3 (WakaWaka300), Campaign Map Making for Warhammer III, Custom Campaign Settlement Skins (ChaosRobie's Warhammer III part: Process with BOB from Terry, its messages), Beginner's Guide and Localisation.
- Heaven Games: the Rome II Assembly Kit guide (2014), for the window and packs.
- The Warhammer III kit itself, read without changing anything: its
rules.bobfiles, the example map,documentation/, the logs inpack/ pack/ compression.txt binariesand the three options of its Steam launcher. BOB's window (its three trees, the right-click menu, the actions window) was recorded on screen on 24.09.2026, without running anything. Thebob.logfiles of our runs (21 to 25.09.2026), and the comparison of the kit's files before and after update 9.0. - Our other guides: Terry, RPFM, CAIME, the modder's tools and modding with an AI; and the workshop.
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, /, where / names the file binaries/ 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>/. For us, <retail> pointed to a retail folder inside the kit (assembly_kit/), 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/). 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.