Files
TeslaRel410/restoration/source410/BT/MECHSUB.NOTES.md
T
CydandClaude Fable 5 e9b51cd6ee Mech milestone phase 2: map the complete subsystem family tree
Records the full mech-subsystem hierarchy discovered while reconstructing the
roster, with per-class build status. 6 classes done + verified (MechSubsystem,
HeatableSubsystem, HeatSink, PoweredSubsystem, Sensor, Generator); the tree shows
the remaining intermediates (HeatWatcher : MechSubsystem, PowerWatcher :
HeatWatcher) that unblock the Torso/HUD/Gyroscope branch (the Mech's directly-
referenced subsystems), plus Myomers/Condenser leaves and the separate weapon
subtree. The reconstruction pattern is now a proven template (documented). Enables
efficient continuation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 23:51:55 -05:00

7.7 KiB

MECHSUB — reconstruction notes (phase 2 kickoff, 2026-07-19)

Status: base-class ANALYSIS done; the reconstruction must be done FRESH against the 4.10 structure, NOT backdated from BT411 (its base class + damage model diverge). Key findings below de-risk the actual code.

MechSubsystem is the base of the ~30-class subsystem roster (sensor, gyro, torso, hud, generator, myomers, weapons…) the Mech ctor's segment-table walk instantiates. The staged MECHSUB.HPP is interface-only (one Mech *owner member, no bodies). Reconstructing the base is phase-2 step 1.

Dependencies (all survive in the 4.10 archive)

  • Subsystem (CODE/RP/MUNGA/SUBSYSTM.HPP) — the base.
  • DamageZone (CODE/RP/MUNGA/DAMAGE.HPP/.CPP) — the engine damage zone.
  • Mech__DamageZone : public DamageZone (CODE/BT/BT/MECHDMG.HPP) + the BT damage model (MechCriticalSubsystem, redirect tables, critical hits).
  • AlarmIndicator (just reconstructed, MUNGA/ALARM.HPP) — statusAlarm.

Finding 1 — the base Subsystem DECLARES the zone but does NOT create it (RESOLVED)

SUBSYSTM.HPP:181 declares DamageZone *damageZone; in the base Subsystem and its TakeDamage (SUBSYSTM.HPP:177-178) delegates damageZone->TakeDamage(damage). The base ctors ARE reconstructed — staged source410/MUNGA/SUBSYSTM.CPP (built, in munga.lib; 38 Subsystem:: syms in the map). Both base ctors set damageZone = NULL (resource ctor line 63) — the base does not allocate the zone. So the DERIVED MechSubsystem creates the Mech__DamageZone (BT411's zone-creation is structurally right here) — but the ARMOUR it seeds must follow Finding 2 (per-type streamed), not BT411's per-facing hand-seed.

Finding 2 — CRITICAL: the damage model diverged

The 4.10 base DamageZone (DAMAGE.HPP/CPP) is a per-damage-TYPE model:

  • members: defaultArmorPoints (Scalar) + damageScale[Damage::DamageTypeCount] where DamageTypeCount = 5 = {Collision, Ballistic, Explosive, Laser, Energy}.
  • TakeDamage: damageLevel += damage.damageAmount * damageScale[damage.damageType] (DAMAGE.CPP:413); the zone STREAMS its own armour (*stream >> defaultArmorPoints; *stream >> damageScale[ii], DAMAGE.CPP:335,340).

BT411's reconstruction is a per-FACING model: armorByFacing[5] (front/back/ left/right/top) + structureReference, manually seeded by MechSubsystem's resource ctor with an armour→absorption-coefficient inversion. Those field names (armour[5], structureReference) exist only in BT411's ReconDamageZone proxy — NOT in the surviving 4.10 DamageZone/Mech__DamageZone. The staged MechSubsystem__SubsystemResource (armorByFacing[5]+structureReference) was copied from BT411 and is likewise suspect for 4.10.

Consequence: BT411's MechSubsystem ctor (heat.cpp/mechsub.cpp) CANNOT be backdated verbatim — it would install a damage model the 4.10 engine's DamageZone doesn't implement, corrupting every subsystem's damage behaviour. The 4.10 MechSubsystem must let the base Subsystem + DamageZone stream ctor handle armour (per-type), not hand-seed per-facing values.

Corrected reconstruction approach (fully scoped — ready to write)

  1. Pin the base Subsystem ctor DONE (Finding 1) — staged SUBSYSTM.CPP sets damageZone = NULL; MechSubsystem creates the Mech__DamageZone.
  2. Reconstruct MechSubsystem: chain the base Subsystem, new Mech__DamageZone(this, index), add the mech-specific members (statusAlarm = AlarmIndicator, vital flag, alarmModel, criticalReference, collisionCriticalHitWeight, printSimulationState, configureActivePress) and the TakeDamage override, using the 4.10 per-type damage model — let the zone stream its own armour (defaultArmorPoints + damageScale[5]); do NOT hand-seed BT411's per-facing armorByFacing[5]/structureReference.
  3. Re-derive MechSubsystem__SubsystemResource against the 4.10 DamageZone stream format (the staged struct's per-facing fields are BT411-copied and suspect).
  4. Then the roster (GAUSS/PPC/SENSOR source + .TCP partials + decomp).

Analysis complete; step 2 is the next code to write. This worksheet is the deliverable that keeps the subsystem foundation on the 4.10 damage model rather than BT411's divergent one.

Progress + roster hierarchy findings (2026-07-19)

DONE: MechSubsystem base (MECHSUB.HPP/.CPP) and HeatableSubsystem (HEAT.HPP/.CPP) reconstructed + compile-verified. Verified vertical slice so far: Subsystem → MechSubsystem → HeatableSubsystem.

The subsystem hierarchy is DEEPER than the staged headers show. From BT411:

MechSubsystem            (done)
  └ HeatableSubsystem    (done; ctor chains MechSubsystem + ResetToInitialState
                          -> currentTemperature=300, heatLoad=0)
     └ HeatSink          (MISSING from the staged tree -- not in source410 nor
                          CODE; VDATA HeatSinkClassID=0xBC5. Must be added.)
        └ PoweredSubsystem (staged POWERSUB.HPP wrongly derives it from
                          HeatableSubsystem -- real base is HeatSink; FIX the
                          staged header. Also its ctor has embedded AlarmIndicators
                          (electricalStateAlarm 5-level, modeAlarm 3-level) and a
                          voltageSource SlotOf.)
           └ Sensor       (surviving header CODE/BT/BT/SENSOR.HPP; leaf)
           └ Generator, ... (other leaves)

PoweredSubsystem has inter-subsystem wiring — its ctor resolves a voltage source (generator) by indexing the OWNER MECH's subsystem roster (owner->GetSubsystem(res->voltageSourceIndex)), not the skeleton. So powered subsystems must be created AFTER the generator in the segment-walk order, and the Mech must expose GetSubsystemCount()/GetSubsystem(). This ordering constraint is a segment-walk (phase-4 ctor) concern; note it there.

Complete subsystem family tree (mapped 2026-07-19) + build status

MechSubsystem                         DONE (MECHSUB.HPP/.CPP)
├─ HeatableSubsystem                  DONE (HEAT)
│   └─ HeatSink                       DONE (HEAT)
│       ├─ PoweredSubsystem           DONE (POWERSUB)
│       │   ├─ Sensor                 DONE (SENSOR; interface survives in CODE)
│       │   └─ Myomers                todo (myomers.hpp)
│       ├─ Generator                  DONE (POWERSUB; source, GNRATOR.TCP partial)
│       └─ Condenser                  todo (heat.hpp)
└─ HeatWatcher  (: MechSubsystem)     todo  -- sibling branch to HeatableSubsystem
    └─ PowerWatcher (: HeatWatcher)   todo
        ├─ Torso                      todo (torso.hpp)   -- Mech sinkSourceSubsystem
        ├─ HUD                        todo (hud.hpp)     -- Mech hudSubsystem
        └─ Gyroscope                  todo (gyro.hpp)    -- Mech gyroSubsystem

Plus the WEAPON family (separate subtree): MechWeapon → {PPC, Gauss, ProjectileWeapon → Missile/…}. PPC/GAUSS source survives in CODE/BT/BT; AMMOBIN/EMITTER/MISSILE/ PROJTILE/PROJWEAP have .TCP partials; the rest decomp-only.

Pattern established (6 classes verified): each = statics (ClassDerivations(parent, "Name") + DefaultData reusing Subsystem::MessageHandlers/ AttributeIndex/StateCount), ctor chaining the parent + member init from the resource, dtor, TestClass/TestInstance/ResetToInitialState real, per-frame Simulation method + CreateStreamedSubsystem staged with Fail. Embedded alarms = AlarmIndicator(N); filters = AverageOf; owner->GetInstance() != ReplicantInstance gates the master performance install.

Next: HeatWatcher (: MechSubsystem) then PowerWatcher (: HeatWatcher) unblock the Torso/HUD/Gyroscope branch (the Mech's directly-referenced subsystems); Myomers

  • Condenser are direct leaves; then the weapon family. After the roster: finalize MECH.HPP layout (probe sizeof==0x854), then the Mech ctor + segment walk.