Commit Graph

3 Commits

Author SHA1 Message Date
gamer147
77fb93f3ea fix(battle-node): real mulligan card replacement + opponent TurnStart push
Two issues caught during v1 smoke at the mulligan / first-turn boundary:

1) BuildSwapResponse ignored the player's idxList and echoed the same
   3-card hand back. The client diffs the new self[] against the Deal
   to compute "drawn cards" — empty diff against the same hand throws
   "Card swap failed: AbandonCards[X]/DrawCards[]". Replace swapped
   idxs with fresh deck idxs (initial hand was 1/2/3, deck has 4..30
   still available). Same hand must flow into Ready since the client
   diffs again there. Move the hand computation into a new helper
   ComputeHandAfterSwap and have ComputeResponses thread it through
   both BuildSwapResponse and BuildReady.

2) The client doesn't transition to the "Opponent's turn…" display
   on its own after sending TurnEnd — it waits for the server to push
   an opponent TurnStart (per prod TK2 capture line 14). Without it
   the UI just sits on the end-of-turn frame. Add a TurnEnd handler
   that pushes a minimal TurnStart{spin} and transitions to a new
   OpponentTurn phase, which IS the documented v1 stopping point.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-01 08:30:44 -04:00
gamer147
e06d97ef6f fix(battle-node): respond to InitBattle/Loaded, not InitNetwork
Pushing Matched in response to InitNetwork lands it before
MatchingInitBattle() finishes wiring up the OnReceivedEvent handler
and setting status=Connect. The client's Matched-case in
ReactionReceiveUri only transitions to StartLoad when status is
Connect at the moment of receipt; otherwise the frame is silently
dropped at the state machine and the matchmaking UI never advances.

The real connect-handshake sequence (per MatchingNetworkConnectChecker
+ Matching.cs):
  1. WS opens.
  2. Client emits InitNetwork (cat=general).
  3. Server replies InitNetwork ack → _initNetworkSuccess = true.
  4. MatchingInitBattle: status=Connect; emit InitBattle; subscribe
     OnReceivedEvent matching handler.
  5. Server replies Matched → status=StartLoad, StartBattleLoad.
  6. Asset load done → client emits Loaded.
  7. Server replies BattleStart + Deal → status=Prepared, GotoBattle.

Add AwaitingInitBattle phase, gate Matched on InitBattle receipt, and
gate BattleStart+Deal on Loaded receipt. Update dispatch and
integration tests to walk the new sequence; InitBattle's wire cat is
Matching(2), not Battle(1).

Caught during v1 smoke walkthrough — battle-traffic.ndjson showed the
client receiving Matched/BattleStart at sub-millisecond gaps after
InitNetwork ack, but never advancing past matchmaking.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-01 02:08:04 -04:00
gamer147
a306295fe2 feat(battle-node): BattleSession skeleton with EIO/SIO read pump 2026-05-31 22:10:17 -04:00