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 <noreply@anthropic.com>
This commit is contained in:
Joe DiPrima
2026-07-28 16:52:26 -05:00
co-authored by Claude Fable 5
parent 0534e93eec
commit ca6718a876
+40 -15
View File
@@ -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