# AfterWar AI Modding Kit v1.0.1 — Complete Authoring Guide ## Overview and quick start Official easy mod creation page: https://www.afterwargame.com/modding.php?lang=en#modding-kit Direct complete kit ZIP: https://www.afterwargame.com/downloads/afterwar-modding-kit-v2.zip?v=1.0.1.20261111-fixes Complete authoring guide: https://www.afterwargame.com/downloads/afterwar-modding-guide.md Machine-readable manifest: https://www.afterwargame.com/downloads/afterwar-modding-kit.json Kit version: 1.0.1. Game support snapshot: 1.0.1. Archive size: 83846082 bytes. Download and extract the entire kit. Read START_HERE.md, AI_INSTRUCTIONS.md and CONTENT_AUTHORING.md. Choose the workflow from the request: edit any current allowlisted entry in an existing .awmod with export-project/build-project; author an existing-map scenario with SCENARIO.md; or create a new universe/map/country and sector IDs with WORLD.md and world.schema.json. `generate-world-map` can derive connected sector IDs from a colored source image. Scenario and world country schemas include startup controls and partial `ai_settings` updates for every writable field in the Runtime Mod Studio AIData editor. Existing-map scenarios edit owner and forces for Region, Sea and Ocean sectors by numeric ID, plus population for Region; Lake remains MapSettings-only. Both map workflows accept partial `map_control_settings` for display, normal-generation parameters, shading, reflections and label placement. The world schema also supports starting reserves, research, factories and city/town catalogs. Existing projects can use `map-control-settings.schema.json` to export and edit map settings and `map-cities.schema.json` to edit city catalogs. Use `fill-world-height --mode reset` to reset grayscale HeightTexture to 70 without topology, or use the land/water modes with exported source and topology documents to reproduce the Studio fills. It preserves the RGB24 province map, exact map dimensions and chunk axes. Use `replace-world-map` to swap the complete map/country source set in an existing project while preserving its mod metadata and other content; export the target and provide a complete source project. Preserved reference-bearing entries must have compatible numeric ID/name catalogs. Use `resize-world-project` on a complete source project to change map dimensions; `--remove-lost-sectors` removes IDs lost to a crop after supported references validate. Use `set-horizontal-map-copies` on a complete world-source project to change repeats from 1 to 16; it updates layout data and invalidates dependent caches. `content.schema.json` builds country artwork credits; decode existing credit records first to preserve their six codec fields and their order. The generic project workflow exposes all 85 fixed current Runtime Mod Studio entries plus accepted dynamic names; other entries use their original binary format. Report which families were structurally validated and which were binary-only edits. Never substitute Earth for a requested independent map. An ordinary AI chat can author mods when it can receive files, read and write them, and run Python 3.10+. No special agent mode or provider API is required; tool availability depends on the provider and account. The tools run on Windows x64 or Linux x64. The tools include their runtime and do not require the game, Unity, SPG, .NET installation, an account or network during authoring. ```text python afterwar_modkit.py build-world examples/NewWorld/world.json --output MyWorld.awmod python afterwar_modkit.py validate-world MyWorld.awmod python afterwar_modkit.py prepare-world ExistingWorld.awmod --output PreparedWorld.awmod ``` For an existing map scenario: ```text python afterwar_modkit.py build scenario.json --output MyScenario.awmod python afterwar_modkit.py validate MyScenario.awmod ``` Independent worlds supply their own lossless RGB24 province map, registered country/sector IDs, geography and optional heights, normals, biomes and rivers. Chunks are at most 1024 pixels per axis; world dimensions are multiples of four from 64 to 8192. Required topology, neighbors, region cache, battle raster, boundaries, terrain, river geometry/style, ownership and country label caches are prepared from that world's sources. A world without rivers has a valid empty river cache. Runtime GPU uploads, glyphs, scene activation and simulation initialization remain runtime work. The complete editable fictional world example is examples/NewWorld/. Custom calendars and explicit supported_languages are supported. Optional current-format binary world content is described in WORLD.md. Existing map scenarios may inherit only assets whose dependencies are unchanged. An independent world must not inherit Earth map caches or Earth country assignments. Deliver the real .awmod, the editable world.json or scenario.json, every referenced source asset and .preparation.json. Require Prepared=true, GameRequired=false and PreparationMode=standalone-world for new worlds or standalone for existing-map scenarios. Validation regenerates/checks caches; it is separate from gameplay verification. If your environment cannot download files or execute the builder, say so before claiming a mod was created. Engine binaries, runtime libraries and the kit itself stay outside .awmod archives. No new hash entries are added to game archives. ## Independent world authoring Use schema_version 3 in world.json. The complete editable example is examples/NewWorld/. It contains two fictional countries, its own land, sea, ocean and lake sector IDs, exact RGB province map, geography, heights and river source. No Earth records or geometry are used. ```text python afterwar_modkit.py build-world world.json --output MyWorld.awmod python afterwar_modkit.py validate-world MyWorld.awmod python afterwar_modkit.py prepare-world ExistingWorld.awmod --output PreparedWorld.awmod ``` Python 3.10+ and the complete kit are required. The included self-contained Windows x64/Linux x64 CPU tool needs no Unity, SPG, game executable, game assemblies, .NET installation or network. Source PNG files and optional binary assets must be inside the world.json directory. Deliver the final .awmod, all editable source files and the companion .preparation.json. The kit libraries and executables stay outside the mod. ## World sources - width and height: multiples of four from 64 to 8192. Chunks are at most 1024 pixels per axis. horizontal_tiles defaults to 1; values above 1 use horizontal wrapping. - images.regions and images.geography: noninterlaced 8-bit RGB PNG at the exact world dimensions. RegionsTexture is an exact RGB24 color-ID map; every pixel must identify a declared sector, every sector must have pixels, and colors must be unique and nonzero. No resizing, quantization, palette conversion or lossy compression is performed. - images.height: optional 8-bit grayscale or grayscale RGB PNG. Omitted height is flat. height_scale defaults to 0.1. Meshes and opaque normal textures are generated from height with current map-control settings; images.normal can supply an opaque RGB normal map of the exact dimensions. - images.biomes: optional exact RGB map matching the biome definitions. Omitted biome map uses the declared sector types and built-in numeric gameplay identities. Custom biome colors and definitions belong to this world. The first seven numeric IDs preserve Ocean, Sea, Lake, Forest, Plains, Desert and Mountain gameplay identities; subsequent entries may define other land biomes. New worlds are not limited to Earth's biome pixels or sector IDs. - images.rivers: optional grayscale PNG: water=64 (legacy 89 accepted), land=90, river thickness=100..255. Omitted rivers generate a correct empty river layer and valid empty rendering cache. Opaque RGB grayscale is also accepted. A zero-byte rendering entry is invalidated data, not a prepared empty layer. - sectors: id (1..500000), unique name, type (Region/Sea/Ocean/Lake), exact #RRGGBB color, optional subregion_id, owner and population. Countries use their own IDs (1..65535). Lakes exist in MapSettings and the sector registry, never in ServerBase. Lake names are not assigned numbered suffixes by the builder. - Province colors must match the engine's HSV hue ranges: Region [0, 0.17), Lake [0.29, 0.37), Sea [0.55, 0.65), Ocean [0.75, 0.85). Values are normalized from 0 to 1. The builder rejects invalid colors and never recolors supplied province pixels automatically. - countries: unique id/name/color, optional capital, flag, money, stability and corruption. Capital must be owned land when land exists. The builder derives membership, neighbors, population and initial country statistics from this world. Countries and all water sector kinds may be absent if the world's sources do not contain them. - supported_languages is required. date, time and calendar use CALENDAR.md. English titles are 2..30 characters. Mod identity/version are independent of the game support version. ## Optional content source_entries maps supported current-format binary entry names to local files. It accepts cities, objects, environment content, leaders, news, formations, political world and ideology/effect content. Map sources, ID registries, package metadata and caches cannot be silently replaced through this field. Modify the canonical world sources and prepare again. Existing-game binary formats still apply; an arbitrary PNG or JSON renamed to .bin is not a valid content entry. Art, mechanics or content not actually supplied/generated must not be claimed as present. ## Preparation and validation The CPU tool reuses the game's extracted source algorithms and binary contracts for sector spans, adjacency, travel metrics, battle raster, terrain and river geometry/style. It writes the world's graph, neighbors, visual boundaries, exact region cache, terrain, river rendering, ownership, country components and label geometry. Province/normal textures remain opaque. Every archive entry is deterministically ordered and timestamped. No new hash entries are written. validate-world regenerates 16 map caches and four portable platform texture entries from that archive's canonical sources and compares them byte-for-byte. It does not consult the Earth profile for map identities. prepare-world rebuilds these caches after source edits. Rebuild world.json when changing map dimensions, heights or other canonical authoring structures. Invalid or inconsistent sources are rejected. Generic validate/prepare select this path when scene_regionTextures.bin is present. Portable geographic and normal texture entries use opaque RGB24 with complete mip chains on desktop and Android. They are prepared offline and require no runtime texture conversion, at the cost of more GPU memory than platform block compression. Normal source payloads use RGBA32 with alpha fixed to 255; source PNGs and the province map remain opaque. Province RGB24 pixels have a single mip and are never resampled. No biome surface materials are invented when none are supplied. Unchanged assets can be inherited only by a scenario that keeps their dependencies unchanged. A full world supplies its own sources and masks incompatible base-world entries. An empty terrain/river cache cannot inherit an unrelated Earth's cache. GPU uploads, materials, text glyphs, scene activation and simulation initialization remain runtime work. Prepared=true confirms authoring/consistency, not a gameplay run or instant loading. ## Existing-project startup and general settings Existing projects can export and edit startup time and general settings through world-settings.schema.json. Version 2 also exposes active maritime transitions, auto-defense suppressions, abandoned-neutral records, colonization/decolonization progress, the last AI war day and administrator grants. Version 1 documents remain accepted and preserve the added fields from the source entry. Export both `serverbase_timeGame.bin` and `serverbase_generalSettings.bin` with `export-world-settings`, edit the JSON, then write both entries with `edit-world-settings`. Replace both project entries and run `build-project`, `validate` and `prepare`. See CONTENT_AUTHORING.md for the full command sequence. ## Existing-project biome raster For a current project's map, use `biome-map.schema.json` with `export-biome-map` and `edit-biome-map`. The exported PNG is opaque RGB24, pixel-exact and constrained to the existing map dimensions, chunk axes and palette in `scene_biomes.bin`. Use `reset-biome-map` to reproduce Runtime Mod Studio's Reset Biome action with the current Sea biome color (numeric ID 1). These workflows change the biome raster only; `scene_regionTextures.bin` and province colors remain untouched. Update the project entry mapping to the generated binary and add `sector_terrain.bin` to `delete_entries` so the game rebuilds its cache from canonical sources. ```text python afterwar_modkit.py export-biome-map ExistingMod.source/project.json --output biome-map.json python afterwar_modkit.py edit-biome-map ExistingMod.source/project.json biome-map.json --output ExistingMod.source/entries/scene_biomeTextures.edited.bin python afterwar_modkit.py reset-biome-map ExistingMod.source/project.json --output ExistingMod.source/entries/scene_biomeTextures.reset.bin ``` Both output files are binary replacements for `scene_biomeTextures.bin`; point the project entry at the one you use and remove stale `sector_terrain.bin` through `delete_entries` before building. ## Existing-project biome terrain source textures `scene-biome-terrain.schema.json` exposes 12 opaque RGB24 source images for the Forest, Steppe, Desert and Mountain / Ice surface groups. Each group has albedo, normal and roughness slots. The compiler creates full mip chains, packs roughness into compiled albedo alpha, writes desktop BC7 and Android ASTC 4×4 data, and applies the Android 1024-pixel limit used by the game. The ABI 4 native compiler is bundled for Windows x64. Linux x64 requires a compatible shared library supplied with `--native-library`. ```text python afterwar_modkit.py export-biome-terrain ExistingMod.source/project.json --output biome-terrain.json python afterwar_modkit.py edit-biome-terrain ExistingMod.source/project.json biome-terrain.json --output ExistingMod.source/biome-terrain-edited ``` Map the generated `scene_biomeTerrainTextures_source.bin`, `scene_biomeTerrainTextures.bin` and `scene_biomeTerrainTextures_android.bin` files in `project.json`, then run `build-project` and `validate`. ## Loading-screen slideshow images The slideshow is an ordered set of PNG/JPEG assets stored in binary `ui_loading_backgrounds.bin`. Exporting the current entry extracts the images unchanged to a sibling directory and writes their relative paths to JSON. Edit the ordered `images` array to add, replace, remove or reorder backgrounds. The builder checks the file name, image container, dimensions, limits and output paths; it does not resize or recompress images. ```text python afterwar_modkit.py export-project MyMod.awmod --output MyMod.project python afterwar_modkit.py export-loading-backgrounds MyMod.project/entries/ui_loading_backgrounds.bin --output loading-backgrounds.json python afterwar_modkit.py edit-loading-backgrounds loading-backgrounds.json --output MyMod.project/entries/ui_loading_backgrounds.edited.bin python afterwar_modkit.py build-project MyMod.project --output MyModEdited.awmod python afterwar_modkit.py validate MyModEdited.awmod ``` ## Existing-project 3D objects and custom models `scene-objects.schema.json` edits the complete object slot catalog, map placements, conditional variants, water routes and the object climate grid. Export the entry to a JSON document and sibling asset folder, then replace the binary entry after editing: ```text python afterwar_modkit.py export-scene-objects MyMod.project/entries/scene_objects.bin --output scene-objects.json python afterwar_modkit.py edit-scene-objects scene-objects.json --output MyMod.project/entries/scene_objects.edited.bin python afterwar_modkit.py import-glb Tree.glb --output Tree.awmodel ``` The GLB importer accepts static glTF 2.0 binary models with one embedded buffer and embedded PNG/JPEG textures. It converts triangle meshes and metallic-roughness materials to the game's prepared model format. The final `.awmod` retains the model and texture payloads inside binary `scene_objects.bin`; JSON and `.awmodel` assets remain editable sources alongside it. Model rendering still requires a game-side review. ## Existing-project environment editing Export a project first. The settings editor exports and edits profile versions 1–4, upgrading legacy layouts to version 4 with the Runtime Mod Studio defaults for missing fields. Omitted scalar fields stay unchanged, while each supplied array replaces that complete array. The baked placement editor exports and replaces the entire placement-edit catalog. Numeric sector references are checked against the project's sector registry. Replace both edited binary entries in `entries/`, then rebuild and validate the project. These tools edit recorded settings and placements; model-library content and rendered appearance still need game-side review. ```text python afterwar_modkit.py export-project MyMod.awmod --output MyMod.project python afterwar_modkit.py export-environment-settings MyMod.project/entries/scene_environment.bin --output environment.json python afterwar_modkit.py edit-environment-settings MyMod.project/entries/scene_environment.bin environment.json --output MyMod.project/entries/scene_environment.edited.bin python afterwar_modkit.py export-environment-edits MyMod.project/entries/scene_environment_edits.bin --output environment-edits.json python afterwar_modkit.py edit-environment-edits environment-edits.json --output MyMod.project/entries/scene_environment_edits.edited.bin python afterwar_modkit.py build-project MyMod.project --output MyModEdited.awmod python afterwar_modkit.py validate MyModEdited.awmod ``` ## Existing-project sector topology Export the project and the complete topology document, edit it, then build and prepare the supported Earth scenario package: ```text python afterwar_modkit.py export-project MyMod.awmod --output MyMod.project python afterwar_modkit.py export-topology MyMod.project/project.json --output topology.json python afterwar_modkit.py edit-topology MyMod.project/project.json topology.json --output MyMod.project/topology-edited python afterwar_modkit.py validate-topology MyMod.project/topology-edited.project.json python afterwar_modkit.py build-project MyMod.project/topology-edited.project.json --output MyModTopology.awmod python afterwar_modkit.py validate MyModTopology.awmod python afterwar_modkit.py prepare MyModTopology.awmod --output MyModTopology.prepared.awmod ``` For Runtime Mod Studio's Reset Regions action, run `reset-region-map MyMod.project/project.json --output MyMod.project/topology_assets/region-reset.png`. It writes a new opaque RGB24 PNG filled with #FFFFFF at the exact map dimensions and preserves the source chunk layout. It does not change the project or sector catalog. Use the PNG as `region_map.image` in the exported `topology.schema.json`, then edit the sector list so its registered color IDs match the image and run `edit-topology --allow-pixel-assignment-changes`. The reset image has only one color, so a package is not ready to build until the topology has been reconciled. For one unregistered map color, run `replace-unknown-region-color MyMod.project/project.json '#A1B2C3' --target-type Region --target-id 123 --output MyMod.project/unknown-color-fixed`. The command replaces only that exact unknown RGB with the selected registered sector color, writes a new project, and marks topology caches for rebuilding. It never selects a target automatically. Repeat for each unknown color, then build and validate the resulting project. For connected sector cleanup, create a preview plan with `preview-sector-redistribution MyMod.project/project.json --type Region --sector-id 123 --output redistribution-plan.json`, review its component and target counts, then apply that plan with `apply-sector-redistribution MyMod.project/project.json redistribution-plan.json --output MyMod.project/redistributed`. The largest connected component remains assigned to the selected sector. Smaller fragments move only to a registered sector of the same type and subregion, chosen by shared boundary count, then target area, then numeric ID. Fragments without a safe target remain unchanged. The preview detects four-neighbor components and respects horizontal map wrapping. Applying creates a new project, invalidates dependent topology caches, and refuses a stale plan; the source project and sector catalog are preserved. Build the new project with `build-project`, then run `prepare-world` and `validate-world` before delivering the mod so ServerBase adjacency and map caches match the changed pixels. For boundary-spike cleanup, use `preview-boundary-spike-cleanup` before `apply-boundary-spike-cleanup`. Choose `--scope selected-subregion` with `--type` and `--subregion`, `--scope all-subregions-of-type` with `--type`, or `--scope all-subregions-of-all-types`. Defaults are four passes, four minimum pixels remaining in a sector, and one target contact edge. Only safe one-pixel-wide branches inside typed subregions are removed; the operation rejects bridges, entire thin sectors, disconnected starting sectors, and moves across sector types or subregions. It preserves every sector ID and nonzero area, validates sector connectedness, respects horizontal map wrapping, writes a new project, and refuses a stale preview. One subregion is limited to 4,000,000 planned pixel moves; if reached, narrow the scope or reduce the pass count and preview again. Build that project, then run `prepare-world` and `validate-world` before delivery. The JSON exposes Region, Sea, Ocean and Lake colors, Lake border values and recoloring flags, plus subregion membership by numeric IDs. The default mode updates colors while keeping each opaque RGB24 pixel assigned to the same sector and retaining map dimensions and chunk axes. For any complete world-source project, including a complete Earth map, `--allow-pixel-assignment-changes` supports splits by adding IDs and deletes/merges by omitting IDs and assigning every removed pixel to a surviving registered color. The transaction updates the registry, MapSettings, applicable ServerBase records, subregion membership, Lake-boundary links and derived country control records, and aborts before writing if supported sector references remain. After `build-project`, `prepare-world` regenerates ServerBase adjacency, MapSettings Lake boundaries and dependent map caches from the edited province map. Sector ID compaction uses `preview-sector-id-compaction` and `apply-sector-id-compaction`; the plan is revision-bound and unsupported binary layouts stop before output. Sector ID compaction supports clean version 9 scenario country data and remaps current military-entry and schema-v2 general-settings references. Persistent country payloads, active battle payloads and unsupported binary layouts are live simulation state outside static mod authoring; apply stops before writing output for them. ## Complete-project province-map editing For any complete world-source project, including a complete Earth map, use the explicit pixel reassignment mode and regenerate the package from the edited map: ```text python afterwar_modkit.py export-project NewWorld.awmod --output NewWorld.project python afterwar_modkit.py export-topology NewWorld.project/project.json --output topology.json python afterwar_modkit.py edit-topology NewWorld.project/project.json topology.json --allow-pixel-assignment-changes --output NewWorld.project/topology-edited python afterwar_modkit.py build-project NewWorld.project/topology-edited.project.json --output NewWorldEdited.awmod python afterwar_modkit.py prepare-world NewWorldEdited.awmod --output NewWorldPrepared.awmod python afterwar_modkit.py validate-world NewWorldPrepared.awmod ``` This mode requires every remaining sector to retain at least one pixel. To add or split a sector, include a new `sectors` record with a globally unused numeric ID, its `name`, `type` and unique RGB color, then assign pixels to that color. To delete or merge, omit the source record and reassign every pixel of its old color to a surviving registered color. The transaction updates the registry, MapSettings, applicable ServerBase records, subregion membership, Lake-boundary links and derived country control records; supported sector references are validated and any remaining references abort the edit. New Region, Sea and Ocean IDs start neutral with zero forces and population; new Lakes are MapSettings-only. Assign ownership only through a workflow that also updates country control records. Sector ID compaction uses `preview-sector-id-compaction` and `apply-sector-id-compaction`; the plan is revision-bound and unsupported binary layouts stop before output. Preparation rebuilds adjacency and dependent caches. For inherited Earth sources, first use `import-world-archive` with the matching `game_data.awreal` and optional existing mod to provide the complete source set. ## Existing-project map source layers For a partial Earth mod, import the game's `game_data.awreal` archive to supply the inherited map sources. Add `--mod ExistingEarth.awmod` to merge the existing mod on top of the game base. If you are starting without an existing mod, provide `--id` and `--title`: Start a new Earth mod: ```text python afterwar_modkit.py import-world-archive path/to/game_data.awreal --output Earth.project --id earth-map-edit --title "Earth Map Edit" ``` Merge an existing Earth mod: ```text python afterwar_modkit.py import-world-archive path/to/game_data.awreal --mod ExistingEarth.awmod --output Earth.project ``` Then edit and prepare the full source project: ```text python afterwar_modkit.py export-world-sources Earth.project/project.json --output map-sources.json python afterwar_modkit.py export-topology Earth.project/project.json --output topology.json python afterwar_modkit.py fill-world-height map-sources.json topology.json --mode land --output map-sources-land-filled.json python afterwar_modkit.py edit-world-sources Earth.project/project.json map-sources-land-filled.json --output Earth.project/maps-edited python afterwar_modkit.py build-project Earth.project/maps-edited.project.json --output EarthEdited.awmod python afterwar_modkit.py prepare-world EarthEdited.awmod --output EarthPrepared.awmod python afterwar_modkit.py validate-world EarthPrepared.awmod ``` `import-world-archive` copies only the current map/country source entries from `.awreal`, optionally overlays an existing `.awmod`, and creates editable project metadata. The built `.awmod` contains the complete source set, so it is larger than a typical partial overlay. The game executable is not required, but the authoring environment must have access to the `.awreal` file. The six PNGs preserve exact dimensions and chunk axes; Regions stays opaque RGB24, Height and Rivers stay grayscale, and other layers stay opaque RGB. Keep Region colors mapped to registered sectors and Biome colors mapped to the biome catalog. After editing, `prepare-world` rebuilds platform textures, topology and dependent caches; `validate-world` checks the prepared package and source references. The workflow does not resize or lossy-compress map images. Split, delete and merge are supported through this topology transaction; Sector ID compaction uses the revision-bound `preview-sector-id-compaction` and `apply-sector-id-compaction` commands. ## Existing-map replacement Export the mod to change and provide a complete map-source project. For an Earth source, create that project with `import-world-archive` using the matching local `game_data.awreal`; for a standalone source, use its existing complete world project. Then replace the target map and country source set while keeping the target mod metadata and non-map entries: ```text python afterwar_modkit.py replace-world-map ExistingMod.project/project.json EarthSource.project/project.json --output ExistingMod.project/new-map python afterwar_modkit.py build-project ExistingMod.project/new-map.project.json --output ExistingModNewMap.awmod python afterwar_modkit.py prepare-world ExistingModNewMap.awmod --output ExistingModNewMapPrepared.awmod python afterwar_modkit.py validate-world ExistingModNewMapPrepared.awmod ``` The source and target projects must contain the complete world-source entry set. Legacy environment stores missing from the source are removed. Other target reference-bearing entries are retained only when their country and sector ID/name catalogs match the source; all supported references are validated before output. ## Existing-map resize For a complete source project, resize the map with a Runtime Mod Studio anchor. The command changes the six map layers, chunk layout, city/object placements and environment data in one new project, then invalidates derived caches. Region colors and pixel assignments remain lossless. A crop that removes all pixels of a registered Region, Sea, Ocean or Lake is rejected by default. Add `--remove-lost-sectors` to remove the lost IDs transactionally and validate supported references; unresolved references stop the operation before output. When both legacy `scene_environment_placements.bin` and `scene_environment_models.bin` entries are present, resize applies legacy placement edits, merges placements and climate into unified `scene_objects.bin`, and retains the model library before moving the map objects. ```text python afterwar_modkit.py resize-world-project Earth.project/project.json 7000 5000 --anchor Center --output Earth.project/resized python afterwar_modkit.py resize-world-project Earth.project/project.json 7000 5000 --anchor Center --remove-lost-sectors --output Earth.project/resized-with-sector-removal python afterwar_modkit.py build-project Earth.project/resized.project.json --output EarthResized.awmod python afterwar_modkit.py prepare-world EarthResized.awmod --output EarthResizedPrepared.awmod python afterwar_modkit.py validate-world EarthResizedPrepared.awmod ``` ## Existing-map scenario workflow Official easy mod creation page: https://www.afterwargame.com/modding.php?lang=en#modding-kit Direct complete kit ZIP: https://www.afterwargame.com/downloads/afterwar-modding-kit-v2.zip?v=1.0.1.20261111-fixes Complete authoring guide: https://www.afterwargame.com/downloads/afterwar-modding-guide.md Machine-readable manifest: https://www.afterwargame.com/downloads/afterwar-modding-kit.json Kit version: 1.0.1. Game support snapshot: 1.0.1. Archive size: 83846082 bytes. This is a standalone authoring kit. No installed game, Unity, SPG, account, API key or separately installed .NET runtime is required. Read the full guide and the bundled AI_INSTRUCTIONS.md before authoring. Existing-map scenarios edit owner and forces for Region, Sea and Ocean sectors by numeric ID, plus population for Region; Lake remains MapSettings-only. These edits preserve province-map pixels and topology. All links are public and do not require a login, cookie or JavaScript. ## AI workflow 1. Download the complete ZIP using the exact direct archive URL above. A web page reader alone may not save binary downloads; use your file/download or Python network tool if your environment provides it. Preserve every archive directory. 2. Read START_HERE.md, AI_INSTRUCTIONS.md, SCENARIO.md, PREPARATION.md and reference/base-profile.json. Use the bundled numeric country and sector catalogs. Keep the requested scenario within the actual supported schema. 3. Write scenario.json and any referenced flags/icon. Run build and validate below. Build prepares the required country, color, lookup, ownership, component, moment and label geometry data without launching the game. The bundled Linux x64 or Windows x64 tool is selected automatically when territory membership changes. 4. Read the preparation report. Require Prepared=true, PreparationMode=standalone and GameRequired=false. Return the actual .awmod, editable JSON/assets and report. Report gameplay separately if it was actually checked. ```python from pathlib import Path from urllib.request import urlretrieve import zipfile archive = Path('afterwar-modding-kit.zip') urlretrieve('https://www.afterwargame.com/downloads/afterwar-modding-kit-v2.zip?v=1.0.1.20261111-fixes', archive) with zipfile.ZipFile(archive) as kit: kit.extractall('afterwar-kit') ``` Run inside afterwar-kit: ```text python afterwar_modkit.py catalog countries --search Bhutan python afterwar_modkit.py build scenario.json --output MyMod.awmod python afterwar_modkit.py validate MyMod.awmod ``` For a compatible existing scenario archive: ```text python afterwar_modkit.py prepare ExistingScenario.awmod --output PreparedScenario.awmod ``` No --game argument is used. Missing game files are never a reason to produce an unprepared draft. The kit includes its reference data and standalone geometry tools. Python 3.10+ and file/code execution are needed. If your environment cannot download or execute files, say so and provide editable JSON; do not claim a prepared binary exists. ## Scope Use the Earth scenario schema for supported changes to an existing map, or the independent-world schema for a new map and numeric IDs. Scenario and world country schemas support startup controls, full partial AIData settings, naval bases, political will, mobilization costs, debt timers and budget shares; world country records also support starting reserves, research and factories. World JSON can author city and town records with `cities`; existing projects can decode/edit `scene_cities.bin` through the city catalog schema, object slots/placements/models through `scene-objects.schema.json`, and biome definitions/materials through `scene-biomes.schema.json`. Existing projects can also export and edit the current environment profile and baked placement catalog with `map-environment-settings.schema.json` and `map-environment-edits.schema.json`, and export or replace loading-background slideshow images with `loading-backgrounds.schema.json`. Country artwork credits can be decoded from an exported project, edited through `content.schema.json`, and rebuilt. For any existing mod, export and edit all 85 fixed current Runtime Mod Studio archive entries plus accepted dynamic entries through the generic project workflow. Structured JSON builders cover map controls and cities, decisions, formations, news/events, selected political records, alliances, initial military deployments, leaders, localization, difficulty profiles, UI appearance, ideologies, state traits, leader effects and audio. Other entries remain editable in their original binary format; see CONTENT_AUTHORING.md for exact authoring and validation coverage. New executable mechanics require engine support. Do not silently replace an original-world request with an Earth adaptation. Scenario and world country records support complete partial AIData updates through `ai_settings`. In an existing project, use `export-ai-settings` to decode `serverbase_ai.bin`, edit the JSON, and use `edit-ai-settings` to update, create or remove country records. The final `build-project`/`validate` checks the binary structure and numeric country/sector references. See `ai-settings.schema.json` and the Full Runtime Mod Studio AI settings section in CONTENT_AUTHORING.md. ```text python afterwar_modkit.py export-project MyMod.awmod --output MyMod.project python afterwar_modkit.py export-ai-settings MyMod.project/entries/serverbase_ai.bin --output ai-settings.json python afterwar_modkit.py edit-ai-settings MyMod.project/entries/serverbase_ai.bin ai-settings.json --output serverbase_ai.edited.bin python afterwar_modkit.py export-map-cities MyMod.project/entries/scene_cities.bin --output cities.json python afterwar_modkit.py edit-map-cities MyMod.project/entries/scene_cities.bin cities.json --output scene_cities.edited.bin python afterwar_modkit.py build-project MyMod.project --output MyModEdited.awmod python afterwar_modkit.py validate MyModEdited.awmod ``` Unchanged game textures and geometric caches are inherited when playing. The AI does not need the installed game to create the supported scenario. Prepared caches do not mean instant loading or a completed gameplay test. A newer game may warn about the informational support version but does not block the mod for that reason. ## Example user request > Read the current AfterWar AI modding instructions at https://www.afterwargame.com/downloads/afterwar-ai-start.md and follow them. Download the complete standalone kit from https://www.afterwargame.com/downloads/afterwar-modding-kit-v2.zip?v=1.0.1.20261111-fixes yourself. > > Create an AfterWar mod: [describe the scenario or your own universe, map and starting situation]. > > Requested changes: [describe the countries, territories, relations, troops, economy, player control, naval bases and budget settings you want to change]. > > Choose the scenario workflow for an unchanged map, or the independent world workflow for your own universe and map with its own country and sector IDs. Generate and validate caches from that world's actual sources. Ask only for important missing details. > > Build the .awmod with its required caches, run the kit validator on the generated archive, and return the finished .awmod, the editable world.json or scenario.json with its source assets, and the preparation report. An installed game must not be required for authoring. > > If your current chat cannot download files or execute the builder, explain that limitation before claiming that a mod has been built. ## What is prepared | Result | Preparation | | --- | --- | | Canonical countries | Ownership lists, borders, populations, research totals, greatness and stable country keys | | Country color cache | Numeric country IDs and exact RGBA colors | | Server lookup cache | Existing land/sea/ocean IDs and country IDs | | Ownership visuals | All sectors, current country colors, neutral sea/ocean policy and same-owner enclosed lake shores | | Country region cache | Connected country components and exact per-region pixel moments | | Country label geometry | Source membership, wrapped geometry, enclosed lakes, layout settings and component identities | When membership is unchanged, exact usable bundled geometry is reused. Territory changes invoke engine/linux-x64/AwmodCacheTool or engine/win-x64/AwmodCacheTool.exe. Both include their runtime and need no .NET installation. The tool is a standalone kit utility with extracted geometry algorithms, not the game. Its buildable source and .NET runtime notices are included under engine/. Unchanged map textures, geometry, rivers and geometric boundary caches are inherited from the matching game when playing. They are unnecessary on the authoring machine. Runtime player/trade/font/glyph/active text placement, GPU uploads, materials and simulation remain runtime work. Prepared output does not promise instant loading or compatibility with arbitrary combinations of mods. The reference is the included Earth map profile. Arbitrary old patch archives and new world geometry are outside this schema and are rejected rather than labelled prepared. New sector IDs can be authored in complete world-source projects through the topology workflow described above. Game support version comes from the publisher-exported Windows AW Release snapshot, not the AI's guess. No additional compatibility hashes are written. ## Reports and deterministic output The builder writes a companion .preparation.json outside the archive. Require Prepared=true, PreparationMode=standalone and GameRequired=false. GeneratedEntries lists canonical countries and all five caches. The validator checks exact color/lookup/ownership data, complete country component membership, recorded component identities and agreement between the region and layout caches. ZIP entry order and timestamps are fixed. Original input archives and existing outputs are not replaced. All authoring requires only Python 3.10+ and the complete kit. Changed-territory preparation uses Linux x64 or Windows x64. No game path is needed. Linux executables use the bundled .NET runtime and standard system C libraries. A process may need temporary disk space for runtime extraction and geometry output; preparation cleans its own temporary directory. ## Version information modsettings.bin keeps the mod's own version separate from latestSupportedGameVersion. The current published Windows AW Release snapshot is 1.0.1. Newer games show a warning, while enabling and playing remain allowed. Missing versions do not form a launch barrier. Compare numeric release first, then an optional numeric suffix, with no suffix=0: - 1.0.1 - 1 > 1.0.1 - 1.0.1 - 2 < 1.0.2 - 1.0.2 - 3 > 1.0.1 - 6 ## Explicit drafts ```text python afterwar_modkit.py build scenario.json --draft --output WorkInProgress.awmod python afterwar_modkit.py validate WorkInProgress.awmod --allow-draft python afterwar_modkit.py prepare WorkInProgress.awmod --output Finished.awmod ``` Drafts are optional work in progress, never a requirement caused by a missing game. Validation and preparation are not gameplay tests. ## Scenario JSON, version 1 Encode JSON as UTF-8. Unknown properties are rejected so typos do not silently disappear. Omitted properties keep baseline values. IDs are numeric and stable only within the bundled profile. Read `reference/countries.csv` and `reference/sectors.csv`. ## Root | Property | Type | Meaning | | --- | --- | --- | | `schema_version` | integer, required | Must be `1` | | `profile` | string, required | Exact ID in `reference/base-profile.json` | | `id` | string, required | 1–64 ASCII letters/digits/underscore/hyphen, starting with a letter or digit; stable identity for this mod | | `title`, `author`, `version`, `description` | strings, required | English title 2-30 characters, full description 100-1000; author and mod version must be nonempty | | `short_description` | string | English public summary, 20-100 characters; defaults to the first 100 characters of description | | `icon` | relative JPEG path | Optional 512x512 JPG within 16 MiB, included as icon.jpg | | `latest_supported_game_version` | string | Draft metadata only; native export replaces it with the release-profile/executable version. Informational warning, never a launch block | | `date` | `[year, month, day]` | Valid Gregorian date, years 1–9999; hour/minute become zero | | `countries` | array of objects | Country edits, unique existing IDs | | `territories` | array of objects | Whole-country land transfers | | `sectors` | array of objects | Individual Region, Sea and Ocean edits, applied after transfers | | `wars` | array of `[countryID, countryID]` | Replaces the initial war list, with both directions generated; `[]` means no starting wars | ## Countries Every object needs `id` (existing country ID, not zero). Optional fields: | Property | Type / range | Meaning | | --- | --- | --- | | `name` | 1–200 visible characters | Unique faction label, updates registry and display fields | | `color` | `#RRGGBB` | Country display color, stored with alpha 255 | | `flag` | relative PNG path | RGB/RGBA 8-bit PNG inside the scenario directory, at most 16 MiB; stored unchanged | | `capital_sector_id` | existing land ID | Must belong to this country after all transfers | | `money` | integer ≥ 0, int64 | Starting money | | `stability`, `corruption` | integers 0–100 | Starting percentages | | `land_forces`, `sea_forces`, `air_forces` | integers ≥ 0, int64 | Country-level starting reserves, not newly placed divisions | | `factories` | integer ≥ 0, int32 | Factory count | | `research_seas`, `research_oceans`, `research_airpower` | integers ≥ 0, int32 | Research counters; their sum must fit int32 | | `exists` | 0 or 1 | Existing scenario field; normally let territory transfers determine this | The kit preserves baseline AI configuration for existing faction IDs, naval bases, leaders, political metadata, other economy fields and unedited assets. Renaming a faction does not automatically rewrite its leaders or lore. Starting army divisions are not supported. `sectors[].forces` changes the legacy sector force field, not a full army composition. ## Territory transfers ```json "territories": [ {"from_country_id": 16, "to_country_id": 31} ] ``` All original land sectors of source 16 move to country 31. Transfers are simultaneous against original ownership: `A в†’ B` followed by `B в†’ C` does not also move A's former land to C. Each source appears once. Sea/ocean controls are preserved. Land ownership is not a texture operation and does not change sector shapes or adjacency. ## Individual sectors ```json "sectors": [ {"id": 1, "sector_type": "Region", "owner": 31, "population": 500000, "forces": 0}, {"id": 41132, "sector_type": "Sea", "owner": 31, "forces": 0}, {"id": 41131, "sector_type": "Ocean", "owner": 0, "forces": 0} ] ``` Use unique numeric IDs from `reference/sectors.csv`. Existing Region, Sea and Ocean records can be edited; `sector_type` is optional but, when provided, must match the registry. Lake is stored only in MapSettings and cannot be assigned to ServerBase. `owner: 0` means neutral; nonzero owners must be existing country IDs. `forces` is a nonnegative int64 value for all three types. `population` is a nonnegative int64 value for Region only. Country population totals and control/border collections are prepared after sector edits. Research totals and greatness are prepared from the resulting statistics. The builder checks reciprocal adjacency but does not change topology or the RGB24 province map. If a country loses its capital through a transfer, the builder chooses its lowest remaining land ID and reports it. If it loses all land, its capital becomes zero and `exists` becomes zero. Set explicit intended capitals for important factions. Review reports rather than assuming this fallback picks a meaningful city. The kit does not rename or create cities. ## Derived data and complete output `build scenario.json --output MyMod.awmod` generates all required scenario caches by default without the game. `prepare ExistingScenario.awmod --output Ready.awmod` also runs standalone. Read PREPARATION.md. Country statistics and five caches are prepared: country colors, server lookup, ownership visuals, connected country regions with moments, and country label layout geometry. Unchanged map geometry, textures, rivers and visual boundaries are inherited unchanged. Three dynamic/inlined entries are invalidated: scene_mapKernel.bin, scene_countryTextPlacementProjectionCache.bin and scene_countryTextPlacementCandidates.bin. The generated caches replace their inherited counterparts and are never simultaneously deleted. The builder includes the exact base's deployed land totals for greatness. Sector `forces` still edits only the documented legacy field, not a deployed army composition. The scenario workflow uses the included Earth map and registered IDs. The independent-world workflow creates another map with its own country and sector IDs, canonical binaries and caches; see WORLD.md. ## Verified `.awmod` scenario profile This describes the scenario subset emitted by kit v2, refreshed against the 2026-10-21 AfterWar baseline and serializers. It is not a complete schema for every game release, player save or map-editor entry. The bundled Python source is the executable codec reference for the layouts below. ## Container `.awmod` is a ZIP overlay over the installed `.awreal`. Entry names are flat, case-sensitive, exact names such as `serverbase_countries.bin`. An entry in the mod replaces the complete same-named entry in the base. Missing entries inherit from the base. The kit uses ZIP DEFLATE, lexically sorted names, a fixed `1980-01-01 00:00:00` timestamp and no custom hash files. Identical inputs yield identical output in the same Python/zlib environment; compression bytes across different library versions are not guaranteed. The game also supports binary patch entries. The Python builder emits full replacements and does not parse `mod_entry_patches.bin`. This standalone kit does not resolve old positional patches. The Python validator accepts this scenario subset plus recognized derived entries; it is not a validator for arbitrary third-party `.awmod` archives. Ordinary scenario/map entries are binary. The existing `modsettings.bin` in `.awmod` is the game's UTF-8 JSON metadata exception; do not replace it with a guessed binary structure. No JSON files are inserted into `.awreal` by this kit. All primitive binary values are little-endian. A string is int32 byte length followed by UTF-8, with `-1` for null. Booleans occupy one byte. IDs use uint16 for countries and int32 for sectors. Zero is the absent/neutral ID. Region=0, Sea=1, Ocean=2, Lake=3. ## Metadata and deletion list `modsettings.bin` JSON contains `author`, `version`, `supportedLanguages: ["en"]`, `titles: {"en": "..."}`, `shortDescription: {"en": "..."}` and `description: {"en": "..."}`. Other game metadata fields exist but are not emitted here. `special_id.bin`: int32 `0x53494430`, int32 version `1`, then a string containing the stable mod ID. `mod_deleted_entries.bin`: int32 count, then that many entry-name strings. Deleted inherited derived entries are not simultaneously replaced. See `SCENARIO.md` for the exact invalidation set. ## Registries and colors `registry_countryIds.bin`: int32 count, then `(uint16 ID, string name)` records. `registry_sectorIds.bin`: int32 count, then `(byte kind, int32 ID, string name)` records. Lakes are included here but have no ServerBase record. This file is used as a reference and inherited by emitted mods. `mapsettings_countries.bin`: int32 count, then `(uint16 ID, byte R, byte G, byte B, byte A)` records. `flags.bin`: int32 count, then `(string filename, int32 payload length, raw image bytes)` records. Replacing one flag replaces the full flags entry, retaining all other flags. ## Raw country container version 9 `serverbase_countries.bin` starts with int32 `-2000000421`, int32 version `9`, int32 `-count-1`. Each record is uint16 dictionary country ID followed by CountryBinary. CountryBinary starts with int32 `-2` and a uint16 reference ID, or int32 `-1` for a null reference. Preserve that representation exactly, then read: 1. int32 `exists`, bool `startFightBlock`, int32 `CapitalSectorId`, int32 `NavalBaseSectorId`, byte `NavalBaseSectorType`. 2. Six control dictionaries: `ControlRegions`, `ControlSeas`, `ControlOceans`, `BorderRegions`, `BorderSeas`, `BorderOceans`. Each is int32 count then `(int32 sectorID, uint16 value)` records. Membership values are country IDs; prepared border values are zero. 3. Empty `BattleInfos` list (int32 zero). 4. 18 int32 values in order: `Stability Corruption gameStart PlayerOrNot Zavod per_corr per_stab per_zav per_res per_land per_sea per_air slreal_money researches_num r_airpower r_oceans r_seas defolt_time`. 5. 15 int64 values: `Money Population AirForcesNum SeaForcesNum LandForcesNum slmoney_CorruptionDeFacto slmoney_StabilityDeFacto slmoney_ZavodDeFacto slmoney_ResearchDeFacto slmoney_AirForcesDeFacto slmoney_SeaForcesDeFacto slmoney_LandForcesDeFacto dailyPopulationIncrease dailyPopulationDecrease MoneyDay`. 6. Strings `Name PlayerName flagName`; float32 `PolitVolya greatness_factor mob_politVolyaCost`. 7. Empty activeTradeDeals and tradeDeals collections; uint16 `CurrentAllianceId`; six empty collections: allianceRequests, allianceInvitations, peaceRequests, allianceJoinRequests, warPreparations, tradeRequests. 8. int32 war-country count and uint16 country IDs; 12 int32 signal values. 9. int64 `tradeIncomeTotal allBudget cachedControlPopulationTotal`, int32 `cachedControlPopulationVersion`, float64 `populationChangeRemainder`, int32 `ConsecutiveWarDays`, string `SessionDisplayName`. This kit rejects nonempty running-game battle/diplomacy collections and compact player-save records. It is a clean-scenario codec, not a save editor. The profile has no initial alliances; `serverbase_alliances.bin` contains int32 `-2000000422`, version `3`, count `0`. AI data is inherited unchanged. ## Raw sector records Each of `serverbase_regionSectors.bin`, `serverbase_seaSectors.bin`, `serverbase_oceanSectors.bin` starts with int32 `-count-1`, int32 key marker `-3`. Records begin with int32 dictionary sector ID. Region records contain int64 population and int64 forces. Sea/Ocean records contain int64 forces. They then contain byte control encoding `1`, uint16 owner ID. Region and Ocean include int32 extended marker `0x53454232` and byte version `1`; Sea has no extended header in this profile. Three neighbor dictionaries follow. Region order is Region, Sea, Ocean; Sea/Ocean order is Sea, Ocean, Region. A neighbor dictionary starts with int32 `-count-1`. Empty is just `-1`. Nonempty additionally contains int32 `-4`, int32 `-2`, byte neighbor kind, byte flags `0`, then `(int32 neighbor sector ID, uint16 value)` pairs. Existing adjacency, including its values, is preserved. Next is battle data: bool active, int32 battle-sector ID, string fight style, eight empty lists, two float32 values. The kit preserves these clean inactive bytes. It accepts inactive battle-sector ID zero or the containing sector ID. Finally int32 `0x53494431` and int32 sector ID repeat the record identity. ## Date `serverbase_timeGame.bin` starts with five int32 values: minute, hour, day, month, year. The remaining speed/pause metadata bytes are preserved. The builder changes those five fields only. ## Map assets outside this kit A new world needs consistent map settings, all sector registries, a lossless RGB24 province/color-ID map, geography and height data, chunk meshes and derived state. The color map is not an ordinary illustration: each exact RGB color identifies a sector. HeightTexture is grayscale. Maximum map dimensions are 8192 Г— 8192. Region and normal textures must have no transparency. Lakes exist only in MapSettings, and lake names have no numbered-sector suffix. Do not fabricate a new world by changing one registry or adding an arbitrary PNG entry. Prepare and validate it in Mod Studio. ## Existing-map scenario profile The current template has 296 registered country IDs. Country container remains raw v9. The encoded Country reference can be marker -2 followed by ushort ID, or marker -1 for null. Preserve this reference exactly; the dictionary ID remains the gameplay key. Dormant formation slots may use null references. The Python reader/writer supports both representations. modsettings.bin now carries latestSupportedGameVersion separately from the author's version. It does not block loading. The standalone builder stamps the publisher-exported Windows AW Release version from the bundled profile. Release comparison is numeric with an optional build suffix after a hyphen; see PREPARATION.md. Prepared output includes the five supported caches generated by this kit. The standalone validator verifies their identities, membership and binary consistency. Drafts retain the existing deletion list for affected ownership/text caches; generated replacements remove corresponding tombstones. Dynamic text-placement caches can remain invalidated. No additional hash fields or archive entries are introduced. The English metadata dictionary key is `English`, matching the game default language. The kit emits that key; the Python validator can also read the legacy v1 `en` key. ## Standalone preparation The current build and prepare commands work without the game. The independent CPU geometry tool and its self-contained runtimes are included in engine/. reference/cache-data.zip contains the exact reference map geometry needed to build supported scenario caches. These kit-side files are not mod entries and must never be copied wholesale into an .awmod. Prepared archives include mapsettings_countryColorCache.bin (v1), serverbase_lookupCache.bin (v1), scene_ownershipCache.bin (160 bytes per sector), scene_countryTextRegionCache.bin (marker -12), and scene_countryTextLayoutGeometryCache.bin (marker -13). They use existing binary formats and existing internal dependency fields; no new hash entries are introduced. Canonical country records use raw v9 and explicit numeric country keys. See PREPARATION.md for dependencies and AI_INSTRUCTIONS.md for the required delivery workflow. Package display metadata: builds record latestSupportedGameVersion, mapWidth and mapHeight in modsettings.bin. Map dimensions come from the included profile. The Workshop measures package size outside the archive; these fields are informational and do not add a game-version launch restriction. ## Custom local time and calendars Calendar authoring is available in the game Mod Studio Time tab and in this standalone kit. See CALENDAR.md inside the ZIP. Add `"calendar": {"preset": "mars"}`, `"date": [1, 1, 1]` and optionally `"time": [0, 0]` to the scenario, or edit examples/mars-calendar.json. Months, weekdays, leap rules, clock units and the duration of a local day are editable. A calendar change alone keeps the scenario map. Use build-world with your own planet map to create an independent Mars world. The kit builds and validates the binary calendar without an installed game. To play a custom-calendar mod, use an AfterWar build containing custom-calendar support. latestSupportedGameVersion remains informational and is not a launch gate. Old packages without a calendar extension keep the existing Earth calendar. ## Explicit supported languages The author must choose the languages supported by this mod. Add `"supported_languages": ["English"]` to scenario.json, replacing English with the actual selection. Ask the author when it is missing. In Mod Studio use Metadata > Supported languages. The new field does not generate translations or infer support from the base game or store descriptions. See LANGUAGES.md inside the ZIP. Old packages without a declaration show Not specified and remain readable; language support does not block launch.