From f25abf1da536b4392a207e5d6d51b878787a88ce Mon Sep 17 00:00:00 2001 From: Cyd Date: Mon, 10 Aug 2026 01:05:24 -0500 Subject: [PATCH] BT410 5.3.130: the cockpit was shaking the wrong way -- a sign bug in the gyro torque, and a decode that stays unlanded on purpose Re-reading landed code against the decomp turned up a real defect. Gyroscope::ApplyDamageTorque (binary @004b2de4) finished with Vector3D::Negate, which flips all three components; the binary negates ONLY x in place after zeroing y. So the z component of the body force has carried the wrong sign on every damage shake and every collision crunch since that function landed. Fixed. Flagged for the same treatment: ApplyVerticalImpulse ends with bodyForce.y = bodyForce.x, which wants its binary address found and checked. The other half of the sitting is a decision NOT to land something. The master perf's second census (@0049fe80) computes three damage means into mech+0x354/8/c -- over the hull zones, over every subsystem's private zone, and over the myomers' private zones (the same 0x51155c GUID the mobility scan proved). A reader hunt found none: the apparent hits are on OTHER objects at the same offsets, the gyro's damage multipliers and a myomers cell, which is a good reminder that a bare offset grep proves nothing when offsets are per-class. No attribute row binds them either. Landing it would be three loops feeding dead memory, so it stays decoded and recorded until a consumer turns up. Regression soak: mobility scan, telemetry and drive all unchanged, zero faults. Co-Authored-By: Claude Fable 5 --- restoration/source410/BT/GYRO.CPP | 9 +++++++- restoration/source410/BT/MECH4.NOTES.md | 28 +++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/restoration/source410/BT/GYRO.CPP b/restoration/source410/BT/GYRO.CPP index 5e7af23e..49f97277 100644 --- a/restoration/source410/BT/GYRO.CPP +++ b/restoration/source410/BT/GYRO.CPP @@ -469,7 +469,14 @@ void direction *= magnitude; bodyForce += direction; bodyForce.y = 0.0f; - bodyForce.Negate(bodyForce); + // + // 5.3.130 CORRECTION: the binary (@004b2de4) negates ONLY the x + // component in place -- `*(+0x308) = -*(+0x308)` -- after zeroing y at + // +0x30c. Vector3D::Negate flips all three, so our z carried the + // wrong sign on every damage shake and collision crunch since this + // function landed. + // + bodyForce.x = -bodyForce.x; } void diff --git a/restoration/source410/BT/MECH4.NOTES.md b/restoration/source410/BT/MECH4.NOTES.md index 4356a14d..727aa701 100644 --- a/restoration/source410/BT/MECH4.NOTES.md +++ b/restoration/source410/BT/MECH4.NOTES.md @@ -447,3 +447,31 @@ streamed value. Both halves now land together. Soak: `[mobility] scale 1 over 1 myomers` on an undamaged bhk1 -- throttle unscaled, drive unchanged (demand 35.9, speed 7.0), zero faults. + +## 5.3.130 -- two findings from re-reading landed code + +**A REAL SIGN BUG, fixed.** `Gyroscope::ApplyDamageTorque` (binary +@004b2de4) ended with `bodyForce.Negate(bodyForce)`, but the binary +negates ONLY the x component in place (`*(+0x308) = -*(+0x308)`) after +zeroing y at +0x30c. `Vector3D::Negate` flips all three, so the z +component has carried the wrong sign on every damage shake and every +collision crunch since the function landed. Fixed to `bodyForce.x = +-bodyForce.x`. STILL WORTH A LOOK: `ApplyVerticalImpulse` ends with +`bodyForce.y = bodyForce.x`, which is odd enough to want its binary +address found and checked the same way. + +**THE DAMAGE AVERAGES: computed, consumed by nobody -- NOT landed.** +`@0049fe80` (the master perf's second census) writes three means to +mech+0x354 / +0x358 / +0x35c: over the HULL zones, over every subsystem's +private zone, and over the MYOMERS' private zones (the 0x51155c test -- +the same GUID the mobility scan proved). Default 0.0 (@0049ffc8) when a +count is empty. + +A reader hunt found none. The apparent hits at part_013:9498 and 13728 +are on OTHER objects at the same offsets -- the gyro's damage multipliers +inside its damage fan-out (@004b2980) and a myomers cell inside the +myomer simulation (@004b8d18) -- a reminder that offsets are per-class and +a bare `+ 0x354)` grep proves nothing. No Mech attribute row binds them +either. Landing them would be three loops feeding dead memory, so per the +project rule (record where the binary is silent, never invent a consumer) +this stays decoded and unlanded until a consumer turns up.