- ADDING-A-MECH.md: full workflow for adding a 'Mech chassis (MSL ADD MECH touch points, positional Mech IDs, scriptaddmech.xls generator, hardpoints in .damage, rebuild/repack/deploy steps) - ADDING-A-MAP.md: full workflow for maps (MapCreator terrain) vs missions (MW4Ed2-authored), .nfo MP registration, user vs stock routes, pitfalls - CLAUDE.md: reference pointers to both new docs - README.md: annotated folder map; warning to read RECOVERY.md before cloning Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
12 KiB
Adding a new map / mission — full workflow
How to add a new playable map (terrain) and mission (scenario) to BattleTech: FireStorm (MW4/Gameleap 5.03 engine). Reconstructed 2026-07-01 from the repo. Companion doc: ADDING-A-MECH.md.
The big picture — maps are NOT like mechs
Adding a 'Mech touches compiled code and a dozen parallel index arrays. Adding a map/mission
touches none of that: there are no MSL ADD MAP markers, no Mech-ID-style positional
tables, and no exe rebuild. Maps and missions are discovered at runtime by file
enumeration and registered by per-mission files, so the whole job is content + packaging.
Two separate things, often confused:
| Thing | Lives in | Packs to | What it is |
|---|---|---|---|
| Map | Content\Maps\<Map>\ |
resource\maps\<map>.mw4 |
Terrain only: tile geometry, materials, HUD overview image |
| Mission | Content\Missions\<Name>\ |
resource\missions\<name>.mw4 |
A playable scenario on a map: placed objects, drop zones, AI nav, scripts, game types |
Several missions can share one map (e.g. Maps\Minerl03 hosts both Cantina and
CantinaSiege; Maps\Reduex hosts Reduex + ReduexSiege).
The original mod-toolkit documentation survives in _UNUSED/Gameleap/EditorDocs/: Map Creation Tutorial.doc, Simple Map Creation Tutorial.doc, Terrain Generation.doc, Map Creator.rtf, Material_Map.rtf, NFO File Editor.rtf, Editor_Tutorial.rtf, plus the ABL tutorials (ABL_Mission_Tutorial.rtf, ABL_Brain_Tutorial.rtf, ABL_Orders.rtf) and sample heightfield/colormap/detailmap TGAs. Read those for tool operation; this doc covers how the pieces wire into this repo.
The tools ship in the dev tree root (Gameleap\mw4\): MapCreator.exe/MapCreatora.exe
(terrain generation), Tctd.exe (terrain color/texture data), NFOEditor.exe (MP .nfo
registration), ERF Deluxe.exe (erf inspection), and the mission editor MW4Ed2.exe
(launch via Gameleap\mw4\run-editor.bat — fully working per CLAUDE.md STEP 8/9).
Part 1 — The MAP (terrain): Content\Maps\<Map>\
Source art is a set of TGAs (heightfield, colormap, detail map, material map — see the
Terrain Generation / Material_Map docs and their sample TGAs). MapCreator turns them
into the terrain tile set; Tctd generates tctd.ini.
Using Maps/StormCanyon/ as the template:
| File | Purpose |
|---|---|
<Map>.build |
Pack manifest: [resource\maps\<map>.mw4] + instance= + TexturePool=textures\maps\<Map>\textures.hint |
<Map>.instance |
One page: model=<Map>.data, executionstate=AlwaysExecuteState |
<Map>.data |
[gamedata] class=mechwarrior4::mwmap, grid=<Map>.erf, hudmap=hud\<map> |
AA..CC .erf/.bsp/.Material |
The terrain tile grid (3×3 for StormCanyon), geometry + BSP + per-tile material properties — generated by MapCreator |
<map>.erf |
The terrain grid referenced by grid= |
tctd.ini |
Terrain color/texture data — generated by Tctd.exe |
Plus two texture registrations:
- Map textures:
Content\textures\Maps\<Map>\*.tgawith their owntextures.hintin that folder (referenced by the map.build'sTexturePool=). - HUD overview image: the
.data'shudmap=hud\<map>needs an[hud\<map>]entry in the master Content/textures/textures.hint with the TGA inContent\textures\HUD\(packs intotextures.mw4).
Part 2 — The MISSION: Content\Missions\<Name>\
Work in the editor. MW4Ed2 creates a new mission by cloning
Content\Missions\EditorTemplate\ (scripts, sounds, lights —
GameInterface.cpp:1352) onto a
map you pick, and on save writes all the files below back into Content\Missions\<Name>\.
File roles, using Missions/StormCanyon/ as the
template ("(editor)" = generated/maintained by MW4Ed2; hand-edit only the rest):
| File | Purpose |
|---|---|
<Name>.build |
Pack manifest: [resource\missions\<name>.mw4] + texturepool=<name>.hint, Instance=, directory=...\scripts, Soundpool=<name>.sounds. The [resource\...] page name is the published .mw4 path — stock MW4 missions abbreviate (CentralPark→cpark.mw4); FireStorm ones keep the full name |
<Name>.instance |
The hub: model=<name>.data, map=maps\<map>\<map>.instance, props=<name>.contents, sky=/nightsky= (an erf from Content\Skies), missionbounds/warningbounds, nametable=, railgraph=, script= |
<Name>.data |
Environment: fog banks, weather effects, clip planes, allowrespawn, heatsinkefficiency, isnightmission, lights=/nightlights= (editor) |
<Name>.contents |
Every placed object. Includes the drop zones: [dropteam1..4] + [playerstart] sections (Model=Misc\DropZone\DropZone.data, DropPoints=DropZones\DropTeamN.contents) — per-team spawn-point sets; this is the "≥N drop points per map" constraint from the MP-cap plan (editor) |
<Name>.ini |
Editor metadata per object (type=dropzone/helper, invulnerable, snaptoground…) (editor) |
<Name>.table |
Name↔ID replication table (editor) |
<Name>Graph.data, <Name>MoveGrid.data, <Name>RectGrid.data, <Name>AirMoveGrid.data |
AI rail graph + ground/air pathing grids (editor — SaveRailGraph) |
<Name>.lights, <Name>night.lights, <Name>_lightmap.raw |
Day/night lighting + baked lightmap (editor) |
Mission.bounds, Warning.bounds |
Playable-area polygons (editor) |
<Name>.hint, <Name>.sounds |
Mission-local texture pool + sound pool |
Scripts\*.abl |
Mission logic in ABL: a base <Name>.abl, player.abl, and one script per supported game type (<Name>_Destruction.ABL, _TeamDestruction, _Attrition, _CTF, …) referenced from the .nfo (see Part 3). ABL docs in EditorDocs |
Part 3 — Registration (how the game finds it)
There are two routes, and FireStorm's own maps (Freezer, StormCanyon, Nazca…) use Route B:
Route A — user mission (zero manifest edits)
The editor can save/publish straight to Resource\UserMissions\: the compiled
<name>.mw4 + .nfo + a 112×112 overview .tga
(GameInterface.cpp:1443).
User missions are auto-discovered: the MP host list enumerates
Resource\UserMissions\*.nfo and Instant Action enumerates Resource\UserMissions\*.mw4
(MW4Shell.cpp:4331). Nothing else to edit.
Good for prototyping; the deployed game (C:\VWE\firestorm\MW4) currently ships 0 of these.
Route B — stock mission (first-class FireStorm content)
- Content/MechWarrior4.build — add the
nested pair (mission inside its map, expressing the dependency):
(If the map already exists, add only the mission line inside its block.) The editor has an
maps\<map>\<map>.build={ missions\<name>\<name>.build={ } }AddToBuildFile()for this but its call is commented out (GameInterface.cpp:1453) — edit by hand. Resource\Missions\<Name>.nfo— the multiplayer registration, a loose text file (never packed; the deploy copiesResource\wholesale). The shell enumeratesResource\Missions\*.nfo(MW4Shell.cpp:12546) and reads:[info](longname= lobby display name,author), and[scenarios]— one nested[server]page per offered game type withname,ruleset=$(CustomDestruction)etc. (constants from Content/GameTypes.h),teamAllowed/teamcount,scenariotext, and the matchingscriptname=...\Scripts\<Name>_<type>.abl. Copy StormCanyon.nfo as the template (or useNFOEditor.exe; NFO File Editor.rtf documents it).- Tables/missionnames.tbl — the
resource-name redirect table (packed into
core.mw4). Stock MW4 rows map long names to abbreviated .mw4 names; FireStorm rows are self-mappings. Addresource\missions\<Name>.mw4=resource\missions\<Name>.mw4under// BTFRSTRM Missions. - Instant Action (optional) — the IA mission list = campaign-defined missions + user
missions (GetMissionNames, MW4Shell.cpp:4297).
To surface a stock mission in IA, add a page to
Campaigns/InstantAction.Campaign
(
[content\missions\<name>\<name>.instance]withStatus=Displayed, display-name string, rollover text, map thumbnail). Campaign files pack viaprops.buildCampaign=lines. - Sky — reuse an existing sky from
Content\Skies(already packed inskies.mw4); a new sky means a new entry inContent\skies.build. Beware the STEP 8 lesson: the.instancesky=path must match the erf filename exactly (case/name).
Part 4 — Build, deploy, verify
- No exe rebuild. Repack resources with
build-env\build-resources.ps1(wrapsMW4pro.exe -build; LAB_ONLY builds only — see build-env/RESOURCE-BUILD.md). Output:resource\maps\<map>.mw4+resource\missions\<name>.mw4, plustextures.mw4/core.mw4if you touchedtextures.hint/missionnames.tbl. - Redeploy with
build-env\deploy-mw4.ps1(copiesResource\— including the.nfo— and the repacked packages intoC:\VWE\firestorm\MW4). - Verify:
MW4Ed2.exe <MissionName> -report— headless load of the mission (same path the editor uses; catches broken refs without clicking through the UI).- Open it in the editor: drop zones present for every team, AI grids regenerate cleanly.
- Host a LAN game: mission appears in the host list under each declared game type with the
.nfolongname; all teams spawn at theirdropteam*zones; HUD overview map shows. - If IA-registered: appears in the Instant Action mission dropdown.
Known pitfalls (all hit during STEP 7/8 content curation — the editor STOPs hard)
- The editor loads every mission/map at startup (
ObjMan->BuildResources()) and LAB builds STOP fatally on the first defect — one broken mission breaks editor startup for everything. - Name consistency is everything: the folder name, the
[page]name in.build/.instance, and the file basenames must agree (the_backup-dir andPhoenixPalaceSTBincidents).Map=in the mission.instancemust point at a map that actually exists (thearctic01/lunar02dangling refs). - The mission
.instanceModel=must reference the[gamedata]-class page (<name>.data), not some other page (hill.contentsincident). .mw4package names in.buildpage headers are the published identity — changing one orphans the old.dep/.mw4inResource\.
Quick-reference: every touch point (Route B stock mission on a new map)
TERRAIN Content\Maps\<Map>\ (.build/.instance/.data + MapCreator tiles + tctd.ini)
Content\textures\Maps\<Map>\ (map textures + own textures.hint)
Content\textures\textures.hint ([hud\<map>] entry) + Content\textures\HUD\<map>.tga
MISSION Content\Missions\<Name>\ (editor-authored: ~18 files, see Part 2)
Content\Missions\<Name>\Scripts\*.abl (one per game type + player.abl)
REGISTER Content\MechWarrior4.build (nest mission .build under map .build — manual)
Resource\Missions\<Name>.nfo (MP game types; loose file, not packed)
Content\Tables\missionnames.tbl (self-mapping row; packs into core.mw4)
Content\Campaigns\InstantAction.Campaign (optional, for IA list)
BUILD build-env\build-resources.ps1 → deploy-mw4.ps1
TOOLS MapCreator.exe / Tctd.exe / NFOEditor.exe / MW4Ed2.exe (run-editor.bat)
DOCS _UNUSED\Gameleap\EditorDocs\ (original tutorials: map creation, terrain, NFO, ABL)