Skip to content
robert-d-schultzPublic

About

Native Total War: WARHAMMER III campaign map tooling: a BOB-free campaign build and editors. Derived from Atlas3K.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Repository files navigation

AtlasWH3

Build Total War: WARHAMMER III campaign maps without BOB.

AtlasWH3 compiles a campaign map from your Assembly Kit sources (the Terry project, its layers and maps) in one run, then writes it into your mod's pack. It does everything BOB's campaign actions do, plus the AI pathfinding data the game would otherwise have to build, and it runs headless from the command line as well as from a window.

  • One run instead of ten actions. A full IEE build takes about 5 minutes on a 4-core machine. A BOB reprocess of the same map takes about 20, with a pack round trip between some of its actions.
  • No workarounds. The devastated map needs no fake second campaign. The camera height map builds (BOB's action fails). Nothing has to be packed and installed halfway through.
  • Checked against BOB. Most outputs are byte-identical to BOB's on the test maps, and the full IEE build has been played in game.

What it builds

Step Writes Replaces
heightmaps full_height_map.dds, full_logic_map.compressed_map, shroud_heights.dds, lf_normal.dds Campaign Heightmap, Campaign Shroud Heights
tile_list tile_list.bin, tile_mask.dds, patch_mask.dds Tilemap
trees trees.campaign_tree_list Campaign Trees
global_map global_map\ (blend, texture arrays, tile list) Global Tilemap, Campaign Global Blendmap
masks colour overlays, corruption, snow and event area masks Color Overlay, Corruption / Snow / Event Area Mask
rivers models\river_* Terry file (river export)
global_props global_props.bin, global_props_sound.bin Terry file (props export)
environment environment_collection.xml Terry file
devastation_pieces pieces\event_*, event_tiles, event_trees, event_vfx, for the map and its devastated version Devastation pieces
lookup *_lookup.tga / .dds, _minimap.tga Convert lookup texture
camera_heightmap camera_heightmap.png Generate Camera Height Map
hlp_spd hlp_data.esf, spd_data.esf the game's own generation during a startpos build

Independent steps run in parallel. Every step reads the Terry project and the game and mod packs directly, so nothing has to be installed between steps.

How close to BOB: the logic map, shroud heights, tile list, masks, piece textures and river models (but for two bytes BOB leaves uninitialised) are byte-identical to BOB's on IEE and The Old World. Trees are byte-identical on Old World; on IEE every tree has the same id, position and rotation, and all but 23 of 253,903 heights agree within 1e-3. global_props.bin has the same objects in the same bodies; BOB's own record order changes from run to run, so it is compared by content. hlp_data.esf and spd_data.esf match the game's own files byte for byte on IEE (on Old World one value differs, where the game's pathfinder has a bug). Each step's record, with every remaining difference explained, is in docs/native_campaign_build.md.

Where it differs on purpose: patch_mask.dds covers the whole map (BOB's misses a band in the north). Props go into quadtree cells by their models' real bounds (BOB uses a 2 × 2 × 2 cube for any model not loose in the kit). Region lookups can move regions past the 1024 palette entries the game reads. Cultures come from the packs' prefab_types, so a mod's own cultures get their own buckets (BOB read the Assembly Kit's vanilla table). Props get their regions from map_data.esf, the file the game reads. full_height_map.dds uses AtlasWH3's own BC6H encoder, with about half the error of BOB's.

What you need

  • Windows 10 or 11, x64.
  • Total War: WARHAMMER III and its Assembly Kit, with your map's Terry project in raw_data\terrain\campaigns\<map>.
  • Your campaign's .pack, set as the project's pack. The build reads CAIME's map_data.esf and pathfinding.ppd from its campaign_maps\<map>\, and the mod's DB tables, models and textures; then it writes the compiled map into it. (A vanilla map needs none: the build makes a new pack.)
  • CAIME's region lookup .bmp, in the Assembly Kit's raw_data\EmpireDesignData\campaign_maps\<map> (a copy CAIME writes to working_data is not read).
  • Optional: the map's devastated project, the one the DB names (campaigns.terrain_location_devastate), for the devastated pieces.

Install

Download the zip from the Releases page and unzip it anywhere. It needs no .NET install. Run AtlasWH3.exe for the app, or AtlasWH3.Cli.exe from a terminal.

The download is unsigned, so Windows SmartScreen may warn on the first start (More info › Run anyway).

Quick start

The build writes into your mod's pack in the game's data folder, keeping one copy of it as it was (%LocalAppData%\AtlasWH3\output\pack_backups). The compiled files go to %LocalAppData%\AtlasWH3\output\compiled\<map>; the Assembly Kit's working_data is not touched.

In the app

  1. Settings: check the game and Assembly Kit folders (found automatically on a Steam install).
  2. Start page: pick the map from the kit (Project: No project).
  3. Build (Ctrl+B): New project for <map>…, save it, pick the mod pack the map ships in (or Cancel for a pack of its own), then Build all (F7).
  4. Start page: pick the project under Project. The editors then open on its map, mod packs and tile map source.

The Build window shows each step's progress, time and notes, and keeps a log of every build in %LocalAppData%\AtlasWH3\output\build_logs.

From the command line

AtlasWH3.Cli new-project iee.atlaswh3 --map cr_combi_expanded_map_1 --pack "D:\...\data\!cr_immortal_empires_expanded.pack"
AtlasWH3.Cli build --project iee.atlaswh3
  • --segments validate,compile builds without writing the pack.
  • --steps tile_list,global_map compiles only those steps.
  • --json prints the report as JSON.
  • AtlasWH3.Cli help lists every command.

The project file

A project (.atlaswh3, JSON) holds one map's build: what the Terry project doesn't. This one is IEE's: the build writes into the mod's own pack in the game's data folder. Settings left out keep their defaults; the Assembly Kit and the game are the ones in Settings (or the CLI's --ak).

{
  "name": "IEE",
  "map": "cr_combi_expanded_map_1",
  "build": {
    "packFile": "{game}\\!cr_immortal_empires_expanded.pack"
  }
}
  • Segments: a build runs Validate, Compile and Pack, in that order, and stops at the first failure. customSteps adds your own commands before or after any of them (a startpos build, a script).
  • Tokens: {project}, {game} (the data folder), {ak}, {map}, {out} and {pack} expand in paths. Relative paths are relative to the project file.
  • Pack: writes the files this build made into packFile and keeps everything else in it (DB, scripts, battle maps, CAIME's files); river models and pieces the build no longer makes are dropped. A pack that doesn't exist yet is created. It refuses while the game runs, writes beside the pack and swaps it in, and first keeps one copy of the pack in %LocalAppData%\AtlasWH3\output\pack_backups ("backupPack": false turns that off). piecesPackFile (optional) takes the event-area pieces instead, for a campaign that ships them in a pack of their own (Old World). modPacks lists other packs the map reads (only read). Projects made before this keep working: their packs and install become packFile on load.
  • Map settings: acceptTileMap (tile-map check codes to build through), patchMask (fitted, or vanilla for BOB's), lookupLast (regions to move past palette entry 1024), keepOutsideQuadtree (true keeps objects placed past the map's edge, in the quadtree cell nearest to them; BOB drops them), zeroShroudWestEdge (true sets shroud_heights.dds to 0 over the map's westmost 10 units).
  • Output: output (or the CLI's --out) compiles into another folder; by default it is %LocalAppData%\AtlasWH3\output\compiled\<map>.

Limits

  • startpos.esf is not built: it still comes from the game (an RPFM startpos build works as a custom step).
  • CAIME's files are inputs, not outputs.
  • The full build has been played in game on IEE. Other maps, Old World included, are checked against BOB's output.
  • The Scene editor, Tile map and Campaign battles windows are a preview: they come from Atlas3K and are only partly moved to WH3.

The full list is in KNOWN_ISSUES.md.

Documentation

Building from source

dotnet build AtlasWH3.slnx -c Release
dotnet test src/AtlasWH3.Tests --filter "FullyQualifiedName~BuildProjectTests"
powershell -ExecutionPolicy Bypass -File tools\publish.ps1
  • SDK: .NET 10 (global.json takes any 10.0 feature band from 10.0.100).
  • Publish: publish.ps1 writes the self-contained download to dist\AtlasWH3-<version>\ and zips it.
  • Tests: the full suite takes about 16 minutes, so filter to the classes you touch. Tests that need the game or kit data skip when it is missing.
Project Contents
AtlasWH3.Formats Readers and writers: packs, DB, Terry, map.hex, tiles, BMD v27, ESF, DDS / BC6H, RMV2
AtlasWH3.Core The build steps, projects and packing, the editors' model
AtlasWH3.Cli AtlasWH3.Cli.exe
AtlasWH3.App AtlasWH3.exe (WPF, Direct3D 11)
AtlasWH3.Tests xUnit

Parity fixtures: the data tests run on two maps, IEE (cr_combi_expanded_map_1) and Old World (cr_oldworld_map_1). Freeze them right after a BOB run, so the tests keep comparing those sources with those BOB outputs while the maps change:

AtlasWH3.Cli fixture-freeze iee --maps cr_combi_expanded_map_1,cr_combi_expanded_map_devastate_1 --packs !cr_immortal_empires_expanded.pack
AtlasWH3.Cli fixture-freeze oldworld --maps cr_oldworld_map_1,cr_oldworld_map_devastate_1 --packs !cr_oldworld_campaign.pack,!cr_oldworld_campaign_devastate.pack
AtlasWH3.Cli fixture-check

A fixture lives in atlaswh3_fixtures beside the kit, as hard links (no extra disk space). Without one, the tests read the live kit. Add --replace to freeze a fixture again.

Related tools

  • WH3_visual_map_decompiler does the reverse: it turns a compiled WH3 campaign map back into a Terry project. AtlasWH3 reuses its format readers, and the two together give a round trip.
  • CampaignMapToolkit (CAIME) makes the campaign AI map files AtlasWH3 takes as input. Its code is under a non-commercial licence, so none of it is copied here.
  • RPFM: AtlasWH3 reads its schema_wh3.ron for DB layouts when it is installed.

Credits and licence

AtlasWH3 is a fork of Atlas3K, the same tooling for Total War: THREE KINGDOMS. The two games share an engine, and Atlas3K's pack, PNG, hex grid, tree and Terry code, and its method of matching BOB byte for byte, are the base this was built on. Atlas3K's own README is at the fork point.

MIT, as Atlas3K. The libraries it uses keep their own licences; see THIRD_PARTY_NOTICES.md.

Not affiliated with Creative Assembly or SEGA. Total War: WARHAMMER III and its Assembly Kit are their property. AtlasWH3 ships none of the game's data.

About

Native Total War: WARHAMMER III campaign map tooling: a BOB-free campaign build and editors. Derived from Atlas3K.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages