Files
firestorm/ADDING-A-MAP.md
CydandClaude Fable 5 e84d6e603c Document mech + map/mission workflows; README folder map + clone warning
- 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>
2026-07-01 21:15:52 -05:00

12 KiB
Raw Permalink Blame History

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:

  1. Map textures: Content\textures\Maps\<Map>\*.tga with their own textures.hint in that folder (referenced by the map .build's TexturePool=).
  2. HUD overview image: the .data's hudmap=hud\<map> needs an [hud\<map>] entry in the master Content/textures/textures.hint with the TGA in Content\textures\HUD\ (packs into textures.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 (CentralParkcpark.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)

  1. Content/MechWarrior4.build — add the nested pair (mission inside its map, expressing the dependency):
    maps\<map>\<map>.build={
    missions\<name>\<name>.build={
    }
    }
    
    (If the map already exists, add only the mission line inside its block.) The editor has an AddToBuildFile() for this but its call is commented out (GameInterface.cpp:1453) — edit by hand.
  2. Resource\Missions\<Name>.nfo — the multiplayer registration, a loose text file (never packed; the deploy copies Resource\ wholesale). The shell enumerates Resource\Missions\*.nfo (MW4Shell.cpp:12546) and reads: [info] (longname = lobby display name, author), and [scenarios] — one nested [server] page per offered game type with name, ruleset=$(CustomDestruction) etc. (constants from Content/GameTypes.h), teamAllowed/teamcount, scenariotext, and the matching scriptname=...\Scripts\<Name>_<type>.abl. Copy StormCanyon.nfo as the template (or use NFOEditor.exe; NFO File Editor.rtf documents it).
  3. 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. Add resource\missions\<Name>.mw4=resource\missions\<Name>.mw4 under // BTFRSTRM Missions.
  4. 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] with Status=Displayed, display-name string, rollover text, map thumbnail). Campaign files pack via props.build Campaign= lines.
  5. Sky — reuse an existing sky from Content\Skies (already packed in skies.mw4); a new sky means a new entry in Content\skies.build. Beware the STEP 8 lesson: the .instance sky= path must match the erf filename exactly (case/name).

Part 4 — Build, deploy, verify

  1. No exe rebuild. Repack resources with build-env\build-resources.ps1 (wraps MW4pro.exe -build; LAB_ONLY builds only — see build-env/RESOURCE-BUILD.md). Output: resource\maps\<map>.mw4 + resource\missions\<name>.mw4, plus textures.mw4/core.mw4 if you touched textures.hint/missionnames.tbl.
  2. Redeploy with build-env\deploy-mw4.ps1 (copies Resource\ — including the .nfo — and the repacked packages into C:\VWE\firestorm\MW4).
  3. 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 .nfo longname; all teams spawn at their dropteam* 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 and PhoenixPalaceSTB incidents). Map= in the mission .instance must point at a map that actually exists (the arctic01/lunar02 dangling refs).
  • The mission .instance Model= must reference the [gamedata]-class page (<name>.data), not some other page (hill.contents incident).
  • .mw4 package names in .build page headers are the published identity — changing one orphans the old .dep/.mw4 in Resource\.

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)