fix(battle-node): reflect PvP Judge back to its sender (turn handover)

Live two-client run (data_dumps/captures/battle_test) exposed a turn-handover
stall: ending a turn on client A made BOTH clients show A's turn again; the
opponent never got a turn. Root cause: JudgeHandler routed the {spin:0} Judge to
ctx.Other. The client rule is 'receive opponent TurnEnd -> SendJudge', so the
PASSIVE player (the one taking over the turn) is the Judge sender, and 'receive
Judge -> ControlTurnStartPlayer' starts the RECEIVER's turn. Routing to ctx.Other
delivered the Judge to the player who had just ended their turn, restarting it in
a closed loop while the taker-over sat on 'Opponent's Turn'.

Fix: the PvP Judge {spin} reflects back to ctx.From (the sender / turn taker-over),
matching the Bot arm's existing 'Judge to sender only' handover. The sender then
emits TurnStart, which relays to the opponent as {spin}. Updated the dispatch unit
test and the PvpHandshakeAndGameplay integration test to the real handover order
(passive sends Judge -> receives it back -> sends TurnStart -> opponent sees it).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
gamer147
2026-06-03 18:45:17 -04:00
parent c360d639f2
commit e98bd10dbe
4 changed files with 29 additions and 15 deletions

View File

@@ -400,7 +400,7 @@ public class BattleSessionDispatchTests
}
[Test]
public void Pvp_Judge_from_A_emits_spin0_to_B()
public void Pvp_Judge_from_A_reflects_spin0_back_to_sender()
{
var (s, a, b) = NewPvpSession();
DriveToAfterReady(s, a);
@@ -408,8 +408,11 @@ public class BattleSessionDispatchTests
var routes = s.ComputeFrames(a, NewEnvelope(NetworkBattleUri.Judge));
// Judge reflects BACK to its sender (the turn taker-over), not to the opponent: receiving
// Judge{spin} fires the sender's ControlTurnStartPlayer. Routing to the opponent would
// restart the just-ended player's turn (2026-06-03 two-client capture).
Assert.That(routes.Count, Is.EqualTo(1));
Assert.That(routes[0].Target, Is.SameAs(b));
Assert.That(routes[0].Target, Is.SameAs(a));
Assert.That(routes[0].Frame.Uri, Is.EqualTo(NetworkBattleUri.Judge));
var body = (SVSim.BattleNode.Protocol.Bodies.JudgeBody)routes[0].Frame.Body;
Assert.That(body.Spin, Is.EqualTo(0));