Best practices for server-authoritative timers, turn order, and synchronized UI in a 4-player card game (Unity + SFS2X)
Posted: 18 Sep 2025, 15:57
Game summary (brief & clear):
Private room, exactly 4 players, fixed teams (1&3 vs 2&4).
Phases per hand:
Intro/seating →
Deal 5 cards to each + one face-up middle card →
Bidding (up to two rounds). Rules decide who may respond and who wins the contract (sometimes suit choice required).
Deal to 8 cards per player (winner or partner may take the middle, depending on contract).
Play 8 tricks: must follow suit; trump may apply with overtrump/overcut rules; trick winner leads next.
Score per trick and contract; hands repeat with dealer rotating.
The game has many validations (legal bids, who may respond, must-follow-suit, trump overcut, timeouts).
Requirements:
Server-authoritative state machine: one turn timer; on expiry do auto-pass/auto-play and advance turn.
All clients must see the same state & timers (whoseTurn, timeLeft, current bid, played cards, trick winner, scores).
Atomic action processing (reject out-of-turn and duplicates).
Reconnect: a snapshot to rebuild UI instantly (phase, dealer, contract, my hand, middle card, bids so far, current trick, whoseTurn, timerEndsAtMs, scores).
Questions (seeking best practices on SFS2X):
Extension structure: Would you recommend one game controller per Room (room-scoped state) with specific RequestHandlers (StartGame, Bid, PlayCard, Sync), or a shared/global controller? Any template you suggest?
Timers: Use SFS2X TaskScheduler vs ScheduledExecutorService? Pattern to avoid drift/races (e.g., broadcast serverEpochMs + duration once, clients render countdown locally)?
State propagation: When to use RoomVariables (coarse snapshot / rejoin) vs custom send() GameEvent messages (bids, plays, turn, scores)? Any guidance to keep it consistent and bandwidth-light?
Validation & idempotency: Recommended pattern to reject stale/duplicate actions (per-turn sequence number, action tokens, or server-stamped seq)?
Reconnect snapshot: What minimal fields would you include, and do you have a sample approach for rejoin after disconnect?
Any official samples or docs for a server-authoritative, turn-based card game with synchronized UI/timers?
Thanks!
Private room, exactly 4 players, fixed teams (1&3 vs 2&4).
Phases per hand:
Intro/seating →
Deal 5 cards to each + one face-up middle card →
Bidding (up to two rounds). Rules decide who may respond and who wins the contract (sometimes suit choice required).
Deal to 8 cards per player (winner or partner may take the middle, depending on contract).
Play 8 tricks: must follow suit; trump may apply with overtrump/overcut rules; trick winner leads next.
Score per trick and contract; hands repeat with dealer rotating.
The game has many validations (legal bids, who may respond, must-follow-suit, trump overcut, timeouts).
Requirements:
Server-authoritative state machine: one turn timer; on expiry do auto-pass/auto-play and advance turn.
All clients must see the same state & timers (whoseTurn, timeLeft, current bid, played cards, trick winner, scores).
Atomic action processing (reject out-of-turn and duplicates).
Reconnect: a snapshot to rebuild UI instantly (phase, dealer, contract, my hand, middle card, bids so far, current trick, whoseTurn, timerEndsAtMs, scores).
Questions (seeking best practices on SFS2X):
Extension structure: Would you recommend one game controller per Room (room-scoped state) with specific RequestHandlers (StartGame, Bid, PlayCard, Sync), or a shared/global controller? Any template you suggest?
Timers: Use SFS2X TaskScheduler vs ScheduledExecutorService? Pattern to avoid drift/races (e.g., broadcast serverEpochMs + duration once, clients render countdown locally)?
State propagation: When to use RoomVariables (coarse snapshot / rejoin) vs custom send() GameEvent messages (bids, plays, turn, scores)? Any guidance to keep it consistent and bandwidth-light?
Validation & idempotency: Recommended pattern to reject stale/duplicate actions (per-turn sequence number, action tokens, or server-stamped seq)?
Reconnect snapshot: What minimal fields would you include, and do you have a sample approach for rejoin after disconnect?
Any official samples or docs for a server-authoritative, turn-based card game with synchronized UI/timers?
Thanks!