From ca9ad5db8f58ec762acffcf99695cb33bc0b966b Mon Sep 17 00:00:00 2001 From: gamer147 Date: Wed, 3 Jun 2026 20:00:41 -0400 Subject: [PATCH] refactor(battle-node): remove scripted-bot test-stub arms from dispatch handlers The IsScriptedBot(ctx.From) forwards in JudgeHandler/TurnStartHandler/TurnEndHandler and the 'if Type==Scripted' raw-forward only ever fired for ScriptedBotParticipant emissions; NoOpBot (Bot mode) never emits, so they are dead. Routing is now purely PvP-vs-Bot. Drops the IsScriptedBot helper. Co-Authored-By: Claude Opus 4.8 --- .../Sessions/Dispatch/FrameDispatchContext.cs | 6 ------ .../Sessions/Dispatch/Handlers/JudgeHandler.cs | 4 ---- .../Sessions/Dispatch/Handlers/TurnEndHandler.cs | 11 ++--------- .../Sessions/Dispatch/Handlers/TurnStartHandler.cs | 4 ---- 4 files changed, 2 insertions(+), 23 deletions(-) diff --git a/SVSim.BattleNode/Sessions/Dispatch/FrameDispatchContext.cs b/SVSim.BattleNode/Sessions/Dispatch/FrameDispatchContext.cs index a81050d..93d23ba 100644 --- a/SVSim.BattleNode/Sessions/Dispatch/FrameDispatchContext.cs +++ b/SVSim.BattleNode/Sessions/Dispatch/FrameDispatchContext.cs @@ -32,10 +32,4 @@ internal sealed class FrameDispatchContext internal bool BothAfterReady() => (A as IHasHandshakePhase)?.Phase == BattleSessionPhase.AfterReady && (B as IHasHandshakePhase)?.Phase == BattleSessionPhase.AfterReady; - - /// True for any participant carrying the synthetic opponent viewer id — i.e. a - /// ScriptedBotParticipant OR a NoOpBotParticipant. Callers that must exclude Bot - /// mode rely on a preceding Type == BattleType.Bot guard. Mirrors the legacy - /// IsRealForwardableFromScripted guard. - internal bool IsScriptedBot(IBattleParticipant p) => p.ViewerId == ScriptedLifecycle.FakeOpponentViewerId; } diff --git a/SVSim.BattleNode/Sessions/Dispatch/Handlers/JudgeHandler.cs b/SVSim.BattleNode/Sessions/Dispatch/Handlers/JudgeHandler.cs index 563d96b..cd6d637 100644 --- a/SVSim.BattleNode/Sessions/Dispatch/Handlers/JudgeHandler.cs +++ b/SVSim.BattleNode/Sessions/Dispatch/Handlers/JudgeHandler.cs @@ -7,10 +7,6 @@ internal sealed class JudgeHandler : IFrameHandler { public IReadOnlyList Handle(FrameDispatchContext ctx) { - // Scripted-bot Judge (test stub): forward verbatim (carries the {spin} shape already). - if (ctx.IsScriptedBot(ctx.From)) - return new[] { new DispatchRoute(ctx.Other, ctx.Env, false) }; - // PvP: Judge is the handover gate. The player who sends Judge is the one TAKING OVER the // turn (the client rule is: receive opponent TurnEnd -> SendJudge). Receiving Judge{spin} // fires ControlTurnStartPlayer ("start MY turn"), so the {spin} must REFLECT BACK to the diff --git a/SVSim.BattleNode/Sessions/Dispatch/Handlers/TurnEndHandler.cs b/SVSim.BattleNode/Sessions/Dispatch/Handlers/TurnEndHandler.cs index 69fb6f0..f54a2eb 100644 --- a/SVSim.BattleNode/Sessions/Dispatch/Handlers/TurnEndHandler.cs +++ b/SVSim.BattleNode/Sessions/Dispatch/Handlers/TurnEndHandler.cs @@ -11,8 +11,8 @@ internal sealed class TurnEndHandler : IFrameHandler if (ctx.Type == BattleType.Bot && ctx.SenderPhase == BattleSessionPhase.AfterReady) return new[] { new DispatchRoute(ctx.From, BattleFrames.BuildJudgeBroadcast(), false) }; - // case 8: general AfterReady arm — matches (and consumes) for any non-Bot type once the - // sender is AfterReady, even if it yields no routes (legacy `break;`). + // case 8: general AfterReady arm — PvP forwards a {turnState} TurnEnd to the opponent + // (handover gate). Any non-Pvp non-Bot type that reaches AfterReady consumes the frame. if (ctx.SenderPhase == BattleSessionPhase.AfterReady) { if (ctx.Type == BattleType.Pvp && ctx.BothAfterReady()) @@ -23,16 +23,9 @@ internal sealed class TurnEndHandler : IFrameHandler var te = ctx.Env with { Body = new TurnEndBody(TurnState: 0) }; return new[] { new DispatchRoute(ctx.Other, te, false) }; } - if (ctx.Type == BattleType.Scripted) - return new[] { new DispatchRoute(ctx.Other, ctx.Env, false) }; - return Array.Empty(); // Pvp-not-both-ready → drop (Bot already returned above) } - // case 11: scripted-bot TurnEnd whose sender has no handshake phase (test stub) → forward. - if (ctx.IsScriptedBot(ctx.From)) - return new[] { new DispatchRoute(ctx.Other, ctx.Env, false) }; - return Array.Empty(); } } diff --git a/SVSim.BattleNode/Sessions/Dispatch/Handlers/TurnStartHandler.cs b/SVSim.BattleNode/Sessions/Dispatch/Handlers/TurnStartHandler.cs index 348cdcf..e7a143b 100644 --- a/SVSim.BattleNode/Sessions/Dispatch/Handlers/TurnStartHandler.cs +++ b/SVSim.BattleNode/Sessions/Dispatch/Handlers/TurnStartHandler.cs @@ -15,10 +15,6 @@ internal sealed class TurnStartHandler : IFrameHandler return new[] { new DispatchRoute(ctx.Other, frame, false) }; } - // Scripted-bot emission (test stub path): the bot already emits the {spin} shape — forward. - if (ctx.IsScriptedBot(ctx.From)) - return new[] { new DispatchRoute(ctx.Other, ctx.Env, false) }; - return Array.Empty(); } }