Files
BT411/context/build-and-run.md
T
CydandClaude Opus 5 a7bcf1cbab Proposal: ship the authentic single-folder dist layout (docs only, NOT implemented)
The bare-launch crash was a symptom; the cause is that BT411 hands players a
developer tree.  mkdist zips tracked repo paths verbatim, so the dist inherited
build\Release\btl4.exe + content\ -- while the 1995 pod (BTL4OPT.EXE sits
beside BTL4.RES to this day, in content\) and RP411/RP412 all ship ONE folder,
where cwd is right by construction and a double-click just works.

docs/DIST_LAYOUT_PLAN.md sets out the proposed tree, the file-by-file change
(~50 lines total, no game code), what it buys, and the part that actually needs
a decision: the upgrade story.  Four migration options with a recommendation,
plus the wrinkle that decides between them -- the zip root is VERSIONED, so
every version may already land in its own folder, in which case the documented
extract-over-top has never worked and the migration cost is near zero.

Four open questions listed for the other author, including whether the .bat
launchers still earn their keep and whether the pod cabinet's own install shape
should be confirmed against Nick's notes before we call one folder authentic
for the cabinet too.

Not implemented pending that discussion.  The 4.11.560 cwd guard stands either
way and makes both layouts work.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 02:49:30 -05:00

100 lines
6.7 KiB
Markdown

---
id: build-and-run
title: "Build / Run / Debug — recipe, repo layout, env gates"
status: established
source_sections: "PROGRESS_LOG.md §10a, §10a-bis; README.md"
related_topics: [wintesla-port, decomp-reference, reconstruction-method]
key_terms: [BTL4OPT, cdb, BTL4.RES, EGG, WinTesla]
---
# Build / Run / Debug
The one top-level `CMakeLists.txt` builds `munga_engine` (engine) + `bt410_l4` (reconstructed BT
game lib) + `btl4.exe`. Full recipe + repo-layout map: `docs/PROGRESS_LOG.md §10a / §10a-bis` +
`README.md`. Env-gate table: [[decomp-reference]] §6.
## Build (Win32 / VS2019 BuildTools — the DXSDK link libs are Lib/x86)
```
# configure once:
cmake -S C:\git\bt411 -B C:\git\bt411\build -G "Visual Studio 16 2019" -A Win32 \
-DCMAKE_GENERATOR_INSTANCE="C:/Program Files (x86)/Microsoft Visual Studio/2019/BuildTools"
# build:
cmake --build C:\git\bt411\build --config Debug
```
- Links DXSDK d3d9/d3dx9/dinput8 + OpenAL/libsndfile (`engine/lib/`). DXSDK June 2010 at
`C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\` (overridable `-DDXSDK`). [T2]
- Linker uses **`/FORCE`** — tolerates header-defined globals + the **dead offline-factory
unresolved externals in mech3.cpp** (`Mech::CreateSubsystemStream` references `void*`-signature
`CreateStreamedSubsystem` for every class; never called at runtime). ⚠ `/FORCE` also HIDES real
unresolved symbols as runtime AVs — see [[reconstruction-gotchas]] §6. [T2]
- Editing an `engine/` file rebuilds the engine lib automatically (one project). A NEW member on a
`DPLRenderer`/`d3d_OBJECT` class needs the game objs that embed its layout recompiled — delete
stale objs if layout-mismatch corruption appears. [T2]
- ⚠ Kill the running exe before rebuilding (`taskkill //F //IM btl4.exe`) or you get LNK1104.
## Run
```
run\run.cmd [EGG] # default DEV.EGG; cd's to content\ and runs btl4.exe -egg <EGG>
```
- **cwd MUST be `content\`** — the engine resolves `BTL4.RES`, `VIDEO\`, `BTDPL.INI`, eggs relative
to cwd (the `loadTables` gotcha: `L4VIDEO.cpp:849` `fopen("VIDEO\\REPLACEMATS.tbl")` is relative +
unchecked → fread on NULL if cwd is wrong). Logs to `btl4.log` in `content\` (or `BT_LOG=<file>`). [T2]
**Since 2026-07-26 the exe enforces this itself** (`BTEnsureContentDirectory`, btl4main.cpp): if
cwd has no `BTL4.RES` it probes from the exe's own directory (`..\..\content` for the shipped
layout, plus flattened / in-content cases) and `SetCurrentDirectory`s there, before the log file
opens. The boot line says so when it had to look. ⚠ **The landmine it defuses** (field report):
a bare `btl4.exe` launch from `build\Release` found no resources ("Resource file btl4.res
v1.0.0.0 is obsolete!"), wrote a stray `bindings.txt`/`environ.ini`/`btl4.log` NEXT TO THE EXE —
so the player's real ones in `content\` looked like they were never created — and killed the
mission generation the menu launched (the child inherits the parent's cwd). Invisible for years
because every launcher `cd`s to `content\` first; it became reachable once glass became the
desktop default and a zero-arg launch started opening the menu.
- **Why this is a BT411-only hazard [T1].** The 1995 pod shipped ONE folder — `BTL4OPT.EXE` sits
next to `BTL4.RES`/`VIDEO\`/`GAUGE\`/`AUDIO\` (it is still there in `content\`) — and RP411/RP412
keep that shape (`pack-dist.ps1` copies the exe and every asset dir into one dist root). BT411's
two-folder split (`build\Release\btl4.exe` + `content\`) is not a design decision: `mkdist.py`
zips TRACKED REPO PATHS verbatim, so the dist inherited the repo's developer layout. In the
authentic single-folder shape cwd is right by construction and a double-click just works, which
is why the other games never hit this. **A proposal to ship the authentic shape is written up
in `docs/DIST_LAYOUT_PLAN.md` — PROPOSED, not implemented, awaiting a decision between the
authors.** The cwd guard stays either way (it protects the developer tree, where the split is
real and permanent).
- Interactive: **WASD** drive; weapon groups (keyboard, task #43) **1/Space** = lasers, **2** =
PPCs, **3/Ctrl** = missiles; **X** all-stop; **V** cockpit/chase view. Default egg = `DEV.EGG`
(map=grass, time=day). Swap mech via the egg's `vehicle=` — **ALL 18 ModelList names
CERTIFIED playable (2026-07-18 vehicle sweep)**: the canonical 8 (avatar, bhk1/blkhawk,
loki, madcat, owens, sunder, thor, vulture) + the short variants (ava1, lok1/lok2,
mad1/mad2, own1, snd1, thr1, vul1); each boots a solo mission, spawns, animates, no
crash. The code path is mech-agnostic. [T2]
## Debug (cdb x86)
`"C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\cdb.exe"`. Pattern for a faulting stack (cwd
= content\): `-g -c ".lines;sxe av;g;kp 24;q"` with `BT_ASSERT_TO_DEBUGGER=1`. Debug CRT fills fresh
heap **0xCDCDCDCD** (uninit) + freed **0xFEEEFEEE** — invaluable for "was this ever constructed?".
`BT_HEAPCHECK=1` = whole-heap validation every alloc/free (O(n²) at mission load — SLOW). To attach
to a frozen abort dialog: `cdb -p <pid> -c ".lines;~*kp 30;q"`. [T2]
## Repo layout (bt411)
- **`engine/MUNGA/` + `engine/MUNGA_L4/`** — the shared 2007 MUNGA engine + Win32/D3D9 HAL (carries
our BT render/loader work: bgfload/L4D3D/L4VIDEO + the image codec). `engine/shim/` (ATL),
`engine/lib/` (OpenAL/libsndfile), `engine/rp/` (RP *headers* the audio HAL includes).
- **`game/reconstructed/`** — the reconstructed BT source (the bulk).
- **`game/original/BT/` + `BT_L4/`** — surviving original BT `.cpp` + **all BT headers** (the include path).
- **`game/fwd/`** — ~186 forwarding shims (`#include <EXPLODE.hpp>``../../engine/MUNGA/<NAME>.h`).
- **`game/btl4main.cpp`** — the WinMain launcher.
- **`content/`** — the runtime tree (BTL4.RES, VIDEO/, GAUGE/, AUDIO/, eggs, BTDPL.INI). Run cwd.
- **`reference/decomp/`** — the raw Ghidra pseudocode (`all/part_*.c`) — the source-of-truth.
- **`docs/`** — the detailed ledgers (incl. `PROGRESS_LOG.md`, the full pre-restructure CLAUDE.md).
- **`tools/`** — btconsole.py, disas2.py, map/res scanners. **`context/`** — this knowledge base.
## Versioning (2026-07-18)
`4.10` = the 1995 arcade release; `4.11` = this win32 reconstruction; dev builds =
**`4.11.<git commit count>` + short hash**, `+` suffix = built from an uncommitted tree
(e.g. `4.11.311 (980c9cd+)`). Stamped every build by `tools/btversion.cmake`
`build/btversion.h` (`BT_VERSION_*` macros); shown in the boot banner (btl4.log head) and
the window title. Ask a tester for their title bar / btl4.log head to identify a build.
## Key Relationships
- Base: [[wintesla-port]] (the engine build recipe).
- Verify loop: [[reconstruction-method]]; env gates: [[decomp-reference]] §6.