From ca6718a8761240a7e576dbd40e3cd6ce9006a7e6 Mon Sep 17 00:00:00 2001 From: Joe DiPrima Date: Tue, 28 Jul 2026 16:52:26 -0500 Subject: [PATCH] turrets: correct the record -- the props are scenery, but PGN is a real turret that was cut Amends what 0534e93 asserted. That commit said "the level turrets are scenery" and called TurretClassID a settled red herring. The first half is right and the project owner has confirmed it; the second half I stated far more confidently than the evidence supports, and I missed the thing that explains why the old timers keep saying turrets should be active. They are half right, which is exactly why it reads as a mixed bag. What shipped really is scenery. TT1/TT2/TWR/APC sit in BTL4.RES as model + damaged-model + name + default with a .sld collision solid -- no skeleton, no joints, no gun port. The destructible world classes in CULTURAL.h have no weapon, fire or target members, and the binary has zero occurrences of turret/sentry/emplac/brain/patrol/aggro/hostile/npc. But PGN is a genuine, fully-articulated gun emplacement, and I walked straight past it the first time because I filtered it out as a mech prefix: [ROOT] pgn_base.bgf dzone=dz_base static base [jointturret] hingey pgn_tur.bgf yaw = traverse [jointgun] hingex pgn_gun.bgf pitch = elevation [sitegunport] tranz=-9.8505 the muzzle Traverse, elevation, a firing site, a damage zone, PGND* destroyed geometry, and no legs or arms or torso -- not a mech. It exists only as loose source assets; BTL4.RES contains zero pgn bytes in any case. So turrets were designed and modelled and then cut before the content build. Finishing them would be completing a cut feature rather than inventing one, but no turret code survives to reconstruct -- it would still need an entity class, targeting, and replication, since BT is networked PvP. Its [LAB_ONLY] "not approved for release" header means nothing, by the way: 63 of the 64 .SKL files carry it, MadCat included. Checked before reading anything into it. Also flagging a ClassID conflict rather than papering over it. Counting the enum in VDATA.h gives ThermalSight 0xBD9 and Turret 0xBDE, but CLASSMAP assigns 0xBDE to ThermalSight from the ctor at @4b8718 -- and that ctor's vtable and performance pointer do match thermalsight.cpp. The enum count agrees with CLASSMAP on HUD and Searchlight and disagrees on MechTech, so the port's VDATA.h ordering has drifted from the shipped binary somewhere in that range. CLASSMAP is binary-derived and wins for runtime behaviour; the real numeric value of TurretClassID is unknown. Marked UNRESOLVED so nobody cites either number. Co-Authored-By: Claude Fable 5 --- context/combat-damage.md | 55 +++++++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 15 deletions(-) diff --git a/context/combat-damage.md b/context/combat-damage.md index 509f3e8..39fc05b 100644 --- a/context/combat-damage.md +++ b/context/combat-damage.md @@ -14,21 +14,46 @@ open_questions: The drive→target→fire→damage→destroy loop. Full detail: `docs/PROGRESS_LOG.md §10c`; the death/ teardown forensics: `docs/HARD_PROBLEMS.md` (P5). -## ⚠ `TurretClassID` is a RED HERRING — there is no turret code (2026-07-28) [T1] -`engine/MUNGA/VDATA.h:209` really does declare `TurretClassID`, as the **last entry of the BT block** -(right after `MechTechClassID`, before the ND section), which makes it look like a BattleTech class. -It is not one. That enum position computes to **3038 = 0xBDE**, and 0xBDE in the shipped runtime is -**ThermalSight** (ctor `@4b8718`, `thermalsight.cpp`, already DONE) — the same enum-vs-runtime label -drift `CLASSMAP.md` records for HUD/MechTech at 0xBD6/0xBDC. The `case 0xbde:` in the mech factory -(`part_012.c:10186`) is a **mech SUBSYSTEM** slot (roster `param_1[0x4a]`), not a world entity. -Corroborating: there is **no `class Turret`** anywhere in the engine or the port, and `BTL4OPT.EXE` -contains **zero** occurrences of `turret`/`sentry`/`emplac`/`brain`/`patrol`/`aggro`/`hostile`/`npc`. -`jointturret` (in `OWN`/`PGN`/`STI` skeletons + `own_tur.bgf`) is a **mech** turret-torso joint, not a -world gun. The destructible world objects (`Landmark`, `CulturalIcon`, `UnscalableTerrain` — -`CULTURAL.h`) have no weapon/fire/target members of any kind: they take damage and break, nothing more. -⇒ **Turret/cannon models in the maps (`TT1`/`TT2`/`TWR`/`TK1`/`APC` + their `D` damaged variants) are -SCENERY.** They never fired in 1995. Making them fire would be inventing a feature, not reconstructing -one — and it would need an entity class, targeting, and a threat model that the binary has no trace of. +## Turrets: PLANNED, never shipped — the props are scenery, but `PGN` is a real turret (2026-07-28) +Players (and original-team "old timers") repeatedly report that **the level turrets should be +active**. Both halves of that are true, which is why it reads as a mixed bag — confirmed by the +project owner 2026-07-28. + +**What shipped is scenery** [T1]. The turret/cannon-looking objects in the maps — +`TT1`/`TT2`/`TWR`/`APC` (+ `D` damaged variants) — are in `BTL4.RES` as +`model + damaged-model + name + default` with a `.sld` collision solid: **no skeleton, no joints, no +gun port**. Destructible props, nothing more. The destructible world classes (`Landmark`, +`CulturalIcon`, `UnscalableTerrain` — `CULTURAL.h`) have no weapon/fire/target members at all, and +`BTL4OPT.EXE` contains **zero** occurrences of +`turret`/`sentry`/`emplac`/`brain`/`patrol`/`aggro`/`hostile`/`npc`. Consistent with the standing +no-AI finding below. + +**But a real turret asset exists and was never shipped** [T1]. `PGN` is a fully-articulated gun +emplacement, present as loose source assets (`content/VIDEO/PGN.SKL`, `content/VIDEO/GEO/PGN*.BGF`) +and **absent from `BTL4.RES` entirely** (zero `pgn` bytes, any case): +``` +[ROOT] Object=pgn_base.bgf dzone=dz_base static base +[jointturret] parent=ROOT Type=hingey pgn_tur.bgf YAW = traverse +[jointgun] parent=jointturret Type=hingex pgn_gun.bgf PITCH = elevation +[sitegunport] parent=jointgun tranz=-9.8505 the MUZZLE +``` +Traverse, elevation, a firing site, a damage zone, and `PGND*` destroyed geometry. It is **not** a +mech (no legs/arms/torso). ⚠ Do not read its `[LAB_ONLY] // not approved for release` header as +meaningful — that is boilerplate on **63 of 64** `.SKL` files, MadCat included. +⇒ Turrets were **designed and modelled, then cut before the content build**. Making them fire is +therefore *finishing* a cut feature, not inventing one — but there is no surviving turret CODE to +reconstruct: it would need an entity class, targeting, and (because BT is networked PvP) replication, +none of which the binary shows a trace of. Treat it as new work, tiered accordingly. + +⚠ **UNRESOLVED — do not cite either number as settled.** `engine/MUNGA/VDATA.h:209` declares +`TurretClassID` as the last entry of the **BT** block (after `MechTechClassID`, before the ND +section). Counting the enum gives `ThermalSightClassID = 0xBD9` and `TurretClassID = 0xBDE`, but +`CLASSMAP.md` assigns **0xBDE to ThermalSight** (ctor `@4b8718`, vtable `0x511498`, perf `[0x511290]` +— which does match `thermalsight.cpp`). The enum count independently agrees with CLASSMAP on HUD +(0xBD6) and Searchlight (0xBD8) but disagrees on MechTech (enum 0xBDD vs CLASSMAP 0xBDC), so the +port's `VDATA.h` ordering has drifted from the shipped binary somewhere in this range. CLASSMAP is +binary-derived and wins for what the runtime does; the true numeric value of `TurretClassID` in the +1995 binary is **unknown**. Resolve by disassembling the ClassID each ctor stores before relying on it. ## No AI — BT is PvP-only (verified, not a recovery gap) The mission system is NETWORKED and BT never had NPCs/AI. Every mech is driven by a `BTPlayer` (or a