Files
TeslaRel410/restoration/source410/BT/MECH-LAYOUT.md
T
CydandClaude Fable 5 efc41f165b Mech milestone: reconstruct NameFilter (helper 3/3) -- helpers phase complete
NameFilter is the Mech's mechNameFilter (@0x36c), a small fixed debounce record
the ctor initialises. Reconstructed from FUN_00435a7c: a 10-word (0x28) struct,
Initialize() sets [2]=1 / [8]=[9]=-1 / rest 0 exactly. Header-only. Field
semantics unresolved (only caller is Initialize; reader is the unbuilt HUD) --
names best-effort, but size + init values are binary-exact, which is all the
Mech layout + ctor need.

All 3 missing embedded helper classes now reconstructed + compile-verified under
BC4.52 (AlarmIndicator, SequenceController struct+Init, NameFilter). MECH-LAYOUT.md
step 1 marked done. Next: MechSubsystem base + the subsystem roster, then finalize
MECH.HPP (probe sizeof==0x854), then the ctor + segment-table walk.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 20:56:06 -05:00

8.1 KiB
Raw Blame History

MECH.HPP staging worksheet (opened 2026-07-19)

The working ledger for growing the literal MECH.HPP alongside the mech-family TU reconstructions. The period compiler is the layout authority: ../layout_probe.cpp compiled+run under BC4.52 with the authentic OPT.MAK flags (-a4 alignment) measures the 1995 base-class sizes from the SURVIVING engine headers.

Probe results (2026-07-19) — methodology VALIDATED 3/3

class sizeof validation
Simulation 0x0D0
Entity 0x1C4 (⇒ Entity-own fields span 0x0D00x1C4: playerLink@0x190 ✓, subsystem roster @0x124/0x128 ✓)
Mover 0x300 (⇒ Mover-own 0x1C40x300: localOrigin@0x260 ✓)
JointedMover 0x328 ⇒ Mech's own region = 0x3280x854 (0x52C bytes)
Mission 0x0E4 BTMission's experienceLevel @+0xE4 = first BT member ✓
BTMission 0x0FC == the binary's new(0xfc) (BTL4Mission alloc) ✓
ModeManager / BTL4ModeManager 0x00C == the binary's new(0xc)
BTRegistry 0x010 == the binary's new(0x10)

Three independent allocation-size matches against the shipped binary ⇒ headers + compiler + flags reproduce 1995 layout exactly. Any future header where the probe disagrees with a binary alloc size is WRONG and must be fixed before use.

Consequences for MECH.HPP staging

  • Every binary offset < 0x328 is a BASE-CLASS field, not a Mech member. The port's mech.hpp declares several pose members in that range (orientation@0xD0, bodyRotation@0x100, turretBase@0x1C4, headPitch@0x1CC, torsoTwist@0x1DC, legAngle@0x1F4, hipAngle@0x200, torsoAim*@0x298/0x2C8, netOrientation@0x2D4) — in the 1995 header these belong to Simulation/Entity/Mover/JointedMover (or their equivalents) and must be RE-ATTRIBUTED by checking the surviving engine headers' member lists at those offsets (probe with offsetof where members are public).
  • Mech-own members with binary offsets ≥ 0x328 (from the port/CLASSMAP, to be laid out with reserved[] filler between mapped runs): reduceButton@0x340, forwardCycleRate@0x344, legCycleSpeed@0x348, reverseStrideLength@0x34C, gimpStrideLength@0x350, mechName@0x360, masterAlarm@0x39C(+legStateAlarm), legAnimationState@0x3B0, unstablePercentage@0x3F0, airborne@0x3F4, radar block @0x3F80x40C, rearFiring@0x410, missionReview@0x414, messageManager@0x434, torsoCache@0x438, lastInflictingID@0x43C, damageLookupTable@0x444, weaponCount@0x448, collisionTemporaryState@0x44C, heatAlarm@0x4500x464, throttleState@0x4A4, fallDirection@0x4A8, fallScalar@0x4B4(+collisionSpeed), templateBottomLift@0x4B8, stabilityAlarm@0x4C40x4D8, standing/duckedTemplateMaxY@0x518/0x51C (≡heatLevel/Capacity — CONFLICT, resolve), gyroSubsystem@0x528, gait caps @0x52C0x548, look angles @0x5640x570, turn rates @0x574/0x578, jump flags @0x5800x588, motionEventName@0x598, motionEventArmed@0x5A4, time scales @0x5A80x5B0, hudSubsystem@0x5B4, cycle rates @0x5B80x5C0, gyroRumbleTimer@0x5C4, footStepRootJoint@0x5C8, animationClips@0x5CC(+namedClip alias @0x5E0, crash clips @0x5D40x5DC), gimpBaseClip@0x64C, deathAnimationLatched@0x650, leg/bodyResetLatch@0x654/0x658, legAnimation@0x65C, controllableSubsystems@0x65C(CONFLICT — one is a chain @0x65C, resolve), bodyTargetSpeed@0x6B4, bodyCycleSpeed@0x6B8, bodyAnimation@0x6BC(≡watchedSubsystems CONFLICT), statusAlarm/bodyStateAlarm@0x714, bodyAnimationState@0x728, deadband block @0x7680x770, creationTime@0x778, poseSyncLatch@0x77C, heatLevelSnapshot@0x780, unstable tuning @0x7840x798, reverseSpeedMax2@0x7A0, heatableSubsystems@0x7AC, weaponRoster@0x7BC, damageableSubsystems@0x7CC, sensorSubsystem@0x7DC, telemetryFilter@0x7E0, linearSpeed@0x81C, resource names @0x8440x84C, deathHandler@0x850, end 0x854.
  • The flagged CONFLICTs are port-side double-attributions to untangle against the decomp before the first staged MECH.HPP is written.
  • Real 1995 types to substitute for the port proxies: ReconChain→ChainOf<Subsystem*>? / AlarmIndicator→the engine alarm type / ReconSeq→the SequenceController analog / BTVal→per case — settle each against the surviving engine headers + sizes via the probe.

Next actions

  1. Extend layout_probe.cpp with offsetof checks on public base members to re-attribute the sub-0x328 pose fields to their true base classes.
  2. Untangle the three offset CONFLICTs above (decomp reads).
  3. Write the first staged MECH.HPP (interface + mapped runs + reserved[] filler) and compile-verify sizeof(Mech)==0x854 with the probe.

ADDENDUM 2026-07-19 (later) — spawn factory reached the Mech ctor; proxy layer resolved

The boot ladder now runs the full spawn factory (CreatePlayerVehicle -> Mech::MakeMessage -> MakeAndLinkViewpointEntity -> registry -> Mech::Make -> new Mech -> JointedMover base streams the model) and halts at the Mech ctor. So the ctor is the live frontier and this worksheet is the active blocker.

Proxy layer resolved (BT411 mechrecon.hpp -> real 1995 types)

Settles the open item in the "Real 1995 types" bullet above:

BT411 alias real type in 4.10 archive?
ReconAlarm (AlarmIndicator) AlarmIndicator (multi-level, N levels sets size) MISSING
ReconSeq SequenceController (animation sequence) MISSING
ReconFiltered / FilteredScalar AverageOf (15-sample running avg) AVERAGE.HPP
ReconFiltered (mechNameFilter) NameFilter MISSING
ReconChain<Subsystem*> ChainOf<Subsystem*> CHAIN.HPP
ReconMatrix / Matrix34 AffineMatrix / Matrix
StateIndicator StateIndicator STATE.HPP
Reticle Reticle RETICLE.HPP
BTVal (turretBase, mechName, torsoAim*, aimRate, headPitch, torsoTwist) animated value/quaternion — UNIDENTIFIED; BT411 BTVal is a no-op placeholder. Most BTVal members are < 0x328 = BASE-class pose fields (re-attribute per §"Consequences"), so their type is a base concern, not Mech's.

CRITICAL new finding — 3 embedded helper classes are missing

AlarmIndicator, SequenceController, NameFilter do not exist anywhere in the 4.10 CODE archive (confirmed by full-tree grep; no alarm/filter/sequen headers either). They are additional helper classes the milestone must reconstruct from BT411's decomp, and their sizes set the embedded-member offsets. (AverageOf was initially flagged missing but DOES survive — AVERAGE.HPP, same SIGNATURED lineage BT411 preserved — so telemetryFilter[5]'s type is available.) The alarm sizing: the masterAlarm@0x39C/heatAlarm@0x450/stabilityAlarm@0x4C4/statusAlarm@0x714 spacing DERIVES the AlarmIndicator per-level size (e.g. masterAlarm 33 levels spans 0x39C..0x450 = 0xB4; heatAlarm 3 levels spans 0x450..0x4C4 = 0x74 — a fixed header + N-level array; solve the two equations for header size + per-level stride). Same method sizes AverageOf from telemetryFilter[5]@0x7E0..0x81C (0x3C/5 = 0xC each) and SequenceController from the legAnimation/bodyAnimation spacing.

Subsystem roster source availability (VDATA 0xBxx ClassIDs)

  • Full .CPP/.HPP in 4.10: GAUSS, PPC, SENSOR
  • .TCP partial survivors (authoritative where present): AMMOBIN, EMITTER, GNRATOR, HEAT, MISSILE, PROJTILE, PROJWEAP
  • Decomp-only (BT411): MechSubsystem base, gyro, torso, hud, myomers, mechweap, mislanch, powersub, + the rest of the "917 missing functions".

Revised reconstruction order

  1. Helper classes (block the layout): AlarmIndicator, SequenceController, NameFilter DONE 2026-07-19 — all 3 reconstructed + compile-verified under BC4.52: MUNGA/ALARM.HPP (AlarmIndicator = StateIndicator subclass, header-only), BT/SEQCTL.HPP+CPP (SequenceController struct + Init real; gait methods staged), BT/NAMEFILT.HPP (NameFilter struct + Initialize, header-only). AverageOf survives. BTVal is mostly base-class pose fields (re-attribute during layout, not Mech's).
  2. MechSubsystem base + roster (GAUSS/PPC/SENSOR + .TCP partials + decomp).
  3. Finalize MECH.HPP per the offset map; probe sizeof(Mech)==0x854.
  4. Mech ctor (@004a1674): embedded construction + segment-table walk.
  5. Per-frame path (mech2/3/4) + damage/weapon handlers.