Concepts / Networked Poker Game Architecture

Networked Poker Game Architecture

The full Poker game state is known only to the PokerHub, not to the players.

  • Programming

Why One Shared Copy Falls Short

When people first build a networked card game, they often choose the simplest possible design. They keep one complete record of the game and send that record to everyone after each move. For games where all information is open to every participant, this design works well. Poker is different, and the reason it is different is the heart of this article.

What do you think happens?

Before reading on: should both players in a networked Poker game receive the same complete copy of the game state after every change?

  • Yes, one shared copy is simplest and every player should see it

  • No, each player should receive only the information they are allowed to know

Reveal answer
Answer:

No. Each player should receive only the information they are allowed to know.

Poker hides information from players. A full shared copy would reveal the opponent's cards and the complete order of the deck, which a player should not be able to see during play. The answer depends on what a player is allowed to know, and that is exactly where Poker differs from the simpler games in this chapter.

Full state to PlayerAincludes everythingView for Player Aonly what A may knowFull state to PlayerBincludes everythingView for Player Bonly what B may knowsame recordseparate objects
What would a player see if the hub sent the same full state object to everyone, compared with sending each player a filtered copy? The changed entries are the ones a player should never receive from the other side.

The left side of the figure is the simple design. Both players receive the same record, so each one can read the other's private information. The right side is the design the Poker application uses: each player receives an object built only for them. The rest of this article explains why that separation is necessary and how the hub produces it.

Two Problems with Broadcasting the Full State

Poker is considerably more complicated than TicTacToe, and its game state grows in step with that complexity. Sending that state to everyone creates two separate problems for a networked design. Each problem applies on its own, so it helps to name them separately.

Why Hiding Data in the Client Fails

A reasonable first thought is that the client program can simply hide the information from the screen. The player sees only what they should, and the problem appears to be solved. The source points out why this is not enough. A client program is software the player controls, so a player who writes a substitute client can read the hidden information directly.

Where the Full State Lives

The solution in the Poker application separates two ideas that the simple design merged together. The first idea is the full game state, which is kept in exactly one place: the PokerHub. The PokerHub is the only component that knows everything about the game. The second idea is what players are allowed to know. That information is delivered through a different kind of object, a PokerGameState, and each PokerGameState describes the game only from the perspective of one particular player.

The source does not list every field the hub stores, so this article does not claim a complete list. It is clear on the two important points. The hub holds the full information, including the complete order of the deck and every player's cards. A single player's view contains only what that player may know, which includes their own information but not the opponent's cards or the deck order.

Deck orderhub onlyOwn cardspresent in viewOpponent's cardshub onlyShared gameinformationpresent in viewOwn cardsin hub and own viewOpponent's cardsabsent from view
Which information exists only in the hub, and which information appears in a player's view? Read each column as a set of facts: the hub column is complete, and the player column is limited to that player's perspective.

How One Change Becomes Two Views

The process is triggered by change. Whenever the state of the game changes, the PokerHub does not update a single shared record and broadcast it. Instead, it builds two different PokerGameState objects, one for each player's point of view, and sends each object to the player it was built for.

Game changefor example, one bet placedPokerHub full stateupdated oncePokerGameState forPlayer Aview built for APlayer Areceives only A's objectPokerGameState forPlayer Bview built for BPlayer Breceives only B's objectapplied by hubfiltered for Afiltered for Bsent to Asent to B
When the game state changes, how does one authoritative state at the PokerHub become a different filtered object for each player, and where does each copy go? Follow the arrows from the change to the player who receives each object.
  1. 1
    A game change happens, such as one bet being placed.
  2. 2
    The PokerHub applies the change to its one full game state.
  3. 3
    The hub builds a PokerGameState for Player A, describing the game only from A's point of view.
  4. 4
    The hub builds a separate PokerGameState for Player B from B's point of view.
  5. 5
    The hub sends each object to the one player it was built for. Neither player receives the other player's object, and neither receives the hub's complete record.

The figure is a summary of this flow, and it should be read as a rule: one change produces two objects, and each object goes to exactly one player. The rule also explains the efficiency problem from earlier. The hub does not need to resend a whole shared record to everyone, because each player receives only the object prepared for them.

Mistakes Learners Make

  • Common mistake

    Assuming the client can hide the opponent's cards on screen, so the server can send everything

    Why it fails

    The client is software the player controls. A player who writes a substitute client can read whatever was sent to their machine.

    Do this instead

    Keep sensitive information off the wire entirely. Filter what the server sends, not what the client displays.

  • Common mistake

    Thinking the simplest design, one full record sent to everyone, is fine for Poker because it is fine for TicTacToe

    Why it fails

    TicTacToe has no hidden information that must be kept from a participant. Poker does, so a full shared record exposes the opponent's cards and the deck order.

    Do this instead

    Ask for each piece of information who should be allowed to see it before choosing what to send.

  • Common mistake

    Believing the PokerGameState is a second copy of the full game state

    Why it fails

    Each PokerGameState is a view of the game from one player's point of view. It is not the authoritative record.

    Do this instead

    Remember that the full state lives in exactly one place, the PokerHub, and each PokerGameState is a filtered object built from it.

  • Common mistake

    Assuming the hub only needs to send data when a major event happens, rather than on every change

Practice: Who Can See It

MEDIUM

A two-player Poker hand is in progress. For each item below, decide whether it belongs only in the PokerHub, in Player A's view, in Player B's view, or in both player views. Items: the complete order of the deck; Player A's own cards; Player B's cards; the fact that a bet was just placed. Explain your choice for each item using the rule that each player may know only what they are allowed to know.

Hints
  • Ask whether the item is hidden information, such as the deck order or an opponent's cards.
  • Ask whether the item is something every participant is allowed to know after a change, such as a placed bet.
  • Remember that the hub holds everything, but a player view is limited to that player's perspective.

Architecture Summary

  1. 1
    The full Poker game state is known only to the PokerHub, not to the players.
  2. 2
    Broadcasting one shared full copy to everyone fails for Poker because of efficiency and, more importantly, because it reveals hidden information such as the opponent's cards and the deck order.
  3. 3
    Hiding data in the client does not protect it, because a player can substitute their own client; sensitive information must never be sent to the player.
  4. 4
    When the game changes, the PokerHub creates a separate PokerGameState for each player and sends each object only to the player it was built for.

At a glance

  • The full Poker game state is known only to the PokerHub, not to the players.
  • A single shared copy would expose hidden information such as the opponent's cards and the deck order, and sending full copies on every small change is inefficient.
  • Hiding data in the client does not protect it, so security must come from what the server sends.
  • On each change the PokerHub builds one PokerGameState per player and sends each object only to its intended recipient.