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

137 lines
7.7 KiB
Markdown

# 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<Scalar>; 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.