Commit Graph
9 Commits
Author SHA1 Message Date
CydandClaude Fable 5 d4f0aef6e1 BT410 Phase 5.3.17: the destruction cascade -- zone deaths DESTROY things
Mech::DamageZone::TakeDamage is the full binary cascade (@0049c690): LOD
artifact router with same-attacker clustering (@0049c40c, hysteresis 0.33),
artifact parent level = mean of children, Energy-hit generator shorts
through the crit plug binding (novice-exempt), weighted CriticalHit
(@0049ccc4), zone-death allotment push (SendSubsystemDamage @0049c9a8) and
the segment-table destruction descent (RecurseSegmentTable @0049cad4 --
SIBS + DESCEND via the engine EntitySegment iterators).

Supporting bricks: Mech's OWN handler table with the TakeDamage override
(latches lastInflictingID @0x43c; gyro feed staged; cylinder table
deferred); friend class Mech__DamageZone (authentic); subsystem private
zones ARMED (structureReference + armorByFacing[5] normalized -- crits are
measurable); ApplyDamageAndMeasure; ForceCriticalFailure sets
DestroyedState so the weapon FSMs' GetSimulationState()==1 hard gate went
live; Generator::ForceShort + PoweredSubsystem::ForceShortRecovery.

Fight-verified (mutual BT_SPAWN_ENEMY + BT_FORCE_ZONE=8 concentrated fire):
arm zone to 1.0 -> sibling searchlight zone dies (Searchlight2/ThermalSight
crits destroyed, HUD degrading) -> DESCEND kills the gun zone -> PPC_2 +
ERMLaser_2 + Condenser6 DESTROYED and FALL SILENT (0 shots after death;
undamaged PPC_1 keeps firing); vital-zone hit = MECH KILL; PPC hit shorted
GeneratorD. This art has zero artifact zones (redirect=0 across all 20 --
router verified dormant-correct). Smoke + novice regressions clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 11:13:28 -05:00
CydandClaude Fable 5 76cfc64353 BT410 Phase 5.3.16: targeting + damage -- two-mech fights are LIVE
The simulation is now a FIGHT. Mech target slot (+0x388), authentic
Loaded->Firing gate (viewFireEnable && HasActiveTarget), UpdateTargeting
range refresh, and SendDamage via the engine TakeDamageMessage.

MECHDMG.CPP is BORN against the AUTHENTIC surviving CODE/BT/BT/MECHDMG.HPP:
the Mech ctor's Pass-3 hull zone fill constructs Mech__DamageZone per zone
(the Entity base only allocates the raw pointer array -- unfilled slots were
crash #1; a base-class fill parses each record short and skews the stream --
crash #2). Streamed ctor parses the full BT tail (flags / Scalar-weighted
criticals with the Master+Dynamic plug gate / LOD redirect table) and
normalizes the armor economy: scale[type]=1/(raw x armorPoints), legs
halved -- BT411-verified @0049ce50.

Live two-mech verification (BT_SPAWN_ENEMY harness in DropZoneReply):
20 named hull zones stream on both mechs; PPC lands 11.77/hit (12 x
chargeRatio^2, type 4), ER-M laser 3.43 (type 3), SRM6 salvos 5.83 x 6
rounds on independent zones (type 2, one message per missile -- burstCount
is NOT in the zone formula); repeat hits climb linearly, leg zones absorb
at half scale, zones reach 1.0 Burning/Destroyed. No-target and novice
regressions hold (weapons load but never fire without a target).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 10:21:43 -05:00
CydandClaude Fable 5 eb8bba3195 BT410 Phase 5.3.6: look-button state machine -- full eyepoint composition
Reconstructs the binary's five-state LOOK machine (controls mapper tail,
part_013.c:396-459) as proper members/methods:

- MECHMPPR: LookState enum (None/Left/Right/Behind/Down) + lookState/
  previousLookState (out of reserved[24] -> [22]). InterpretControls picks the
  state from the look buttons each frame and on a CHANGE calls
  Mech::CommitLookState. BT_FORCE_LOOK=<1..4> dev hook.
- MECH: authored look angles lookLeft/Right/Front/BackAngle (deg->rad from the
  GameModel resource, guarded) + lookPitch/lookYaw + CommitLookState(int):
  side looks yaw by the authored angle, look-behind = yaw pi + lookBackAngle
  pitch, look-down = lookFrontAngle pitch, forward = identity. The per-frame
  eyepoint compose in Simulate adds the live Torso elevation on top.
  (reservedState [208] -> [202].)
- Deferred inside the commit (needs MechWeapon viewFireEnable/rearFiring):
  per-view weapon fire re-arm + HUD pip group-mask flip.

Verified headlessly: model reads clean authored angles (L=60 R=-60 F=-10 B=0
deg -- ModelResource layout confirmed again); BT_FORCE_LOOK=3 fires ONE commit
([look] state=3 yaw=3.14159 pitch=0) and the per-frame compose holds eyeYaw=pi
with eyePitch=0.349066 (lookBackAngle + the 20deg-clamped elevation). Zero Fail.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 22:08:50 -05:00
CydandClaude Fable 5 87b1c048cf BT410 Phase 5.3.5: eyepointRotation -- torso elevation pitches the eye/aim-ray, not a joint
Investigated the next planned binding (elevation -> gun joints jointlgun/
jointrgun) before implementing it, and found it was the wrong target: BT411's
own reverse-engineering history records that NO gun/arm elevation joint exists
in the authentic engine. The pod's stick-Y aim pitches the COCKPIT EYE and the
weapon boresight directly (mech4.cpp @~5219, pixel-calibrated against real
screenshots) -- the torso geometry never tilts for elevation on this mech
family. Reconstructing a gun-joint binding would have been invented behavior.

- MECH.HPP: EulerAngles eyepointRotation member (out of reservedState, now
  [208]) + GetEyepointRotation() accessor.
- MECH.CPP: composed each frame in Simulate -- eyepointRotation =
  EulerAngles(Radian(Normalize(lookPitch+elevation)), Radian(Normalize(lookYaw)),
  Radian(0)), reading Torso::CurrentElevation() via sinkSourceSubsystem.
  lookPitch/lookYaw are 0 until the look-button wave (BTCommitLookState) lands.

Verified: BT_FORCE_ELEV=0.8 -> torsoElev and eyePitch both read 0.349066 (the
authentic 20 degree resource limit) every frame, exact match; neutral -> 0.
Zero Fail. Corrected TORSO.NOTES.md's prior (wrong) "next: gun joints" note.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 21:51:28 -05:00
CydandClaude Fable 5 9fff0e969e BT410 Phase 5.3.4: Mech::ResolveJoint + skeleton-joint binding (torso twist)
Reconstructs the shared skeleton-joint resolver and binds the first subsystem
(Torso) to the live skeleton.

- Mech::ResolveJoint(name) (mech.cpp @00424b60): GetSegment(name) -> segment
  joint index -> GetJointSubsystem()->GetJoint(idx).
- Verified the JointedMover base streams the full skeleton headlessly:
  jointCount=19, 40 named segments (gun joints jointlgun/jointrgun, shoulders,
  hip, leg joints jointlthigh..jointrankle). BT_MECH_LOG [skel] summary;
  BT_SKEL_DUMP lists every segment/jointIdx.
- Torso resolves + binds its twist joint (ResolveJoint(torsoHorizontalJoint))
  and pushes currentTwist onto it via Joint::SetRotation (hinge->Radian,
  ball->EulerAngles yaw). The TEST.EGG mech has a fixed torso (horizJoint='',
  enabled=0) so its twist path is inert -- correct + guarded, zero Fail.

Next joint piece: elevation -> gun joints (jointlgun/jointrgun, the fixed-torso
aim mechanism) via weapon-joint binding; then gait leg animation. Both are
VISIBLE only under the renderer; headlessly the joint transforms are loggable.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 16:17:37 -05:00
CydandClaude Fable 5 ebf0d8c23f BT410 Phase 5.3.2: DRIVABLE mech -- authentic control interpretation + locomotion
The mech now drives from the authentic control chain (faithful route). Verified
headlessly: full throttle -> walks straight at top speed (30 u/s) along heading;
throttle+turn -> walks a circle (radius = speed/turnRate); neutral -> holds pose;
zero Fail.

MechControlsMapper::InterpretControls (mechmppr.cpp @004afd10) -- installed as the
mapper's per-frame Performance (roster slot 0, ticks before the mech):
- speedDemand = topSpeed*throttle*fwdScale (reverse inverts); soft stick (square)
  / pedal (cube) response; Basic=stick turn, Std/Vet=pedal turn; speed clamped
  while turning hard. Reads owner stride via Mech accessors.
- BT_FORCE_THROTTLE/BT_FORCE_TURN dev hooks for headless verification.

Mech::Simulate drive -- consumes the mapper demands:
- accelerate currentBodySpeed toward speedDemand (maxBodyAcceleration);
- authTurnRate = lerp(walkingTurnRate, runningTurnRate) by ground speed + over-run
  falloff (mech4.cpp master-perf @0x4aa3d3);
- integrate heading via Quaternion::Add(prevPose, (0,turn*rate*dt,0));
- facing = world -Z basis (GetFromAxis(Z_Axis)); worldLinearVelocity = facing*spd;
- integrate position (increment-1 core).

MECH.HPP: 9 named locomotion members out of reservedState (now [211]) --
walking/runningTurnRate, reverse/walkStrideLength, reverseSpeedMax,
forwardThrottleScale, maxBodyAcceleration, body/currentBodySpeed. BRING-UP
DEFAULTS (authentic values come from the model resource + LoadLocomotionClips --
next refinement).

Deferred: gait-clip-exact advance + leg anim (needs animation subsystem/renderer),
model-resource sourcing, terrain drop, torso/free-look aim, telemetry filters.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 14:46:30 -05:00
CydandClaude Fable 5 3364b65ae8 BT410 Phase 5.3.1: Mech::Simulate motion core -- mech integrates motion per-frame
Installs Mech::Simulate as the mech's per-frame Performance (was DoNothingOnce).
Reconstructs the load-bearing spine of the 1995 Simulate (mech4.cpp @004ab430):
integrate the body velocity into localOrigin (linearPosition.AddScaled(..,
worldLinearVelocity, dt)) and commit the Origin to the world transform with the
engine idiom (localToWorld = localOrigin, per ENTITY.cpp:988 / MOVER.cpp:850).

Uses the NAMED engine base Mover fields (localOrigin/localToWorld/
worldLinearVelocity) -- BT411's MechBaseLayoutCheck proved the WinTesla decomp's
raw this+0x100/0x260 offsets actually stomp those base fields; the clean 1995
build addresses them by name.

- MECH.HPP: Mech Performance typedef + SetPerformance + Simulate() decl.
- MECH.CPP: SetPerformance(&Mech::Simulate) at ctor tail; Simulate body.

Verified headlessly (BT_MECH_LOG "[sim] mech pos=" 1Hz): BT_DRIVE="5,0,10"
advances the mech +5.0/s x, +10.0/s z (y fixed) = exactly the injected world
velocity; no BT_DRIVE -> worldLinearVelocity is 0, mech holds spawn pose. Zero
Fail/Exception either way. BT_DRIVE is a retained dev hook for headless motion.

Deferred (locomotion wave): gait-cycle self-propulsion feeding worldLinearVelocity
(IntegrateMotion->AdvanceBodyAnimation, steered by mapper throttle/turn), heading
integration, terrain-height drop, cockpit telemetry filters.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 13:45:24 -05:00
CydandClaude Fable 5 4d175c959a Mech phase 3: named member layout + embedded-member construction
Replaced MECH.HPP reserved[331] with the named Mech-own members: cached subsystem
pointers (sensor/gyro/sinkSource/hud) + messageManager + weaponCount, the 5
capability chains (ChainOf<Subsystem*>), and the embedded status/animation state
(4 AlarmIndicators, Reticle, 3 StateIndicators, 2 SequenceControllers, NameFilter,
telemetryFilter[5]=AverageOf<Scalar>, 3 CStrings) + a reservedState pad for the
phase-5 per-frame fields. The subsystem ROSTER (subsystemArray/subsystemCount)
lives in the base Entity (GetSubsystem/GetSubsystemCount), so the Mech only caches
back-pointers.

The Mech ctor now CONSTRUCTS all embedded members (alarms Initialize'd, reticle
armed, state indicators sized, telemetry filters sized, sequence controllers
Init'd) -- compile-verified -- then halts at the segment walk (the remaining
piece). BT: 42 ok; tree links clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 07:00:51 -05:00
CydandClaude Fable 5 d9b34ddc63 source410: THE WHOLE 4.10 TREE COMPILES - 11/11 under the fleet's BC++ 4.52
All 10 surviving original TUs plus the reconstructed BTL4APP.CPP pilot build
clean with the authentic OPT.MAK flags (compile410.sh --sweep). First time
the 4.10 BattleTech source has compiled since 1996.

- layout_probe.cpp: the period compiler measures 1995 layouts from the
  surviving headers; validated 3/3 against binary alloc sizes (BTMission
  0xFC, BTL4ModeManager 0xC, BTRegistry 0x10). Base boundary: Simulation
  0xD0 / Entity 0x1C4 / Mover 0x300 / JointedMover 0x328 => Mech-own region
  0x328-0x854 (MECH-LAYOUT.md staging worksheet).
- 13 staged headers close the family ([T3] reserved[]-parked layouts;
  interfaces PROVEN by the surviving consumers): MECH, MECHSUB, HEAT,
  POWERSUB, MECHWEAP, EMITTER, MECHMPPR, BTPLAYER (BTPlayer__MakeMessage =
  Player's 8 args + roleName/teamName [T1 via BTREG]), PROJTILE, MISSILE,
  BTL4MPPR, BTL4VID + the round-2 BTCNSL/BTSCNRL.
- compile410.sh: PCH gate retired (bt.hpp/mungal4.hpp full include sets),
  DPL SDK roots on the include line.
- BTL4APP.CPP: appmgr include + GetApplicationManager()->GetFrameRate() +
  ResourceDescription:: scoping; Fail() held at its recorded line 400.
- Evidence ledgers: STAGED-HEADERS.NOTES.md, MECH-LAYOUT.md, BACKFILLS,
  BTCNSL (binary-recovered console wire IDs), BTSCNRL.

Remaining for a linkable BTL4OPT: the ~40 missing TU bodies (917-function
manifest) - the header skeleton they grow into now exists and compiles.

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