myomer system COMPLETE -- the 'WAVE 6 mover cutover' was a phantom built on

a misattribution; the authentic couplings are all live

THE CORRECTION [T1]: @004b9550/@004b95b8 ('ConnectToMover'/'Disconnect
FromMover') are MechWeapon::ConfigureMappables/ChooseButton -- their +0x31C
is the weapon TriggerState and **(mech+0x128) is the CONTROLS MAPPER's
button roster (the MECHWEAP.CPP assert string + the trigger-edge detector
@004b9608 sit adjacent in the image).  The binary has NO dynamic myomer->
speed feed: AvailableOutput has exactly TWO callers in the whole image --
RegisterMaxOutput (assembly) and the SeekVoltageGraph sampler -- and
speedEffect@0x31C is a published GAUGE attribute.

The authentic myomer system (now fully live):
1. drive heat (#85, this morning);
2. VITAL death -- myomers are the only authored vital=1 subsystem
   (BTL4.RES res+0x48 scan): destroying them kills the mech via the #80
   vital-crit path (this is also the ram-death mechanism -- myomers are a
   0.35-weight collision-rattle target);
3. the assembly-time gait cap: RegisterMaxOutput @004b8ef0 raises
   mech+0x7A0 to AvailableOutput(top gear) = base x ~1.4284 -- now called
   (idempotent max, per tick; the 0x358 layout lock leaves no latch room)
   with real OwnerBaseSpeed/OwnerMaxSpeed bridges; the old per-frame
   reverseSpeedMax2 heal that would have clobbered it is garbage-guarded;
4. the ENG-page power curve at correct absolute scale (real base speed);
5. electrical sourcing (low gears run on a browned-out generator).

REMOVED (inventions): the mechmppr `speedDemand *= speedEffect` demand
multiplier + BTMyomersDriveOf + the Myomers ConnectToMover/MoverAttach
family.  Damaged-but-alive myomers heat faster and drop the power curve
but do NOT slow the mech (gitea #75's premise is falsified by the binary;
the real damage slowdown is the LEG-damage gimp gait).  Seek gears change
heat/sourcing/graph -- never speed.

Verified live: a mech at myomer dmg=0.234 (speedEffect attr 0.766)
beelines at full commanded speed with dmgGain=1.234 heat; 0 faults.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019Zh7PTkFy4KwTzVighLR9J
This commit is contained in:
Joe DiPrima
2026-07-31 09:17:31 -05:00
co-authored by Claude Fable 5
parent 31552c0444
commit cf8618bcb9
6 changed files with 142 additions and 126 deletions
+29 -68
View File
@@ -414,28 +414,13 @@ Scalar Myomers::SeekVoltageResponse(Scalar input_voltage)
// (see emitter.cpp BTSeekVoltageSample). Guarded: a non-Myomers subsystem
// samples 0 (only emitter/myomer pages own a graph in the shipped config).
//***************************************************************************
//***************************************************************************
// #75 bridge -- the myomers' live drive fraction for the mech's speed demand.
//
// The authentic coupling: ConnectToMover attached &speedEffect into the
// mech's mover, which multiplied every attached feed into its drive. The
// 2007 engine's mover has no such roster, so the port applies the same
// multiplication at the speed-demand site (mechmppr.cpp): demand *= this.
// speedEffect@0x31C is the wrapper's live 0..1 output -- gear ratio, thermal
// curve and (1 - zone damage) -- already republished every tick. A mech
// with no Myomers (or no roster yet) drives at 1.0; a DESTROYED myomers
// drives 0.0 (no drive -- the subsystem that moves the mech is gone).
//***************************************************************************
Scalar BTMyomersDriveOf(void *subsystem)
{
Entity *entity = (Entity *)subsystem;
if (entity == 0 || !entity->IsDerivedFrom(Myomers::ClassDerivations))
return -1.0f; // not a Myomers
Scalar f = ((Myomers *)entity)->SpeedEffect();
if (f < 0.0f) f = 0.0f;
if (f > 1.0f) f = 1.0f;
return f;
}
// (BTMyomersDriveOf is DELETED -- myomer-system completion, 2026-07-31. The
// demand-side `speedDemand *= speedEffect` coupling it fed (mechmppr.cpp) was
// an invention built on the ConnectToMover misattribution. The binary's only
// runtime AvailableOutput consumers are RegisterMaxOutput (assembly) and the
// SeekVoltageGraph sampler; myomer damage does NOT slow a live mech -- a
// DESTROYED myomers KILLS it, via the authored vital flag (the only vital=1
// subsystem in the RES) + the #80 vital-crit death path.)
Scalar BTMyomersSeekSample(void *subsystem, Scalar voltage)
{
@@ -505,6 +490,20 @@ static const Scalar MyomerRecoveryPerTick = -0.010999999940395355f; // 0xbc34395
//
void Myomers::MyomersSimulation(Scalar time_slice)
{
// 0. RegisterMaxOutput (@004b8ef0) -- the assembly-time top-speed cap.
// The binary calls it from the mech-assembly loop over the myomer chain
// (part_012.c:10322), after the model record is streamed:
// mech[0x7A0] = max(mech[0x7A0], AvailableOutput(seekVoltage[maxIdx]))
// = base x (topGear/recGear) = base x ~1.4284 on a healthy assembly --
// the gait rise-clamp both channels bound against (part_012:12103/12334).
// The port's capability-chain fill is the SubProxy stub (same situation as
// the flush's chain walk), so each myomer registers ITSELF here. Called
// per tick instead of once (the 0x358 layout lock leaves no room for a
// latch member): RegisterMaxOutput is an idempotent max() -- best falls as
// heat/damage degrade AvailableOutput, and max() never lowers the cap --
// so the resulting state is identical to the binary's once-at-assembly.
RegisterMaxOutput(); // @004b8ef0
// 1. @004b8bab -- the base electrical state machine. MUST come first, and
// must precede any heat-model gate: OwnerAdvancedDamage() is off below
// veteran, so gating ahead of this denied the machine to most pilots.
@@ -739,52 +738,14 @@ void Myomers::ResetToInitialState(Logical powered)
//***************************************************************************
// Myomers::ConnectToMover (mislabeled)
//***************************************************************************
//
// ⚠ MISATTRIBUTION (task #5 correction): @004b9550/@004b95b8 are NOT Myomers
// functions -- the weapon message-table @0x511860 proves they are
// MechWeapon::ConfigureMappables (id 9) / ChooseButton (id 10), the weapon->
// button grouping handlers (the +0x31C coincidence: Myomers speedEffect vs
// MechWeapon TriggerState). The bodies below are retained as the port's
// Myomers stand-ins but carry no binary address.
//
// Attaches the live SpeedEffect output (@0x31C) into the Mech's JointedMover
// roster (the mover at **(Mech[0xD0]+0x128)). Driven by a connect message
// whose payload index is at message+0xC:
// index = abs(message->value) - 1;
// if (message->value < 1) { mover->Detach(index); this[0x110] = -1; }
// else { this[0x110] = 0; mover->Attach(index, &speedEffect, this, 10, 9, 0); }
// (mover vtable +0x38 = Attach, +0x3C = Detach.)
//
void Myomers::ConnectToMover(SubsystemMessage &message)
{
int index = abs(message.value) - 1; // message+0xC
if (message.value < 1) {
MoverDetach(index); // owner mover vtable +0x3C
/* base+0x110 = -1 (detached) -- inert, no base accessor yet */
} else {
/* base+0x110 = 0 (attached) -- inert, no base accessor yet */
MoverAttach(index, &speedEffect); // owner mover vtable +0x38, feed @0x31C
// (original args: index,&speedEffect,this,10,9,0)
}
}
//***************************************************************************
// Myomers::DisconnectFromMover (stand-in; no binary address)
//***************************************************************************
// Counterpart of ConnectToMover: detaches the SpeedEffect feed.
// if (message->value > 0)
// mover->Release(message->value, &speedEffect); // mover vtable +0x44
void Myomers::DisconnectFromMover(SubsystemMessage &message)
{
if (message.value > 0) { // message+0xC
MoverRelease(message.value, &speedEffect); // owner mover vtable +0x44, feed @0x31C
}
}
// (ConnectToMover / DisconnectFromMover are DELETED -- myomer-system
// completion, 2026-07-31. Their source functions @004b9550/@004b95b8 are
// MechWeapon::ConfigureMappables / ChooseButton (the +0x31C there is the
// weapon TriggerState and **(mech+0x128) is the CONTROLS MAPPER's button
// roster -- proven by the MECHWEAP.CPP assert string and the trigger-edge
// detector @004b9608 adjacent in the image). The binary has NO dynamic
// myomer->mover feed; see the RegisterMaxOutput latch in MyomersSimulation
// for the real (assembly-time cap) locomotion coupling.)
//***************************************************************************
// Myomers::ToggleSeekVoltageMessageHandler @004b8a48
//***************************************************************************