MP: peer poses from the BODY channel following replicated state -- the authentic single-channel design (task #50)
Answers 'is this different from the original?' -- NO, it RESTORES it. Decomp
(workflows wh1h5gnmc/w1s9ou02o): the 1995 game had ONE live skeletal channel,
the BODY channel FUN_004a5678 via IntegrateMotion; the LEG channel FUN_004a5028
is DEAD CODE (zero call sites, SetLegAnimation never runs). Both master and peer
posed the whole skeleton from the body channel, the PEER FOLLOWING the master's
replicated body-anim state (bodyStateAlarm@0x728, set by the type-3 reader's
SetBodyAnimation, mech.cpp:1913) + replicated bodyTargetSpeed@0x6b4.
Our port RESURRECTED the dead leg SM as the peer's poser (mech4.cpp AdvanceLeg-
Animation) fed a LOCALLY re-derived commanded speed. The leg SM's phase-
independent pre-switch wind-down (mech2.cpp:560-568: force-jump {6,7,8,9}->stand
when legCycleSpeed<=0) made the peer SKIP the master's decel state 8 and snap to
stand while the body coasted -- the 'slid forward after legs stopped' slide, the
reverse 'slippy sliding in place', and the whole re-derivation desync class.
FIX (peer branch, gated BT_PEER_LEGCH=1 to revert): pose+travel from
AdvanceBodyAnimation(dt, mj=1) -- the body channel, which follows the replicated
state and has NO early wind-down, playing the master's exact clips (walk/decel-8/
reverse/stand). ZERO new netcode -- the state is already on the wire and already
decoded into the body channel; we were simply posing from the wrong (resurrected,
dead) channel. Single-player untouched (replicant-gated).
Verified autonomous (through-zero sweep): no crash; body channel advances
(frmAvg 0.3-0.75, states 5/6/7/10 following master); slide-in-stand events
519 -> 3.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
3792a04661
commit
96a896ae43
@@ -2134,7 +2134,23 @@ void
|
|||||||
// once so a direct run-state entry can't slew from -4.3e8.
|
// once so a direct run-state entry can't slew from -4.3e8.
|
||||||
if (legCycleSpeed < -100.0f || legCycleSpeed > 200.0f)
|
if (legCycleSpeed < -100.0f || legCycleSpeed > 200.0f)
|
||||||
legCycleSpeed = 0.0f;
|
legCycleSpeed = 0.0f;
|
||||||
const Scalar replLegAdv = AdvanceLegAnimation(dt); // joints + ROOT TRAVEL
|
// PEER POSE CHANNEL (decomp workflow w1s9ou02o -- the authentic fix): the
|
||||||
|
// 1995 peer posed the WHOLE skeleton from the BODY channel (FUN_004a5678)
|
||||||
|
// FOLLOWING the master's replicated body-anim state (bodyStateAlarm@0x728,
|
||||||
|
// set by the type-3 reader's SetBodyAnimation, mech.cpp:1913) + replicated
|
||||||
|
// bodyTargetSpeed@0x6b4. The LEG channel (FUN_004a5028) is DEAD CODE. Our
|
||||||
|
// port resurrected the leg SM as the peer's poser fed a LOCALLY re-derived
|
||||||
|
// commanded speed, and the leg SM's phase-independent pre-switch wind-down
|
||||||
|
// (mech2.cpp:560-568, force-jump {6,7,8,9}->stand when legCycleSpeed<=0) makes
|
||||||
|
// the peer SKIP the master's decel state 8 and snap to stand while the body
|
||||||
|
// coasts (the 'slid forward after legs stopped' bug). The body channel has
|
||||||
|
// NO such wind-down and follows the replicated decel state, playing the
|
||||||
|
// master's exact clips. Swapping the peer to the body channel RESTORES the
|
||||||
|
// original single-channel design (no new netcode). BT_PEER_LEGCH=1 = old.
|
||||||
|
static const int s_peerLegCh = getenv("BT_PEER_LEGCH") ? 1 : 0;
|
||||||
|
const Scalar replLegAdv = s_peerLegCh
|
||||||
|
? AdvanceLegAnimation(dt) // old: re-derived leg SM
|
||||||
|
: AdvanceBodyAnimation(dt, 1); // authentic: body channel, mj=1 poses skeleton
|
||||||
// AUTHENTIC coupled position (mirror of the master's world-step at
|
// AUTHENTIC coupled position (mirror of the master's world-step at
|
||||||
// mech4.cpp:3325-3336 == Mech::IntegrateMotion tail @004ab1c8): between
|
// mech4.cpp:3325-3336 == Mech::IntegrateMotion tail @004ab1c8): between
|
||||||
// records the body advances by the CLIP'S OWN travel rotated by the
|
// records the body advances by the CLIP'S OWN travel rotated by the
|
||||||
@@ -2195,7 +2211,7 @@ void
|
|||||||
if (getenv("BT_SLIDE"))
|
if (getenv("BT_SLIDE"))
|
||||||
{
|
{
|
||||||
static Point3D s_slPrev; static int s_slInit = 0;
|
static Point3D s_slPrev; static int s_slInit = 0;
|
||||||
const int ls = (int)legStateAlarm.GetLevel();
|
const int ls = getenv("BT_PEER_LEGCH") ? (int)legStateAlarm.GetLevel() : (int)bodyStateAlarm.GetLevel();
|
||||||
if (s_slInit)
|
if (s_slInit)
|
||||||
{
|
{
|
||||||
const float dx = (float)(localOrigin.linearPosition.x - s_slPrev.x);
|
const float dx = (float)(localOrigin.linearPosition.x - s_slPrev.x);
|
||||||
@@ -2240,8 +2256,9 @@ void
|
|||||||
static float s_gvPrevF = -1.0f, s_gvAcc = 0.0f, s_gvSum = 0.0f, s_gvMax = 0.0f;
|
static float s_gvPrevF = -1.0f, s_gvAcc = 0.0f, s_gvSum = 0.0f, s_gvMax = 0.0f;
|
||||||
static int s_gvN = 0, s_gvBack = 0, s_gvTrans = 0, s_gvPrevSt = -1;
|
static int s_gvN = 0, s_gvBack = 0, s_gvTrans = 0, s_gvPrevSt = -1;
|
||||||
static float s_gvDemPrev = 0.0f; static int s_gvDemChg = 0;
|
static float s_gvDemPrev = 0.0f; static int s_gvDemChg = 0;
|
||||||
const float gf = (float)legAnimation.currentFrame;
|
const int _pb = getenv("BT_PEER_LEGCH") ? 1 : 0;
|
||||||
const int gs = (int)legStateAlarm.GetLevel();
|
const float gf = _pb ? (float)legAnimation.currentFrame : (float)bodyAnimation.currentFrame;
|
||||||
|
const int gs = _pb ? (int)legStateAlarm.GetLevel() : (int)bodyStateAlarm.GetLevel();
|
||||||
if (s_gvPrevF >= 0.0f)
|
if (s_gvPrevF >= 0.0f)
|
||||||
{
|
{
|
||||||
float df = gf - s_gvPrevF;
|
float df = gf - s_gvPrevF;
|
||||||
|
|||||||
Reference in New Issue
Block a user