From 992aedece8b1129da1bea7d9de1cb10a8df01e36 Mon Sep 17 00:00:00 2001 From: arcattack Date: Tue, 14 Jul 2026 09:11:22 -0500 Subject: [PATCH] Gait: FIX replicant trn regression -- gate master-perf turn-stop exit to masters Today's authentic trn dispatcher folded the master-perf turn-STOP exit into leg/body case 4. But the master perf (FUN_004a9b5c) runs on MasterInstance mechs, NOT replicants -- and a replicant derives turnDemand from the noisy REPLICATED yaw rate (mech4.cpp:1968), which dips into the +-0.05 deadband between dead-reckon updates. So the exit kicked the peer out of trn every few frames -> the peer 'rotated as a statue' + jerky (user-reported regression from yesterday). Gate both turn-stop exits to GetInstance() != ReplicantInstance; the replicant advances the trn clip from its replicated turn signal exactly as before the exit was added. Also BT_REPL_TRN probe (mech4.cpp) logs the replicant yawRate/turnDemand/legState. Co-Authored-By: Claude Fable 5 --- game/reconstructed/mech2.cpp | 18 ++++++++++++++---- game/reconstructed/mech4.cpp | 13 +++++++++++++ 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/game/reconstructed/mech2.cpp b/game/reconstructed/mech2.cpp index ea85219..152643b 100644 --- a/game/reconstructed/mech2.cpp +++ b/game/reconstructed/mech2.cpp @@ -693,8 +693,17 @@ Scalar distance = 0.0f; break; } - if (mppr == 0 - || (mppr->turnDemand <= 0.05f && mppr->turnDemand >= -0.05f)) + // MASTER ONLY (regression fix): the master-perf turn-stop exit is master-perf + // logic (FUN_004a9b5c runs on MasterInstance mechs, NOT replicants). A replicant + // derives turnDemand from the REPLICATED yaw rate (mech4.cpp:1968) -- a noisy + // proxy that dips into the deadband between dead-reckon updates; running this + // exit on it kicked the peer out of trn every few frames -> the peer "rotated as + // a statue" + jerky (user-reported). Gate to masters; a replicant leaves trn via + // the speed exits + its own turnDemand-driven re-entry, exactly as it did before + // this exit was added. + if (GetInstance() != ReplicantInstance + && (mppr == 0 + || (mppr->turnDemand <= 0.05f && mppr->turnDemand >= -0.05f))) { legStateAlarm.SetLevel(0); // turn stopped -> Standing (master-perf exit) ForceUpdate(8); @@ -932,8 +941,9 @@ Scalar distance = 0.0f; break; } - if (bm == 0 - || (bm->turnDemand <= 0.05f && bm->turnDemand >= -0.05f)) + if (GetInstance() != ReplicantInstance // MASTER only (see leg twin) + && (bm == 0 + || (bm->turnDemand <= 0.05f && bm->turnDemand >= -0.05f))) { bodyStateAlarm.SetLevel(0); // turn stopped (leg-symmetric) ForceUpdate(8); diff --git a/game/reconstructed/mech4.cpp b/game/reconstructed/mech4.cpp index 3d5cdf8..354598a 100644 --- a/game/reconstructed/mech4.cpp +++ b/game/reconstructed/mech4.cpp @@ -1988,6 +1988,19 @@ void legCycleSpeed = 0.0f; (void)AdvanceLegAnimation(dt); // joints only; travel = DeadReckon + if (getenv("BT_REPL_TRN")) + { + static float s_rt = 0.0f; s_rt += dt; + if (s_rt >= 0.15f) + { + s_rt = 0.0f; + DEBUG_STREAM << "[repltrn] yawRate=" << yawRate + << " turnDemand=" << replMppr->turnDemand + << " legState=" << (int)legStateAlarm.GetLevel() + << " spd=" << replMppr->speedDemand << "\n" << std::flush; + } + } + // REPLICANT BEAMS (task #51): the emitters carry live replicated // discharge state (Emitter::ReadUpdateRecord); draw them with the // same per-weapon walk the master uses.