@idealic/poker-engine
Version:
Professional poker game engine and hand evaluator with built-in iterator utilities
134 lines (85 loc) • 8.41 kB
Markdown
# Poker Engine Integration Guide
This document provides a guide for integrating the Poker Engine into your back-end and front-end applications. It explains the core concepts, system architecture, and game lifecycle of the Poker Engine.
## Core Concepts
### The Hand as a Notation
The Poker Engine uses a standardized notation for poker games, which is called a **Hand**, as the source of truth. The Hand is similar to chess notation; it stores the actions of the players, not the current position of all the pieces. This makes it a powerful format for both storage and communication, as it allows for the transmission of the entire state without the need to manage details.
A Hand also has an **author**, which determines whose view of the game it represents. This is crucial for games with incomplete information, as not every Hand is the same, even if the game is the same. For example, each player will have a different Hand that includes their own hole cards, while the server will have a complete Hand with all players' cards.
This approach has several advantages:
- **Portability:** The Hand notation is a human-readable and portable format that can be easily stored, transmitted, and replayed.
- **Determinism:** The state of a poker game can be precisely reconstructed by replaying the actions in the Hand. This makes it easy to debug and test applications.
- **Flexibility:** The Hand notation can be used to represent a wide variety of poker variants and game types.
Each Hand is a fully self-contained version of the game, sufficient to reconstruct the game from the standpoint of a player. This is why it is so powerful to use it as both a storage and communication format, because it allows for the transmission of the entire state without the need to manage details.
### The Game as a Vision of the Table
The Poker Engine provides a rich and detailed vision of the game table state. The **Game** object contains all the information needed to render a poker game, including:
- The players at the table and their current status (e.g., stack size, action status)
- The community cards on the board
- The size of the pot
- The current betting round
- The next player to act
- The betting status of the game
- The completion status of the game
- Which actions can be taken by the player, such as which buttons should be enabled
- How much time the player has to make an action
- Winnings and losses of each player
- Rake computations
Separately, there are **stats**, which are stored inside the Game object to provide a deeper analytics view.
This comprehensive game state facilitates the creation of user interfaces that accurately reflect the state of the game.
## System Architecture
### Client-Server Model
The Poker Engine runs on both the client and the server. Even though the client and server have different responsibilities, the shared engine allows both parties to advance the game independently.
**Client-Side Responsibilities:**
- **Enabling Actions:** The client-side engine is responsible for enabling actions for the user (e.g., showing the bet button).
- **Optimistic Rendering:** By having the engine on the client side, optimistic rendering can be implemented. This means the game state can be passed and the game moved forward without needing server acknowledgment, providing a smoother user experience.
**Server-Side Responsibilities:**
- **Action Validation:** The server is the ultimate authority on what actions are valid.
- **Game Sanitization:** The server is responsible for sanitizing the Hand for each player.
- **Randomness:** The server is responsible for dealing with randomness, such as shuffling the deck and dealing cards.
### Single Endpoint Architecture
The entire game flow is handled by a single endpoint on the backend (e.g., `/game/poker`). This endpoint is responsible for taking the state from the client, advancing the game state, and restarting a new game if necessary.
The backend is a regular stateless API that serves requests and sends responses. There are no long-running pieces of code; everything operates as request and response.
### Modular Backend
The backend endpoint for poker will be reused by other games. With this modular structure, the Poker Engine can be plugged in and out, creating a system that facilitates the reuse of networking and game code.
### The Lobby and Table System
The Poker Engine is only responsible for the logic of a single poker hand. The player experience of browsing for games, joining a table, waiting for a game to start, and advancing from one game to another is handled by a separate **Table System** on the backend. This lobby system is going to be reused for other card games as well, so this is not just a poker feature.
The Table System is also responsible for:
- Assigning stacks to players
- Returning stacks
- Making payouts when a player is unseated
Guidance and specifications will be provided for the Table System. The backend is also responsible for handling timeouts, which is not a Poker Engine concern.
### Backend Scope of Work
The backend has three main components:
1. **The Table System:** Responsible for the lobby, seating players, and managing the overall game flow (starting new games, etc.).
2. **The Game Endpoint:** A single endpoint that takes the client's state, advances the game, and returns the new state.
3. **The Timeout Polling Script:** A script that periodically checks for timeouts in all games and applies actions on behalf of players who have timed out.
## Game Lifecycle
The Poker Engine is a pipeline for processing poker games. It is a request-response system, not a real-time system. Here are the different phases of the game:
### 1. Pre-Game Creation
Before a game can be created, players are seated at a table by the **Table System**. This system is part of the casino backend and is not part of the Poker Engine.
### 2. Game Creation
1. **Creation:** A new game is created by the Table System.
2. **Initial State:** The server creates the initial state of the `Hand`, which includes the game seed.
3. **Initial Dealer Actions:** The server immediately runs all initial dealer actions (e.g., shuffling, dealing hole cards).
4. **Store:** The initial `Hand` is stored in the database.
5. **Initial Update:** An initial sanitized `Hand` is sent to all players, letting them know who is at the table and that the game has started.
6. **Await Action:** The server implicitly awaits the first player's action. Once the request has been served, a timeout is set for the player to act.
### 3. Player Action Loop
The player action loop is stateless from the perspective of the server endpoint.
1. **Receiving:** A `Hand` is received from a client containing a new action.
2. **Loading:** The current state of the hand is loaded from the database.
3. **Merging:** The client's `Hand` is merged with the server's `Hand`.
4. **Applying:** The new action is applied to the game state by using the engine to process the new action and update the game.
5. **Storing:** The updated `Hand` is stored in the database.
6. **Sanitizing:** The `Hand` is sanitized for each player.
7. **Updating:** The sanitized `Hand` is sent to each player.
### 4. Dealer Actions and Game Completion
1. **Dealer Actions:** After a betting round is complete, the server executes the dealer's actions (e.g., dealing the flop, turn, river).
2. **Determine Win State:** At the end of the hand, the winner and the win state are determined.
3. **Start New Game:** The Table System starts a new game.
### 5. Timeout Handling
There is a periodical polling request that checks for timeouts every second for all games. If a timeout is detected, the system automatically applies an action on behalf of the user (e.g., fold). This is a stateless system that runs periodically every second for all games, not just one game.
## Related Documentation
- **[API Reference](./API.md)** - Complete API documentation for Poker.Game, Poker.Hand, and Poker.Command methods
- **[Hand Notation](./HAND.md)** - Detailed specification of the Poker.Hand notation format
- **[Statistics](./STATS.md)** - Analytics and statistics capabilities of the engine
- **[Frontend Integration](./integration/frontend.tsx)** - React component example for client-side integration
- **[Backend Integration](./integration/backend.ts)** - Server-side integration example (TODO)