Commit Graph
10 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 e1e5a9a6db BT410 Phase 5.3.12: experience gates + coolant system -- novice/expert modes REAL
The player-experience system now gates the entire heat/jam economy, verified in
BOTH directions with a one-token egg edit (TESTNOV.EGG, experience=novice):
NOVICE = 212 fire cycles all pinned at T=77, zero jams, zero shutdowns (the
heat model authentically absent); EXPERT = the full economy (duty cycles, 119
shutdowns + 2 authentic jams under forced fire). Zero Fail in both.

- BTPLAYER: the flag block renamed to its TRUE semantics (simLive @0x25c,
  heatModelOn @0x260 -- the FUN_004ad7d4 master switch, advancedDamageOn pair,
  levelFlag26c/270, experienceLevel); the ctor rows were already
  binary-accurate (nov 0000 / std 1011 / vet 1111 / exp 1101); accessors +
  [exp] sentinel.
- HeatSink::HeatModelActive() + ProjectileWeapon::LiveFireEnabled(): owner
  mech -> Entity::GetPlayerLink() -> the BTPlayer flags, NULL-permissive.
  Gates: both HeatSinkSimulation phases, every weapon fire-heat dump, and
  CheckForJam is now the AUTHENTIC form (LiveFireEnabled + heatLoad<=0
  early-outs + the minJamChance floor; the interim heat-degraded gate retired).

- THE LOAD-BEARING FIX: Mech ctor SetValidFlag(). Every 1995 entity ctor tail
  marks itself valid; ours didn't -- Entity::Dispatch routes messages to an
  INVALID entity into the deferred event queue, so the PlayerLink bind (and
  every directly-dispatched mech message) silently never landed and the gates
  read a NULL player forever.

- THE COOLANT SYSTEM (authentic bodies, byte-verified constants: HeatLoadScale
  0.002 -> heatLoad now in [0,1]; equalize eps 1e-4; draw floor/ON
  0.0025/0.003): UpdateCoolant (damage-scaled draw -- an undamaged mech leaks
  nothing), BalanceCoolant (full clamp chain from ConductHeat), DrawCoolant
  base=0 with the RESERVOIR override as THE SOURCE; Reservoir reconstructed
  (capacity overlays thermalCapacity, CoolantSimulation + the full
  InjectCoolant flush distribution, BT_FORCE_FLUSH dev hook); Condenser
  RefrigerationSimulation (massScale = (1-damage)*refrigerationFactor >= 1 --
  the heat pump that chills the bank; valveState inits 1; digit-suffix number
  fix). Deferred: AggregateHeatSink family, cockpit-button handlers
  (MoveValve/ToggleCooling/InjectCoolant), TrackSeekVoltage charge model.

Research driven by a 4-agent workflow dossier over the BT411 RE (verbatim
bodies for every function above + the egg experience plumbing).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 22:15:07 -05:00
CydandClaude Fable 5 3610ff1ecd BT410: entity simulation goes LIVE -- mission reaches RunningMission, mech + roster tick per-frame
The world now executes. Entity::Execute only PerformAndWatch's entities in
application state RunningMission, reached by two RunMissionMessages
(WaitingForLaunch->LaunchingMission->RunningMission). The 2nd is dispatched by
Player::ManageApplicationStatus when the launch fade expires -- but that only
runs inside PlayerSimulation, not the launch-phase HuntForDropZone. So the
player must switch Performance onto PlayerSimulation after it spawns.

- BTPLAYER.CPP DropZoneReplyMessageHandler: after CreatePlayerVehicle +
  InitializePlayerLink, choose the per-vehicle Performance by class -- Mech ->
  SetPerformance(PlayerSimulation)+SetScoringPlayerFlag; else CameraShipSimulation.
- BTPLAYER.CPP PlayerSimulation: chains the authentic base Player::PlayerSimulation
  (CalcRanking + ManageApplicationStatus + vehicle-pos copy + status service);
  console SCORE-delta flush deferred to the scoring wave.
- SENSOR.CPP SensorSimulation: minimal-safe partial (radarPercent = 1 -
  GetSubsystemDamageLevel, sensor healthy) so the roster tick path can't Fail
  once RunningMission engages. The heat/electrical gating awaits the power/heat
  sim wave (PoweredSubsystem/Generator/HeatSink/HeatWatcher *Simulation staged).

Verified: BT_MECH_LOG run reaches "[tick] roster live (first Sensor frame)",
two RunMissionHandler transitions, zero Fail/Exception. The mech is executed
each frame; its BODY Performance is still DoNothingOnce (real Mech::Simulate =
Phase 5.3, now the frontier).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 12:20:23 -05:00
CydandClaude Fable 5 812ca99652 BT410: reconstructed source BOOTS into the live game loop (zero Fail)
Phase-5.1 crash solved + two BTPlayer bricks reconstructed. The tree now
builds AND boots end-to-end with no staged Fail() reached, into the running
per-frame game loop.

- EMITTER.CPP: define Emitter::AttributePointers[]/AttributeIndex (ChargeLevel,
  chained to Subsystem::AttributeIndex) and point Emitter::DefaultData at it.
  EMITTER.HPP declared the index but the .cpp never defined it, so the surviving
  PPC.CPP (PPC::DefaultData binds inherited Emitter::AttributeIndex) and
  GAUSS.CPP (chains it) captured a NULL activeAttributeIndex -> GetAttributePointer
  faulted on the first PPC (roster slot 22). Fix clears all 33 roster slots and
  the control-mapping binding block.

- BTPLAYER.CPP InitializePlayerLink: real body -- dispatch PlayerLinkMessage
  (our EntityID) to playerVehicle + replicants (mirrors engine
  CameraDirector::CreateCameraShip). No staging.

- BTPLAYER.CPP VehicleDeadMessageHandler: non-death flavours (-2 drop-zone probe,
  >=0 respawn re-post) delegate to the authentic Player base handler; only the
  -1 death cycle stays staged (needs mech4 + scoring roles).

Verified: 516-line smoke run, zero Fail/Exception/abort; boot reaches
LBE4ControlsManager::Execute per-frame, waiting only on absent RIO hardware.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 11:51:04 -05:00
CydandClaude Fable 5 e610a2a3aa 4.10 reconstruction: real spawn factory path -> Mech ctor frontier
BTPlayer::CreatePlayerVehicle reconstructed (faithful; BT411's BT_SPAWN_XZ/
BT_SPAWN_ENEMY bring-up scaffolding dropped): builds the Mech::MakeMessage from
the mission game-model resource and hands it to MakeAndLinkViewpointEntity.
Mech::Make = new Mech(creation_message); a staged Mech ctor chains the real
JointedMover base (so the model skeleton/segments stream from BTL4.RES) then
Fails.

This validates the entire spawn factory chain live: CreatePlayerVehicle ->
MakeAndLinkViewpointEntity -> registry -> Mech::Make -> new Mech -> JointedMover
base ctor (streams the mech model) -> halts at the Mech ctor (mech.cpp:66).

The Mech ctor (@004a1674, 5690 bytes -- the largest function in the game) plus
the subsystem roster is the next MAJOR milestone, not a brick: it needs the full
1995 Mech member layout derived first (MECH.HPP is still reserved[331]; BT411's
decomp uses raw offset pokes that can't compile fresh), the subsystem class
hierarchy (only GAUSS/PPC/SENSOR survive in the 4.10 archive; the rest are the
measured "917 missing functions"), and the segment-table walk. Plan + scope in
MECH.NOTES.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 20:33:15 -05:00
CydandClaude Fable 5 956fc57681 4.10 reconstruction: BTPlayer message-handler table + DropZone spawn dispatch
Fixes the incorrect DefaultData reuse of Player::MessageHandlers -- BTPlayer now
has its own handler table (DropZoneReply, VehicleDead, Score, ScoreInflicted,
ScoreUpdate; the last two add BT message IDs) chained onto the base set, matching
the .data table recovered in BT411. A mission-start DropZoneReply now routes to
BTPlayer::DropZoneReplyMessageHandler (the real spawn/respawn dispatch skeleton)
instead of the base "should not be handled by base player class" Fail stub.

Boot ladder now runs the full engine + app + network + mission + player path and
reaches the spawn handshake, halting at CreatePlayerVehicle -> Mech::Make -- the
Mech subsystem frontier (Mech ctor + mech2/3/4 + subsystems + weapons), the next
major reconstruction milestone. Scoring/death handlers, PlayerSimulation, and the
mech-placement tail staged with documented Fail bodies (BTPLAYER.NOTES.md).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 20:24:27 -05:00
CydandClaude Fable 5 c43e6d873a 4.10 reconstruction: real BTPlayer ctor (binary-accurate experience-level flags)
Boot ladder advances past player creation. BTPlayer ctor/dtor/Make/
TestInstance/GetExperienceLevel reconstructed from BT411's Ghidra-recovered
body (@004c0bc8) backdated to 1995 idiom; the reserved[38] placeholder in
BTPLAYER.HPP replaced with the real BT-own members.

Key fidelity call: the game-mode flags are derived from
btMission->ExperienceLevel() (the egg's per-pilot experience key) with the
binary-accurate switch rows from the [T1] disassembly -- NOT from the scenario
role's returnFromDeath, which BT411's port uses as a [T3] stand-in. Mapping and
residual naming/[T4] uncertainty documented in BTPLAYER.NOTES.md.

Live boot now runs: banner -> resources -> app ctor -> network single-user ->
egg -> mission -> SetPlayerData -> BTRegistry::MakePlayer -> BTPlayer ctor
(resolves team, seeds experience flags) -> halts at the base
Player::DropZoneReplyMessageHandler stub (BTPlayer's own message-handler table
is the next brick -- DefaultData still reuses Player::MessageHandlers).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 20:18:37 -05:00
CydandClaude Fable 5 5b35eb973c 4.10 reconstruction: BTL4OPT.EXE links clean and BOOTS to the first staged brick
The reconstructed tree now produces a runnable binary with the authentic
1995 toolchain (BC4.52 / tlink32 / DPMI32):

- BTL4.CPP main TU reconstructed from the 4.11 Ghidra decomp (FUN_0040109c)
  + the 4.10 binary's own string pool + surviving RPL4TOOL.CPP house style;
  probe_main.cpp scaffold retired (BTL4.NOTES.md documents every decoded call)
- L4NET.CPP staged: L4NetworkManager ctor/dtor + 10 vtable-pulled virtuals
  (standalone-benign ones no-op, network ones Fail loudly) + NetNub client
  globals (Net_Common_Ptr=NULL routes L4File to its plain-DOS path)
- build410.sh: libs now built in the AUTHENTIC makefile member order
  (MUNGA.MAK / mungal4.mak / BT.MAK / BTL4.MAK). Order is load-bearing:
  tlink emits static-init records in module pull order, and alphabetical
  order booted into a null-vptr crash (IcomManager::ClassDerivations
  constructing before parent NetworkClient::ClassDerivations). Also fixed
  stage_link to the proven 32-bit lib set (SOSDBXC+SOSMBXC, no WATTCPLG)
- BOXTREE.HPP MemoryBlock unify, BTL4GRND notify stubs, remaining engine
  backfills (audio/gauge/resource/stream TUs) that closed the deep ledger

Smoke test (DOSBox-X + 32RTM, copy of the pod BT tree, our exe swapped in):
  BattleTech v4.10
  BTL4Application::BTL4Application
  l4net.cpp(22): L4NetworkManager -- l4net.cpp not yet reconstructed
Static init, main, -egg parse, BTL4.RES load (version 1.0.6 check passes),
ApplicationManager and the BTL4Application ctor chain all execute real
reconstructed code; boot halts at the first staged Fail() as designed.
Next brick: the real l4net.cpp body.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 19:05:53 -05:00
CydandClaude Fable 5 af80d52e22 source410: engine COMPLETE (165/165) - link reaches PE emission; deep ledger cut
The tlink32 campaign after the checkpoint: eleven engine bodies back-dated
from BT412 (rotation player team explode dropzone terrain cultural receiver
subsystm app l4gauge - the Application core included), the WinTesla-ectomy
handled by backdate.py's new unwrap rules (accessor-fn statics -> 1995 static
objects, decl rewrites, pointer->reference Derivation ctor, 2007 windowed-
gauge/console-marshal/idle-pump excisions), staged statics TUs opened for the
game classes (MECH/BTPLAYER/BTDIRECT/PROJTILE/MISSILE/BTL4MPPR .CPP + L4APP/
NETWORK engine statics).

State: every compiled symbol short of the shallow graph RESOLVED (the 52- and
17-symbol ledgers burned to zero); with 32stub.exe in place the linker reaches
full vtable closure and emits the deep ledger (~210 symbols, UNRESOLVED-
LEDGER.txt): remaining engine bodies (objstrm cstr gauge/gaugrend graphics
pixelmap palette resfile ray scnrole explosion-table), the DOS driver extern
layer (_SVGA*/_PCSerial*/_PCSPAK*/joystick/netnub/sosMIDI), the full L4App
body, and the real game-TU frontier (Mech::Make et al.). Recipe proven for
every category.

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