Fixed critical bugs in game recovery and play persistence:
1. Terminal REPL Auto-Recovery:
- Added _ensure_game_loaded() helper to auto-recover games from database
- Calls state_manager.recover_game() when game not in memory
- Calls _prepare_next_play() after recovery to populate snapshot fields
- Enables seamless continuation of games across REPL sessions
2. Play Validation:
- Added verification in _save_play_to_db() for required fields
- Ensures batter_id, pitcher_id, catcher_id are never NULL
- Raises ValueError with clear error message if fields missing
- Prevents database constraint violations
3. Updated Commands:
- All REPL commands now call _ensure_game_loaded()
- Commands: defensive, offensive, resolve, status, quick_play, box_score
- Fixes "Game state not found" errors on recovered games
Root Cause:
- state_manager.recover_game() rebuilds GameState from database
- But didn't populate snapshot fields (current_batter_lineup_id, etc.)
- _save_play_to_db() requires these fields to save plays
- Solution: Call _prepare_next_play() after recovery
Files Modified:
- app/core/game_engine.py - Added verification in _save_play_to_db()
- terminal_client/repl.py - Added _ensure_game_loaded() and integrated
Testing: Successfully recovered game, submitted decisions, and resolved plays
🚀 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Replaced awkward "lookback" pattern with clean "prepare → execute → save"
orchestration that captures state snapshots BEFORE each play.
Key improvements:
- Added per-team batter indices (away_team_batter_idx, home_team_batter_idx)
- Added play snapshot fields (current_batter/pitcher/catcher_lineup_id)
- Added on_base_code bit field for efficient base situation queries
- Created _prepare_next_play() method for snapshot preparation
- Refactored start_game() with hard lineup validation requirement
- Refactored resolve_play() with explicit 6-step orchestration
- Updated _save_play_to_db() to use snapshots (no DB lookbacks)
- Enhanced state recovery to rebuild from last play (single query)
- Added defensive lineup position validator
Benefits:
- No special cases for first play
- Single source of truth in GameState
- Saves 18+ database queries per game
- Fast state recovery without replay
- Complete runner tracking (before/after positions)
- Explicit orchestration (easy to debug)
Testing:
- Added 3 new test functions (lineup validation, snapshot tracking, batting order)
- All 5 test suites passing (100%)
- Type checking cleaned up with targeted suppressions for SQLAlchemy
Documentation:
- Added comprehensive "Type Checking & Common False Positives" section to CLAUDE.md
- Created type-checking-guide.md and type-checking-summary.md
- Added mypy.ini configuration for SQLAlchemy/Pydantic
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixes:
✅ Updated GameEngine._save_play_to_db() to fetch real lineup IDs
- Gets active batting/fielding lineups from database
- Extracts batter, pitcher, catcher IDs by position
- No more hardcoded placeholder IDs
✅ Shortened AbRoll.__str__() to fit VARCHAR(50)
- "WP 1/10" instead of "AB Roll: Wild Pitch Check..."
- "AB 6,9(4+5) d20=12/10" for normal rolls
- Prevents database truncation errors
✅ Created comprehensive test script (scripts/test_game_flow.py)
- Tests single at-bat flow
- Tests full half-inning (50+ plays)
- Creates dummy lineups for both teams
- Verifies complete game lifecycle
Test Results:
✅ Successfully ran 50 at-bats across 6 innings
✅ Score tracking: Away 5 - Home 2
✅ Inning advancement working
✅ Play persistence to database
✅ Roll batch saving at inning boundaries
✅ State synchronization (memory + DB)
GameEngine Verified Working:
✅ Game lifecycle management (create → start → play → complete)
✅ Decision submission (defensive + offensive)
✅ Play resolution with AbRoll system
✅ State management and persistence
✅ Inning advancement logic
✅ Score tracking
✅ Lineup integration
✅ Database persistence
Ready for:
- WebSocket integration
- Frontend connectivity
- Full game simulations
- AI opponent integration
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Core Components:
✅ GameValidator (validators.py)
- Validates game state and decisions
- Rule enforcement for baseball gameplay
- Game-over and inning continuation logic
✅ PlayResolver (play_resolver.py)
- Resolves play outcomes using AbRoll system
- Simplified result charts for MVP
- Handles wild pitch/passed ball checks
- Runner advancement logic for all hit types
- PlayOutcome enum with 12 outcome types
✅ GameEngine (game_engine.py)
- Orchestrates complete game flow
- Start game, submit decisions, resolve plays
- Integrates DiceSystem with roll context
- Batch saves rolls at end of each half-inning
- Persists plays and game state to database
- Manages inning advancement and game completion
Integration Features:
- Uses advanced AbRoll system (not simplified d20)
- Roll context tracking per inning
- Batch persistence at inning boundaries
- Full audit trail with roll history
- State synchronization between memory and database
Architecture:
GameEngine → PlayResolver → DiceSystem
↓ ↓
GameValidator StateManager
↓ ↓
Database In-Memory Cache
Ready For:
✅ End-to-end at-bat testing
✅ WebSocket integration
✅ Result chart configuration
✅ Advanced decision logic (Phase 3)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>