From 4bfcd2735e04e121b097f4e5de1de8caef5e0998 Mon Sep 17 00:00:00 2001 From: Erik Date: Thu, 2 Jul 2026 19:19:46 +0200 Subject: [PATCH] fix(L.2g-S2b): turn/sidestep axes checked BEFORE overlay classification in RemoteMotionSink MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The first S2b cut classified turn/sidestep dispatches (Modifier-class 0x65xxxxxx) into the generic overlay router before the axis checks ran — turns never reached the cycle pick OR the ObservedOmega seed. S2 smoke symptoms: turn-in-place showed no animation (orientation snapping only) and running-in-circles had no client-side rotation between UPs. Log evidence: 30 [TURN_WIRE] events, zero turn [SETCYCLE]s (launch-s2-smoke.log). Harness gap noted: the conformance suite stops at the funnel->sink boundary; extending golden coverage through the sink (SETCYCLE-level fixtures) is scheduled with the R-phase rewrite. Co-Authored-By: Claude Fable 5 --- src/AcDream.App/Rendering/RemoteMotionSink.cs | 37 ++++++++++++------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/src/AcDream.App/Rendering/RemoteMotionSink.cs b/src/AcDream.App/Rendering/RemoteMotionSink.cs index 1eb473ad..bdf1efaf 100644 --- a/src/AcDream.App/Rendering/RemoteMotionSink.cs +++ b/src/AcDream.App/Rendering/RemoteMotionSink.cs @@ -61,24 +61,33 @@ internal sealed class RemoteMotionSink : IInterpretedMotionSink return; } - var route = AnimationCommandRouter.Classify(motion); - if (route is AnimationCommandRouteKind.Action - or AnimationCommandRouteKind.Modifier - or AnimationCommandRouteKind.ChatEmote) - { - // Overlay (attack swings, emotes): append over the current - // cyclic tail immediately — the substate cycle is unaffected - // (retail Action branch of GetObjectSequence). The funnel's - // contact gate already filtered airborne cases. - AnimationCommandRouter.RouteFullCommand( - _sequencer, _style, motion, speed <= 0f ? 1f : speed); - return; - } - + // Turn/sidestep FIRST: they are Modifier-class (0x65xxxxxx), so the + // generic overlay classification below would swallow them — that + // exact ordering bug shipped in the first S2b cut and killed + // turn-in-place animation + the ObservedOmega seed (S2 smoke, + // 2026-07-02: 30 [TURN_WIRE] events, zero turn SetCycles). They are + // cycle-axis candidates for the single-cycle pick, not overlays. uint low = motion & 0xFFu; bool isTurn = low is 0x0D or 0x0E && (motion & 0xFF000000u) == 0x65000000u; bool isSidestep = low is 0x0F or 0x10 && (motion & 0xFF000000u) == 0x65000000u; + if (!isTurn && !isSidestep) + { + var route = AnimationCommandRouter.Classify(motion); + if (route is AnimationCommandRouteKind.Action + or AnimationCommandRouteKind.Modifier + or AnimationCommandRouteKind.ChatEmote) + { + // Overlay (attack swings, emotes): append over the current + // cyclic tail immediately — the substate cycle is unaffected + // (retail Action branch of GetObjectSequence). The funnel's + // contact gate already filtered airborne cases. + AnimationCommandRouter.RouteFullCommand( + _sequencer, _style, motion, speed <= 0f ? 1f : speed); + return; + } + } + if (isTurn) { _turn = motion;