Poker Engine is a server-authoritative real-time poker platform. A single Node.js process runs the REST API, the WebSocket server, the in-memory game tables and the background services. PostgreSQL holds persistent state. Clients only render what the server sends: cards, stacks, pots and action validity are all decided on the server.
System Components
| Component | Location | Responsibility |
|---|---|---|
| Game engine | src/game/ | Cards, hand evaluation, betting rules, pots, rake, showdown, and the table lifecycle for every variant |
| WebSocket server | src/websocket/ | Bridges table events to clients: public broadcasts, private prompts, personalized snapshots and sequence-aware resync |
| REST API | src/api/routes/ | Accounts, lobby, cashier, tournaments, admin and integration endpoints |
| Services | src/services/ | Business logic and persistence: wallets, tournaments, sessions, payments, settings |
| Database | prisma/schema.prisma | PostgreSQL through Prisma; schema changes ship as migrations |
| Bot system | src/game/bot/ | Bot players, decision strategies and the table-fill scheduler |
| Web client | client/src/ | Lobby, Table V2, cashier, profile and admin panel |
| Shared package | packages/shared/src/ | Types, stores and sequence-tracking helpers used by clients and server |
How a Hand Flows Through the System
- A player action arrives over the WebSocket connection and is validated against the live table.
- The in-memory
Tableinsrc/game/table/applies it and advances the betting round, deals the next street, or runs the showdown. - The table emits game events. The WebSocket layer turns them into public broadcasts and private, guaranteed-delivery messages such as
hole_cardsandaction_required. - When the hand finishes, chips are settled at the table and the hand result is persisted by the services layer.
- A client that reconnects or detects a sequence gap sends
request_table_stateto get an authoritative snapshot back.
Hands in progress live in memory, so the table process is stateful. Money movement is not: wallet and tournament prize changes go through database transactions.
Key Principles
- Server authority. The server evaluates cards and enforces betting rules. Clients never decide an outcome.
- Integer chips at the table, decimals in the ledger. Game logic works in whole chips. Wallets and ledger rows use
Decimal(18,2). - Rule profiles. Cash, private and tournament behaviour resolves through versioned rule profiles in
src/services/rule-profile.service.ts. - Database-backed settings. Game settings, feature toggles, SMTP and payment configuration are managed from the Admin Panel, not environment variables.
Key Architecture Documents
- Game Loop Implementation – Table lifecycle, street progression and the event contract
- Database Pooling – Connection pool architecture and production database scaling
- WebSocket Pipeline – Real-time message processing
- Database Migrations – Schema evolution and migration strategy
- Dual-Currency Economy – Gold/Diamond wallet, ledger, conversion, and reconciliation design
Related Documentation
- Developer Architecture – Detailed code structure
- Game Engine – Variants, evaluation, pots, rake and showdown
- Tournament Engine – Tournament lifecycle, tables and payouts
- API Documentation – REST API reference
- WebSocket Protocol – WebSocket message format