← Sol Thiessen

Since Jul 2025 · poker.soljt.ch · Personal project

Poker

Real-time multiplayer Texas Hold'em, built from scratch. Join a lobby, sit at a live table against friends or bots, and keep your chips between sessions.

Take a seat ↗Source on GitHub ↗Made for desktop

Frontend
React · TypeScript
Realtime
Flask-SocketIO
Data
PostgreSQL · Redis
Bots
Heuristic · Gemini
Deploy
Docker Compose · nginx

The game

Full hold'em rules: preflop, flop, turn and river, with side pots, all-ins and showdowns. Every player's table stays in sync over a WebSocket, and new players queue for a seat without interrupting the hand in progress.

  • An inaction timer folds a player after 45 seconds and removes them from the game.
  • Players who go broke are offered a rebuy before the next hand.
  • Every hand is written to an append-only log with the full action history, board and hole cards.

A hand, end to end

  1. LobbyCreate or join a live game
  2. SeatQueued if a hand is running
  3. DealEach player gets only their own cards
  4. BetFour rounds, 45 s to act
  5. ShowdownSide pots split, ties broken
  6. SettleChips saved, hand logged

Architecture

Where state lives. Live table state (players, bets, deck, timers) stays in memory on the backend. The database only holds accounts and chip balances, written at the end of each hand.

Hard parts

A

Nobody sees your cards

Game state is serialised separately for each player, so a client only ever receives its own hole cards.

B

Getting the chips right

The hand evaluator and pot logic are covered by tests: ranking, comparison, tie-breaking, side pots and edge cases like the ace-low straight.

C

Bots behind one interface

Any decision engine can take a seat without touching the game loop. The heuristic bot weighs made-hand strength against draw potential, pot odds, kickers and preflop bonuses. The Gemini bot sends the full game state to the API and parses a structured JSON action, falling back to a random move if the call fails.

D

Security

JWTs live in httpOnly cookies with CSRF checks on every state-changing request. Auth endpoints are rate-limited through Redis, and admin routes sit behind role-based access control.

Next

In progress: a reinforcement-learning agent to fill empty seats.

© 2026 Sol ThiessenBack to the start