Skip to content

Conversation

@lox
Copy link
Owner

@lox lox commented Nov 15, 2025

Hand History Tracking with PHH Format

Implements hand history recording using the PHH (Poker Hand History) standard format - a TOML-based academic standard (IEEE CoG 2024) designed for poker AI research. Enables post-game analysis, bot debugging, and ML training dataset creation.

Key Features

100% PHH Spec Compliance: Implements all required and optional fields from the official specification. No custom extensions.

Chronological Board Tracking: Fixed board card ordering by tracking actual dealing sequence instead of bitset iteration. Flop/turn/river cards emit in correct order.

Player Rotation: SB-first ordering per PHH spec with proper blind tracking per position.

High-Performance Buffered Recording: In-memory buffering with async disk I/O. Flushes every 10s/100 hands. Zero performance impact (350+ hands/sec maintained).

Multi-Game Architecture: Per-game file isolation (hands/game-{id}/session.phhs), mutex-protected buffers, partial flush recovery, section counter resumption on restart.

Failure Recovery: 3-strike disable policy, graceful degradation, no data loss on partial flush failures.

Privacy Controls: Hole cards masked as ???? by default during deal. Showdown cards (publicly revealed) always recorded. Opt-in with --hand-history-hole-cards to include all private hole cards.

UTC Timestamps: All timestamps normalized to UTC for consistency.

Usage

# Enable recording
pokerforbots spawn --spec "complex:6" --hand-limit 100 --hand-history

# Include private hole cards (debugging only)
pokerforbots spawn --spec "complex:6" --hand-limit 100 --hand-history --hand-history-hole-cards

# Render/replay hands
pokerforbots hand-history render hands/game-default/session.phhs
pokerforbots hand-history render hands/game-default/session.phhs --limit 3

Example Output

[1]
variant = "NT"
table = "default"
seat_count = 3
seats = [2, 3, 1]
antes = [0, 0, 0]
blinds_or_straddles = [5, 10, 0]
min_bet = 10
starting_stacks = [995, 990, 1000]
finishing_stacks = [985, 1000, 1000]
winnings = [0, 10, 0]
actions = [
  "d dh p1 ????",
  "d dh p2 ????",
  "d dh p3 ????",
  "p3 cc",
  "p1 cc",
  "p2 cc",
  "d db Kh7d4s",
  "p1 cc",
  "p2 cc",
  "p3 cc",
  "d db 6s",
  "p1 cc",
  "p2 cc",
  "p3 cc",
  "d db Ah",
  "p1 cc",
  "p2 cc",
  "p3 cc",
  "p2 sm 5cAc",
  "p1 sm 9h2d",
  "p3 sm KsQs",
]
players = ["bob", "charlie", "alice"]
hand = "hand-1"
time = "12:34:56"
time_zone = "UTC"
day = 16
month = 11
year = 2025

Player-indexed arrays (players, seats, antes, blinds_or_straddles, starting_stacks, finishing_stacks, winnings) start with the small blind and wrap clockwise per PHH spec.

Implementation

Core Changes:

  • internal/game/hand.go - Added boardOrder slice and BoardCards() method for chronological tracking
  • internal/phh/ - PHH encoder, types, card notation helpers, bulk .phhs format
  • internal/server/hand_history/ - Buffered monitor with player rotation, manager with flush coordination
  • cmd/pokerforbots/hand_history_cmd.go - Render command with playback engine

Configuration Flags:

  • --hand-history - Enable recording (default: disabled)
  • --hand-history-dir - Base directory (default: hands)
  • --hand-history-flush-secs - Flush interval (default: 10s)
  • --hand-history-flush-hands - Flush count threshold (default: 100)
  • --hand-history-hole-cards - Include all private hole cards (default: false)

Performance: ~200KB memory per game, ~2MB per 1000 hands, <1% throughput overhead

Testing

  • Comprehensive unit tests with race detection (go test -race ./...)
  • Integration tests for multi-game isolation, graceful shutdown, partial flush recovery
  • Board ordering verified with deterministic seeded decks
  • Section counter resumption verified across restarts
  • Showdown tracking accuracy tests

Documentation

Breaking Changes

None. Opt-in feature, disabled by default.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@lox lox force-pushed the feat/hand-history-tracking branch from ad8d05d to 90cc33e Compare November 15, 2025 04:39
@lox lox changed the title feat/hand history tracking feat: hand history tracking Nov 15, 2025
@lox lox force-pushed the feat/hand-history-tracking branch from 90cc33e to 86f56ef Compare November 15, 2025 07:48
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@lox lox force-pushed the feat/hand-history-tracking branch 7 times, most recently from 31b333b to 2526697 Compare November 16, 2025 05:09
lox added 6 commits November 16, 2025 16:40
- Add boardOrder slice to HandState to preserve dealing sequence
- Implement BoardCards() method for chronological access
- Update hand_runner to use BoardCards() instead of bitset iteration
- Add TestBoardCardsPreserveDealingOrder with deterministic verification
- Add integration tests for board emission ordering

This fixes PHH board card ordering by tracking the actual sequence
cards are dealt rather than relying on bitset iteration order.
- Add HandHistory struct with all spec-compliant fields
- Implement TOML encoder with proper field ordering
- Add card notation helpers (10h → Th conversion)
- Support player rotation (SB-first ordering per spec)
- Implement bulk .phhs format with section headers
- Add comprehensive encoder tests

Implements the Poker Hand History (PHH) standard format
as specified at https://phh.readthedocs.io/
- Implement Monitor with mutex-protected buffer and async flushing
- Add Manager for server-wide flush coordination
- Support player rotation and blind tracking per PHH spec
- Track chronological board progression per street
- Implement failure state machine (3 strikes → disable)
- Prevent race conditions in CreateMonitor with double-check locking
- Add comprehensive tests with race detection

Buffering reduces disk I/O to ~1 write per 100 hands or 10 seconds.
- Wire Manager into Server lifecycle with graceful shutdown
- Add hand history config fields (dir, flush interval, hole cards)
- Create Monitor per game with automatic registration
- Add --hand-history flags to spawn and server commands
- Flush all buffers on server shutdown (zero data loss)
- Update Server tests to cover hand history integration

Hand history recording disabled by default for backward compatibility.
- Implement 'hand-history render' command for PHH file replay
- Add playback engine that reverses player rotation to seat positions
- Infer button position from PHH ordering (SB-first convention)
- Support both .phh and .phhs formats
- Add comprehensive playback tests
- Support --limit flag for rendering subset of hands

Enables post-game analysis and hand review workflows.
- Add comprehensive hand-history.md with format guide and examples
- Update operations.md with hand history usage instructions
- Add analyze-phh.py example for Python integration
- Add implementation plan document
- Update README with hand history feature
- Update TODO.md to mark v1.0 complete

Provides complete documentation for hand history feature including
PHH format specification, CLI usage, and integration examples.
@lox lox force-pushed the feat/hand-history-tracking branch from fd759bb to 49e03fb Compare November 16, 2025 05:40
- Convert all timestamps to UTC in populateTimeFields
- Remove time_zone_abbreviation field (non-standard)
- Update documentation to clarify UTC usage
- Update tests to reflect UTC-only format

Ensures consistent time handling across all PHH files regardless
of server timezone configuration.
@lox lox force-pushed the feat/hand-history-tracking branch from 49e03fb to e59144c Compare November 16, 2025 07:13
@lox
Copy link
Owner Author

lox commented Nov 16, 2025

@codex review please?

- Mark status as complete with all phases done
- Remove outdated bug section (all bugs fixed)
- Update file format examples to show [1] section headers
- Update acceptance criteria with all items checked
- Add completed implementation details (UTC, player rotation, showdown tracking)
- Remove reference to deleted analyze-phh.py example
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

- Add dedicated flushMu to prevent concurrent flush races
- Track partial flush progress and only remove successfully written hands
- Resume section counter from existing file on Monitor creation
- Prevent section number gaps on partial failures
- Add helpers: writeHand, finalizeFlush, readLastSectionCounter

Ensures hand history files maintain consistency even with partial
flush failures or server restarts.
@lox
Copy link
Owner Author

lox commented Nov 16, 2025

@codex issues addressed, review again please.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@lox lox merged commit 6d9099d into main Nov 16, 2025
4 checks passed
@lox lox deleted the feat/hand-history-tracking branch November 16, 2025 08:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants