ComputeFrames now reads (from as IHasHandshakePhase)?.Phase for the four handshake arms (InitNetwork, InitBattle, Loaded, Swap) and the TurnEnd gate, transitioning the participant's Phase instead of the session's. RealParticipant implements IHasHandshakePhase via the new Phase property; the session-level BattleSession.Phase stays for the Terminal short-circuit. Scripted dispatch + wire shape unchanged (single-Real-participant case collapses to Phase 1 semantics). Test fixture migrates FakeParticipant to FakeRealParticipant for the side that drives handshake states. The bot's TurnEnd previously rode the session-level AfterReady arm; with that arm now gated on the sender's per-participant Phase (which the bot lacks), TurnEnd joins TurnStart/Judge in the scripted-bot forwarder arm so the v1.2 burst still reaches the real participant.
12 KiB
12 KiB