Commit Graph
5 Commits
Author SHA1 Message Date
CydandClaude Fable 5 0d97d8c38b BT410 5.3.45: six more watcher names published; the Reservoir one CRASHES (bisected)
Published and verified green on the pod rig: Condenser/CondenserState,
Generator/GeneratorState, Emitter/LaserOn, ControlsMapper/TargetRangeExponent,
plus the Torso and Myomers tables from the previous pass.

Reservoir/ReservoirState CRASHES the pod on the DOS extender, and a bisect
pins it to exactly that change: revert it and the run returns to a clean
Fail, re-apply it alone and the crash returns.  It is reverted; the tree is
green and the ladder is blocked there.

The important lesson is general: AttributeWatcherOf<T> does
currentValue = *(T*)attributePointer AT CONSTRUCTION, so a published name is
read the moment its watcher is built.  My earlier staging note claimed the
provisional types could not matter because nothing drives the values yet --
that is wrong, and this is the counterexample.

Ruled out by measurement and recorded so they are not retried: the
AlarmIndicator-vs-int type (a plain int got further, 232 -> 749 bytes of log,
but still crashed), static-init order (reservr.obj sorts last, after heat),
an id gap (contiguous at HeatSink::NextAttributeID), and the gauge rig (same
binary runs clean there -- only the pod/arena context faults).

Crash signature for whoever picks it up: 0044B4AD, mov eax,[edx+0x18] then
call [eax+4], EAX=0x15, fault at 0x19 -- a small integer called through as an
object, i.e. the AttributeIndexSet::Build uninitialised-slot pattern.
Condenser is the control: same base class, plain int, no crash.

Also fixed on the way: staged members must be appended at the END of a class
(offset-sensitive readers exist -- condenserNumber is reached as
master+0x1d4) and never added to a resource struct, which is a wire format.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 02:42:43 -05:00
CydandClaude Fable 5 bfff7fe874 BT410 Phase 5.3.22: the cockpit weapon-button column -- generator panel LIVE
The full per-receiver message chain, contiguous ids 3..0xb: PoweredSubsystem
4-8 (SelectGeneratorA-D + ToggleGeneratorMode, binary table @0x50F4EC)
chained on HeatSink's ToggleCooling(3); MechWeapon 9/10 (config buttons,
staged latch bodies); Emitter 0xb ToggleSeekVoltage (@0x511DB8).

SelectGenerator = release the old tap -> roster walk by generatorNumber ->
AttachToVoltageSource -> Connected; mode toggle cycles Manual->Auto->
(detach)->Manual; the seek dial steps the authored voltage ladder with wrap
(a step up re-enters Loading, charge persists).  All novice-locked.
Generator::UntapVoltageSource + PoweredSubsystem::DetachFromVoltageSource
added.  Dev harness: BT_PRESS_GEN=1..4 / BT_PRESS_SEEK.

Verified: PPC_1 retaps GeneratorB (tapped); seek index 2->3, target 9900V
(authored fraction x rated); novice presses INERT; missile fight 14/14 and
smoke green, zero faults.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 14:36:32 -05:00
CydandClaude Fable 5 b772e716fe BT410 Phase 5.3.15: the electrical charge model -- real charge, closed feedback loop
The emitter charge cycle is now the authentic electrical model end to end.

- WIRE-VERIFIED resource fix: the Emitter block is graphicLength /
  dischargeTime / seekVoltage[5] (FRACTIONS of the generator's rated voltage,
  -1 sentinel) / seekVoltageRecommendedIndex. The old two-field guess read
  seekVoltage[3]=0.99 as "dischargeTime 0.99s" -- the true PPC discharge is
  0.2s, and the calibration reads seekV={6000,7000,8000,9900} x rated 10000,
  recommended gear 2: the documented curve exactly.
- Ctor calibration (@004bb120): energyTotal=(dmg+heat)x1e7; EC pins
  E=0.5V^2EC to energyTotal at the recommended gear; voltageScale calibrates
  the exponential charge to reach seekV[rec] in the authored RechargeRate
  seconds cold; damageFraction = the damage share.
- TrackSeekVoltage (@004ba838) + ChargeTimeScale (@004b0d50): the charge
  integrates from the generator through the heat-stretched time scale, and
  the I2R loss heats the GENERATOR -- verified GeneratorA at 477.9K charging
  its PPC (BT411 predicted ~+480K) while the avionics generator idles at 77.
  Hot generators charge slower: the heat/firepower feedback loop is CLOSED.
- Emitter::ComputeOutputVoltage override (now virtual, as in the binary
  vtable): dial = level/seekV[gear], 0.01 snap, over-1 clamp.
- Sub-stepped Loading (1/60s slices -- the BT411 weapon-brick fix) + the
  documented-divergence overcharge rescue. VERIFIED: the PPC loads at level
  ~7920, inside the binary's exact [7920,8080] snap window.
- FireWeapon energy algebra (@004bace8): damage/heat = energy shares x
  chargeRatio^2. VERIFIED dmg=11.78 / heat=1.079e8 at ratio 0.9906. The
  heatCost x 1e7 partial is retired -- heat now comes from the energy.

Zero Fail; jams/shutdowns regressions stay live under spam.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 09:14:56 -05:00
CydandClaude Fable 5 896bbbed4d BT410 Phase 5.3.8: weapon fire path -- authentic attribute table + fire state machine
The energy weapons now run a live fire cycle, and the REAL trigger wiring is in
place: the 1995 MechWeapon attribute table (binary @0x511890) is published with
PINNED IDs, so the streamed per-mech fire-button mappings bind TriggerState
(0x13) -> fireImpulse and the controls push writes the trigger into the weapon.

- MECHWEAP: attribute enum + table (PercentDone 0x12, TriggerState 0x13,
  DistanceToTarget 0x14, TargetWithinRange 0x15, WeaponRange 0x16,
  EstimatedReadyTime 0x1A, RearFiring 0x1B, WeaponState 0x1C). Pads bridge the
  chain gap 2..0x11 -- LOAD-BEARING: AttributeIndexSet::Build leaves uncovered
  gap slots as uninitialized garbage, so every ID up to the max must be covered
  (they shrink to the authentic 0x0F..0x11 when the parent attribute waves land;
  SENSOR.HPP pins PoweredSubsystem::NextAttributeID at 0x0F).
- MECHWEAP: fire-machine members (fireImpulse/previousFireImpulse,
  rechargeLevel, rangeToTarget, effectiveRange, estimatedReadyTime, recoil,
  weaponAlarm 0/2/3/4); CheckFireEdge (@004b9608, BIT-PATTERN int compare --
  TriggerState carries raw ControlsButton ints whose release value is a float
  NaN; IEEE compare would latch the detector shut); ComputeOutputVoltage
  (@004b9c9c recharge dial).
- EMITTER: EmitterSimulation (PARTIAL @004baa88) -- Firing/Loaded/Loading FSM
  on the weapon alarm, viewFireEnable gate at Loaded->Firing, recoil-decay
  recharge over the authored RechargeRate seconds; FireWeapon (PARTIAL
  @004bace8) discharge bookkeeping; ChargeLevel re-pinned to the authentic
  0x1D; index re-chained to MechWeapon's. Deferred: electrical charge model
  (TrackSeekVoltage), heat dump, HasActiveTarget gate, beam/damage submission.
- BT_FORCE_FIRE dev hook: trigger pulse whenever Loaded (auto-fire cadence).

VERIFIED headlessly: forward view -- PPC_1/2 + ERMLaser_1 cycle FIRED->LOADED
at the authored 0.6s/1s cadence, rear lasers silent; BT_FORCE_LOOK=3 -- ONLY
the rear lasers (ERMLaser_2/3) fire. The view-fire x fire-FSM interlock holds
both directions. Zero Fail. (SRM6 ballistic FSM = a later increment.)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 23:01:57 -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