Audit of what actually landed in context/ versus what only ever got said in
chat. Five gaps and one stale claim repeated in four files.
New env gates were the biggest hole -- BT_TORSO_LOG, BT_MYOMERS_LOG,
BT_MYOMERS_REPAIR_TEST, BT_SELF_DAMAGE and BT_POWER_DETACH_TEST were all in the
code and none of them in decomp-reference §6, which is supposed to be the hub.
Added with the reasoning that makes them usable: why the myomers probe samples
every frame while unpowered (the NoVoltage window is about a second and a 1 Hz
probe steps straight over it), why the repair test also forces Manual (or
AutoConnect restores power a frame later), why SELF_DAMAGE latches off at the
first death, and why DETACH_TEST taking a NAME is what proves failover rather
than a same-generator re-attach.
The 6am log day was in the code and the player bats but not the KB. Now in
build-and-run with the stem table, the unconditional append, the 8 MB part
roll-over and the BT_LOG-truncates trap, plus the operator-facing note in
operator-console and OPERATOR_GUIDE that you ask for the NEWEST log, never
"today's".
Recorded the crash-symbolization gap, which is the one with teeth. BTCrashFilter
writes a stack into the day log and its own comment claims "we hold the PDB". We
do not: no Release PDB is produced at all, and /O2 implies /Oy so the EBP walk is
unreliable anyway. When the Owens crash finally lands we get an address we cannot
resolve. Written down with the fix (/Oy-, /Zi + /DEBUG, archive the PDB per
build) rather than left as something I mentioned once.
New gotcha 22: HeatModelOff() reads simulationState == 1, i.e. "am I destroyed",
and has nothing to do with the heat model. Behaviour at the call sites is right,
the name is not, and while chasing #70 it reads as "novice pilots cannot twist"
and sends you hunting an experience-level bug that does not exist. Same misnomer
in torso/gyro/sensor headers.
Also documented the dist flavor trap, having nearly shipped it myself: mkdist
reads build/CMakeCache.txt, so a tree configured BT_STEAM=OFF silently produces
a -nosteam zip with no play_steam.bat and no steam_api.dll. OFF is the CMake
default; ON is the documented dev state.
Swept the stale `btl4.log` filename out of reconstruction-gotchas,
reconstruction-method, build-and-run and CLAUDE.md itself -- the log has been
<stem>_YYYYMMDD.log since 1777d5a and every "read btl4.log" instruction was
pointing at a file that is no longer written.
checkctx CLEAN.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
181 lines
12 KiB
Markdown
181 lines
12 KiB
Markdown
# BattleTech Pod-Port — Reverse-Engineering Expert Knowledge Base
|
|
|
|
> **This file is a ROUTER, not a knowledge store.** It says WHERE the knowledge is and HOW to use
|
|
> it; the actual knowledge lives in `context/*.md` (read on-demand). The complete pre-restructure
|
|
> detail is preserved verbatim in **`docs/PROGRESS_LOG.md`** (the old monolithic CLAUDE.md) — the
|
|
> ultimate fallback if a topic digest is thin. Migration history: `phases/phase-01-context-restructure.md`.
|
|
|
|
**Project:** Port VWE's 1995 arcade **BattleTech** (BT) pod game (MUNGA engine, Tesla platform
|
|
4.10) to modern Windows + the pod hardware, by reconstructing the missing BT game logic from the
|
|
`BTL4OPT.EXE` binary on top of the working WinTesla engine.
|
|
**Repo of record:** the top-level `CMakeLists.txt` + `README.md` build `btl4.exe`. Layout:
|
|
`engine/ game/ content/ docs/ reference/ tools/ context/`.
|
|
**Current front:** `btl4.exe` runs a full single-player loop; the gauge system is complete; the
|
|
active work is reconstructing each subsystem's authentic behavior from the binary. Details +
|
|
what's-next: `context/project-overview.md`, `context/open-questions.md`, recent git log.
|
|
|
|
---
|
|
|
|
## YOU ARE THE BATTLETECH PORT EXPERT
|
|
|
|
**You (Claude) are the expert on this port** — the 1995 MUNGA/BT engine, its asset formats, the
|
|
decompilation, and the reconstruction state. The `context/*.md` files, `reference/glossary.yaml`,
|
|
`reference/decomp/` (the raw pseudocode), and the `docs/*.md` ledgers are YOUR knowledge base.
|
|
|
|
**ALWAYS consult the context system before answering a question about the engine, formats, a
|
|
subsystem, or the reconstruction state — and before writing reconstruction code.** Do not rely on
|
|
training data; this is a specific, reverse-engineered 1995 codebase. The knowledge here is more
|
|
precise than anything you can infer.
|
|
|
|
### How to answer a question
|
|
1. **Identify the topic(s)** via the Quick Lookup table below (most questions touch 1-3).
|
|
2. **Read the full topic file** — don't guess from the filename.
|
|
3. **Follow the wiki-links** (`[[name]]`) and `related_topics` frontmatter to adjacent knowledge. A
|
|
`[[name]]` resolves to the topic file `context/<name>.md` if one exists, else to the glossary
|
|
term in `reference/glossary.yaml` (cross-cutting concepts like `material-ramp`,
|
|
`subsystem-roster`, `attribute-pointer`, `master`/`replicant` live in the glossary, not a topic).
|
|
4. **Check `context/decomp-reference.md`** for any offset, ClassID, resource type, address, or env gate.
|
|
5. **Check `reference/glossary.yaml`** for a term's meaning.
|
|
6. **Check `context/open-questions.md`** for known unknowns / deferred systems.
|
|
7. **Cite** the file + section (and the `docs/*.md` ledger or `reference/decomp` address when relevant).
|
|
|
|
### How to reason about / reconstruct something novel
|
|
1. **Ground it in the decomp.** Read the raw `FUN_xxxx` in `reference/decomp/all/part_*.c`; map
|
|
`FUN_`/`DAT_`/`this+0xNN` to engine symbols via BT headers + the WinTesla MUNGA source +
|
|
`game/reconstructed/CLASSMAP.md` + RP's parallel code.
|
|
2. **Check the gotchas.** `context/reconstruction-gotchas.md` — layout (shadow/alias/phantom
|
|
fields, resource mismatch), linkage (`/FORCE`), dtor-epilogue, databinding trap. Most bugs are here.
|
|
3. **RULE: no stand-ins.** The full logic IS in the pseudocode; a "gap" is an unfilled stub, not a
|
|
hole. Never write placeholder logic — read the decomp. Bring-up scaffolding is marked + temporary.
|
|
4. **Verify honestly.** `static_assert`-lock layouts; run env-gated; read `content\<stem>_YYYYMMDD.log`; cdb on crashes.
|
|
Tag claims with the evidence tier; flag T3/T4.
|
|
5. **Persist insights.** A genuinely new finding → add it to the right `context/*.md` (+ the `docs/`
|
|
ledger for detail), with an evidence tier. Keep the knowledge base current — this is a mandate,
|
|
not an afterthought.
|
|
|
|
### Quick Lookup
|
|
| User asks about... | Read this file |
|
|
|---|---|
|
|
| What the project is, engine, platform, goal | `context/project-overview.md` |
|
|
| Missing BT source, decompilation strategy | `context/source-completeness.md` |
|
|
| The 4.10 literal-source manifest (per-TU function/size/address map) | `reference/BT410_SOURCE_MANIFEST.md` (tool: `tools/manifest410.py`; log: `phases/phase-03-bt410-source-manifest.md`) |
|
|
| The WinTesla Windows port (renderer/audio/HAL) | `context/wintesla-port.md` |
|
|
| Build / run / debug / repo layout / env gates | `context/build-and-run.md` + `context/decomp-reference.md` §6 |
|
|
| Asset formats (MOD/SKL/ANI/BMF/BSL/SLD/…) | `context/asset-formats.md` |
|
|
| BGF geometry, LODs, CONN/PCONN, ramps | `context/bgf-format.md` |
|
|
| A layout/linkage/databinding BUG | `context/reconstruction-gotchas.md` |
|
|
| The reconstruction method / workflow | `context/reconstruction-method.md` |
|
|
| Walking, gait, ground model, collision | `context/locomotion.md` |
|
|
| Subsystems, the factory, heat/weapons/power | `context/subsystems.md` |
|
|
| Damage zones, targeting, firing, death | `context/combat-damage.md` |
|
|
| Experience / simulation modes (novice/standard/veteran/expert), heat-model + novice gates | `context/experience-levels.md` |
|
|
| Rendering, LODs, materials, sky, shadows, beams | `context/rendering.md` |
|
|
| The death/respawn translocation warp (tsphere vortex) | `context/translocation-warp.md` |
|
|
| First-person cockpit canopy (*_cop) + the eyepoint camera | `context/cockpit-view.md` |
|
|
| Cockpit gauges / MFD HUD | `context/gauges-hud.md` |
|
|
| Multiplayer, replication, netcode | `context/multiplayer.md` |
|
|
| **The OPERATOR CONSOLE + RELAY** — how to launch it, ports, seats, the round/launch lifecycle, re-arm | `context/operator-console.md` |
|
|
| Running a session as sysop (operator-facing how-to) | `docs/OPERATOR_GUIDE.md` |
|
|
| Pod hardware, monitors, RIO, MFD surfaces, input remap (CONTROLS.MAP/XInput) | `context/pod-hardware.md` |
|
|
| Glass cockpit desktop dev layer (BT_GLASS/BT_STEAM gates, PadRIO, miniconsole, Steam) | `context/glass-cockpit.md` |
|
|
| Steam internet MP (the wire seam, identity tokens, lobby) | `context/steam-networking.md` |
|
|
| Content archives, maps, where data lives | `context/content-archives.md` |
|
|
| Offsets, ClassIDs, addresses, resource types, env vars | `context/decomp-reference.md` |
|
|
| What we don't know / deferred systems | `context/open-questions.md` |
|
|
| Term / acronym definitions | `reference/glossary.yaml` |
|
|
| The ORIGINAL 1995 player manual (controls, per-mech stats, coolant loops) | `reference/manual/Tesla40_BT_manual.pdf` (+ alignment audit in `context/pod-hardware.md` §Manual) |
|
|
| The complete verbatim detail (fallback) | `docs/PROGRESS_LOG.md` (the old 2236-line CLAUDE.md) |
|
|
| Detailed running ledgers | `docs/RECONCILE.md`, `docs/GAUGE_COMPOSITE.md`, `docs/HARD_PROBLEMS.md`, `docs/SUBSYS_PLAN.md`, `docs/P3_LOCOMOTION.md`, `docs/RESOURCE_AUDIT.md`, `docs/VEHICLE_SUBSYSTEMS.md`, `docs/BGF_FORMAT.md`, `docs/ASSET_PIPELINE.md`, `docs/BT_SOURCE_STATUS.md`, `docs/WAVE_PLAN.md`, `docs/GLASS_COCKPIT.md`, `docs/REVOLVING_DOOR_PLAN.md`, `docs/INPUT_PATH_AUDIT.md`, `docs/RESPAWN_REARM_PLAN.md`, `docs/KD_SCOREBOARD_PLAN.md`, `docs/DIST_LAYOUT_PLAN.md`, `docs/MOUSELOOK_PLAN.md` |
|
|
|
|
---
|
|
|
|
## Evidence Tiers (adapted for reverse-engineering)
|
|
|
|
Tag individual claims (not sections) inline: `[T1]`, `[T2]`, … A claim inherits the **highest
|
|
(least certain)** tier of its inputs. Flag T3/T4 to the user.
|
|
|
|
| Tier | Label | Meaning |
|
|
|---|---|---|
|
|
| **T0** | Engine/header truth | A fact from the WinTesla MUNGA/L4 source or a BT header — the actual code we compile against. Authoritative. |
|
|
| **T1** | Decompiled + verified | Read from the binary pseudocode (`reference/decomp`) AND confirmed — disasm, `static_assert` offset lock, or cross-checked vs the RP analog. |
|
|
| **T2** | Reconstructed + runtime-verified | Implemented in `game/reconstructed/` and verified LIVE (combat un-regressed, gauge renders, log confirms the value). |
|
|
| **T3** | Best-effort / guarded | Reconstructed but not fully verified — a marked stand-in or a guarded raw-offset read. Runs, fidelity uncertain. |
|
|
| **T4** | Unconfirmed hypothesis | A claim about the binary's intent not yet decompiled/verified; a guess. |
|
|
|
|
---
|
|
|
|
## Conventions (CRITICAL — full detail in `context/reconstruction-gotchas.md`)
|
|
- **Never raw-read a compiled object's offsets** (`*(T*)(obj+0xNN)`) — our layout ≠ the 1995 binary.
|
|
Use named members / accessors / a **bridge** fn in a complete-type TU. (databinding trap)
|
|
- **Never re-declare an engine-base field** — it shadows the base (reads `0xCDCDCDCD`) + mis-offsets.
|
|
- **`/FORCE` hides unresolved symbols** — an unresolved external → runtime AV near `__ImageBase`, not
|
|
a link error. Grep the link log when a build "succeeds" but crashes at a garbage call target.
|
|
- **Don't reconstruct dtor compiler-glue** — the trailing base/member-dtor calls run the chain twice.
|
|
- **`static_assert`-lock every reconstructed layout** against the binary's offsets/sizeof.
|
|
- **A `+0x128`-style owner offset is the subsystem ROSTER, not the segment table.**
|
|
- **RULE: no stand-ins** — read the decomp; a gap is an unfilled stub.
|
|
- **Keep the knowledge base current** — new durable findings → `context/*.md` (+ `docs/` for detail).
|
|
- **Correct errors when you find them.** The context system is a reconstruction — some claims are
|
|
wrong. When the decomp / binary / engine source (ground truth) CONTRADICTS a claim in `context/*.md`
|
|
(or the glossary/`docs/`), FIX it — don't just work around it. Then **grep the other topic files for
|
|
the same wrong claim and sweep it** (a mistaken belief is often repeated across files), re-run
|
|
`scratchpad/checkctx.py`, and note the correction. Prefer this over silently distrusting a file.
|
|
(Archetype: the `0xBD3` "gates the valve/message routes" claim was wrong — 0xBD3 is a damage/explosion
|
|
hub; the real gate is the owning `BTPlayer` at `mech+0x190`. Verified from the decomp, then swept.)
|
|
|
|
## DO NOT
|
|
- Present T3/T4 claims as established without flagging the tier.
|
|
- Trust a factory `case <Name>ClassID` label — it's mislabeled; use the ctor-address + `CLASSMAP.md`.
|
|
- Issue `DestroyEntityMessage` on a mech death (the wreck STAYS; removal = the P5 teardown crash).
|
|
- Conclude "gauge not built" from an early process kill — the gauge renderer builds LAZILY.
|
|
- Use `DebugStream` (ReconStream, a no-op) for a log — use `DEBUG_STREAM`.
|
|
- Confuse the two console programs. **"Launch the console" = `python tools/btoperator.py`** (the
|
|
PySide6 operator GUI). `tools/btconsole.py` is the HEADLESS relay that GUI spawns — it has no
|
|
window, and backgrounded it has no stdin, so operator commands are dead. See
|
|
`context/operator-console.md`.
|
|
|
|
---
|
|
|
|
## Project Structure
|
|
```
|
|
bt411/
|
|
├── CLAUDE.md # this router (was the 2236-line monolith)
|
|
├── README.md # build of record
|
|
├── context/ # topic files (curated knowledge graph)
|
|
│ ├── decomp-reference.md # offsets/ClassIDs/addresses/env gates (the "equations" hub)
|
|
│ ├── reconstruction-gotchas.md # the systemic bug classes (conventions hub)
|
|
│ ├── open-questions.md # deferred systems + get-from-Nick
|
|
│ └── <topic>.md # one concept each
|
|
├── reference/
|
|
│ ├── glossary.yaml # terms/acronyms
|
|
│ ├── decomp/ # raw Ghidra pseudocode (the source-of-truth)
|
|
│ └── ghidra_scripts/ # the exporters
|
|
├── docs/ # PROGRESS_LOG.md (the full old CLAUDE.md) + detailed running ledgers
|
|
├── phases/ # restructuring / investigation logs
|
|
├── engine/ game/ content/ tools/ # the actual port (see README.md)
|
|
```
|
|
|
|
### How to add content
|
|
- **New finding on an existing topic** → edit the `context/*.md` (+ the `docs/` ledger for full detail).
|
|
- **New topic** → new `context/*.md` with YAML frontmatter; add to the Quick Lookup table + cross-refs.
|
|
- **Split** a topic file that exceeds ~25k tokens into finer subtopics.
|
|
- **New investigation** → a `phases/*.md` log.
|
|
- The `docs/*.md` ledgers stay as the DETAILED logs; `context/*.md` are the curated digests that route to them.
|
|
|
|
## Topic file format
|
|
```markdown
|
|
---
|
|
id: topic-id
|
|
title: "Title"
|
|
status: established | provisional | deferred | living
|
|
source_sections: "CLAUDE.md §X; docs/FILE.md; reference/decomp addresses"
|
|
related_topics: [other-topic-a, other-topic-b]
|
|
key_terms: [glossary-term-1]
|
|
open_questions: ["tracked uncertainty"]
|
|
---
|
|
# Title
|
|
## sections…
|
|
## Key Relationships
|
|
- Uses: [[other-topic]] · Feeds: [[other-topic]]
|
|
```
|