Design a Multiplayer Card Game
A multiplayer card game is a turn-based service that seats players at tables, deals hidden hands and runs play under a turn timer. Turn-based means players act one at a time in a fixed order, and the server owns the deck and the hands.
The ask
Players join a table, receive a hidden hand and play cards in turn order. A hand or a round ends, scores update, and the table plays on.
The game is turn-based, so exactly one player may act at any moment. Everyone else watches the same public state.
Players join from phones on uneven links. Drops and returns mid-hand are normal events.
Fairness rests on two secrets. The deck order and every rival hand must stay hidden until cards are played.
Estimate the scale
Peak load is 100,000 tables at once. A table seats 6 players.
100,000 tables x 6 players = 600,000 players at peak.
Each player acts once every 10 seconds on average. That is a stated figure for one player.
600,000 players / 10 seconds = 60,000 actions per second.
Most actions are tiny. The cost sits in holding many live tables and pushing every action to all watchers at the table.
API and data
The join operation takes a player and a game kind. It returns a table seat or a place in a waiting pool.
The act operation takes a table, a player and an action, such as playing a card or passing. It returns the new public state and the player's own hand.
The leave operation takes a table and a player. It marks the seat as away and starts the return window.
A table record holds seats, a state, the player to act and a turn deadline. The state moves from waiting to dealing to playing to scoring.
A hand record lives only on the server. It holds one player's cards, linked to the table and the round.
High-level design
A lobby service fills tables from waiting pools by game kind and stakes or level. Filled tables hand over to a game server.
One game server hosts a table for its whole life. That server is the single writer for the deck, hands and turn order.
Players hold a WebSocket connection to the game server. Actions go up, and per-player views come down.
A view is built per player at send time. It carries public cards, rival card counts and the receiver's own hand only.
Scores and finished rounds move to storage. Live tables stay in memory on their game server.
Deep dive: hidden state
The deck is shuffled on the server with a random source the players cannot predict. The shuffled order is stored with the round.
A stored deck order makes a disputed round replayable. Reviewers can check a deal after the round ends.
No message ever carries another player's cards. Even error responses and reconnect views follow the same per-player rule.
Cards become public only by being played. The public pile is the one shared truth every view agrees on.
A hash of the deck order can be shown before play and the order revealed after. Players can then verify the deal was fixed in advance.
Deep dive: the turn timer
Each turn carries a deadline kept by the server. The client timer is a display copy.
An action counts only if the server receives it before the deadline. Late actions meet the next state and fail cleanly.
A missed deadline triggers a default action, such as a pass or an automatic play. The table never stalls on one absent player.
Repeated timeouts mark the seat as away. A simple standing policy plays for the seat until the player returns or the round ends.
When a player drops
A dropped connection keeps the seat and the hand. The turn timer and the standing policy cover the gap.
Reconnect returns a fresh per-player view. The returning player sees the public state and their own hand, nothing more.
A player gone past the return window leaves the table at round end. Scores settle from the stored record.
A dead game server is the hard case. Tables there end, stakes or points are settled from the last stored round state, and players are told plainly.
Evaluation and trade-offs
Server-owned hidden state makes fairness enforceable. The price is per-player views built for every message.
Turn timers keep tables moving at the cost of rushed decisions. Longer timers feel fairer and hold tables longer.
One writer per table keeps turns and scores exact. A multiplayer card game earns trust when the deck, the hands and the turn order cannot be argued with.
Peak actions are many and tiny. The design spends its budget on connections and views, not on computation.
Scale at a glance
| Measure | Figure |
|---|---|
| Tables at peak | 100,000 |
| Players at a table | 6 |
| Players at peak | 600,000 |
| Actions per second | 60,000 |
Exercise
Why does the server send each player only their own hand?