Commit Graph
7 Commits
Author SHA1 Message Date
CydandClaude Fable 5 4168f1ad4d BT410 5.3.47: the whole authored watcher set is published -- cockpit renders in the pod
Ladder rungs, each run-verified on the pod rig: ReportLeak (HeatSink),
GeneratorOn (Generator -- member existed, publication missing),
ConfigureActivePress (MechSubsystem -- likewise), AmmoState +
FireCountdownStarted + the rest of the AmmoBin table.

THE PINNED RANGE IS NOW THE AUTHENTIC SHAPE.  Publishing ReportLeak on
HeatSink and ConfigureActivePress on MechSubsystem shifts the chain down two,
and MechWeapon's bridge to its binary-pinned PercentDone (0x12) collapses
from THREE guessed pads to ONE -- which is exactly the arithmetic the shipped
string pool predicts (MechSubsystem 1, HeatableSubsystem 3, HeatSink 6,
PoweredSubsystem 5).  Three pads of guesswork replaced by a real attribute
and a real base-class row.  HeatableSubsystem and Torso rebase onto
MechSubsystem::AttributeIndex; MechControlsMapper does not (it derives from
Subsystem directly).

Types were chosen deliberately this time, per the AudioWatcher families the
engine instantiates (Motion / Hinge / Scalar / StateIndicator): every *State
name resolves to a StateIndicator, ReportLeak is a Scalar.

RESULT: the pod run now gets past every authored watcher and DRAWS THE FULL
COCKPIT -- sensor cluster, myomers, cooling, the weapon panels, kills/deaths
-- with the board booted and audio running.  It then exits without flushing
its redirected stdout, so the exit reason is not yet known; next step is a
run with the redirect removed so the console is readable.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 08:09:56 -05:00
CydandClaude Fable 5 afb9e3f5d9 BT410 5.3.46: the Reservoir crash solved -- *State names must be StateIndicators
The linker map named the faulting function: the crash address minus the CODE
base (0x410000) looked up in btl4opt.map's Publics-by-Value landed inside
AudioStateWatcher::AudioStateWatcher +0x2D.

AudioStateWatcher is AudioWatcherOf<StateIndicator> and its ctor immediately
runs Cast_Object(StateIndicator*, attributePointer)->AddAudioWatcher(this).
So every authored *State name must be published as a StateIndicator --
AlarmIndicator counts, it derives from one -- and pointing one at a plain int
sends that member call through garbage.

That explains both earlier failures: the AlarmIndicator attempt was the right
type but was tested with other bugs still in the batch, and the plain-int
attempt was simply the wrong type and crashed further along.

Published as state objects: Reservoir/ReservoirState -> reservoirAlarm,
Generator/GeneratorState -> stateAlarm, plus new StateIndicator members for
Condenser/CondenserState and Torso/MotionState.  StateIndicator has no
Initialize(); the default ctor suffices because the watcher only needs the
object to exist.

Verified on the pod rig: no crash, ladder advanced to ReportLeak.

Technique worth keeping: on an extender fault, subtract 0x410000 from the
dumped address and look it up in btl4opt.map -- it names the engine function,
and for this family of work that names the watcher class and hence the
required member type.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 07:42:44 -05:00
CydandClaude Fable 5 3ecd88aaef BT410 5.3.44: read the whole watcher list out of the resource; Torso MotionState
BTL4.RES stores each watcher as a (SUBSYSTEM, ATTRIBUTE) string pair, so the
complete list can be extracted directly instead of discovering one name per
6-minute run.  Banked the extraction method and the full normalised table.

Sixth rung climbed: Torso/MotionState (staged member, appended at the end of
Torso's own range so no downstream id moves).  LocalVelocity and
LocalAcceleration turn out to need nothing -- the engine's Mover already
publishes them.

Also banked, and deliberately NOT acted on: ReportLeak and
ConfigureActivePress are base-class attributes inside the pinned range, and
chasing them turned up what looks like the authentic attribute layout.  The
shipped pool gives MechSubsystem 1, HeatableSubsystem 3, HeatSink 6,
PoweredSubsystem 5 -- which counted from Subsystem::NextAttributeID=2 lands
MechWeapon's real ids on the binary-pinned 0x12 with EXACTLY ONE pad, where
our tree needs three.  That arithmetic is strong evidence for the original
layout, and reconciling to it would replace three guessed pads with the real
table.  But it moves ids underneath a cockpit currently verified at 98.9%
pixel-identical, so it wants a deliberate session with the A/B rig open
rather than a bulk edit at the end of a long one.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 01:25:40 -05:00
CydandClaude Fable 5 14da9489c2 BT410 5.3.43: full pod rig -- geometry loads, ladder advances to the audio watchers
Under the documented rig (launch_pod.ps1 with the GL bridge up) the 'couldn't
load object' count went to ZERO.  .BGF loading was never a reconstruction
problem, only a missing bridge.

What blocks now is a series of authored AttributeWatchers: BTL4.RES binds
them BY NAME and the engine Fails outright on any that does not resolve, so
each is a name our subsystems must publish.  Five rungs climbed, each
run-verified: UnstablePercentage, SpeedEffect (Myomers table), AnimationState
+ CollisionState/CollisionNormal + ReduceButton (Mech), and the full Torso
table (all six authentic names mapped onto existing members).

The method that makes this cheap is banked: the shipped binary's string pool
carries each class's attribute names CONTIGUOUSLY in ID ORDER after the class
name, and in every case so far our member declarations sit in the same order
-- which confirms the layout and lets ids be pinned rather than guessed.
Intersecting those names with BTL4.RES gives the exact work list.

A THIRD miswired SharedData found on the way: Myomers carried Subsystem's
tables where it derives from PoweredSubsystem, the same defect as
MissileLauncher (5.3.33).  Worth a sweep across every subsystem.

Staged member TYPES are provisional and documented as such: AttributeWatcherOf
reads *(T*)attributePointer and the instantiation comes from the resource,
which the string pool does not reveal.  Nothing drives them yet, so settle the
types with the models that write them.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 01:03:36 -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 3a0920acc0 BT410 Phase 5.3.3: torso weapon-elevation aim -- completes the control surface
Reconstructs Torso::TorsoSimulation (installed as the Torso's per-frame
Performance) and wires the torso aim into MechControlsMapper::InterpretControls,
so the control surface now covers aiming as well as locomotion.

- TORSO: analogElevationAxis/analogTwistAxis + SetAnalog* setters,
  CurrentElevation()/GetHorizontalEnabled() accessors. TorsoSimulation slews
  currentElevation += analogElevationAxis*baseElevationRate*dt clamped to the
  vertical limits, and (if horizontalEnabled) currentTwist by the twist axis
  clamped to the horizontal limits (authentic torso.cpp core; the skeleton-joint
  application is deferred with the render wave).
- InterpretControls: routes stick pitch (stick_y, squared) into the torso
  elevation every mode; Std/Vet route stick yaw into the twist. BT_FORCE_ELEV
  dev hook.

Verified: BT_FORCE_ELEV=0.8 -> the elevation slews up and clamps at the authentic
verticalLimitTop = 0.349 rad = 20deg; neutral -> 0; zero Fail.

Deferred: skeleton-joint application (render wave), HUD free-aim slew,
look/eyepoint commit.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 16:02:54 -05:00
CydandClaude Fable 5 4e16c49443 Mech phase 2: reconstruct Torso (: PowerWatcher) -- Mech sinkSourceSubsystem
Torso twist / weapon-elevation subsystem. Named tuning members (rates/limits in
radians, button-accel) + twist/elevation dynamics pad; ctor chains PowerWatcher,
copies tuning (RAD_PER_DEG), skips skeleton-joint resolution (deferred to the live
Mech link). statics/dtor/test real; TorsoSimulation/TorsoCopySimulation staged.
Cockpit leaf trio complete (Gyroscope/HUD/Torso). BT: 30 ok.

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