Implemented hybrid state management system with in-memory game states and async PostgreSQL persistence. This provides the foundation for fast gameplay (<500ms response) with complete state recovery capabilities. ## Components Implemented ### Production Code (3 files, 1,150 lines) - app/models/game_models.py (492 lines) - Pydantic GameState with 20+ helper methods - RunnerState, LineupPlayerState, TeamLineupState - DefensiveDecision and OffensiveDecision models - Full Pydantic v2 validation with field validators - app/core/state_manager.py (296 lines) - In-memory state management with O(1) lookups - State recovery from database - Idle game eviction mechanism - Statistics tracking - app/database/operations.py (362 lines) - Async PostgreSQL operations - Game, lineup, and play persistence - Complete state loading for recovery - GameSession WebSocket state tracking ### Tests (4 files, 1,963 lines, 115 tests) - tests/unit/models/test_game_models.py (60 tests, ALL PASSING) - tests/unit/core/test_state_manager.py (26 tests, ALL PASSING) - tests/integration/database/test_operations.py (21 tests) - tests/integration/test_state_persistence.py (8 tests) - pytest.ini (async test configuration) ### Documentation (6 files) - backend/CLAUDE.md (updated with Week 4 patterns) - .claude/implementation/02-week4-state-management.md (marked complete) - .claude/status-2025-10-22-0113.md (planning session summary) - .claude/status-2025-10-22-1147.md (implementation session summary) - .claude/implementation/player-data-catalog.md (player data reference) - Week 5 & 6 plans created ## Key Features - Hybrid state: in-memory (fast) + PostgreSQL (persistent) - O(1) state access via dictionary lookups - Async database writes (non-blocking) - Complete state recovery from database - Pydantic validation on all models - Helper methods for common game operations - Idle game eviction with configurable timeout - 86 unit tests passing (100%) ## Performance - State access: O(1) via UUID lookup - Memory per game: ~1KB (just state) - Target response time: <500ms ✅ - Database writes: <100ms (async) ✅ ## Testing - Unit tests: 86/86 passing (100%) - Integration tests: 29 written - Test configuration: pytest.ini created - Fixed Pydantic v2 config deprecation - Fixed pytest-asyncio configuration 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
618 lines
20 KiB
Markdown
618 lines
20 KiB
Markdown
# Session Summary: Phase 2 Game Engine Planning
|
||
|
||
**Date**: 2025-10-22
|
||
**Time**: ~23:00 - 01:13
|
||
**Duration**: ~2 hours
|
||
**Branch**: `implement-phase-2`
|
||
**Status**: Planning Complete ✅ - Ready to Begin Implementation
|
||
|
||
---
|
||
|
||
## Session Overview
|
||
|
||
### Primary Objectives
|
||
1. Plan Phase 2: Game Engine Core implementation (Weeks 4-6)
|
||
2. Design in-memory state management architecture
|
||
3. Document all player data fields for caching
|
||
4. Create detailed weekly implementation plans
|
||
|
||
### Technologies Involved
|
||
- **Backend**: FastAPI, Python 3.13, Pydantic, SQLAlchemy (async)
|
||
- **Database**: PostgreSQL (10.10.0.42:5432)
|
||
- **State Management**: In-memory Python dictionaries + async DB persistence
|
||
- **Testing**: pytest, automated Python tests
|
||
|
||
### Overall Outcome
|
||
✅ **Successfully completed comprehensive planning for Phase 2**
|
||
- Created 4 detailed planning documents
|
||
- Resolved key architectural questions about state caching
|
||
- Documented complete player data model from Discord bot
|
||
- Established "measure twice, cut once" approach
|
||
- Ready to begin Week 4 implementation
|
||
|
||
---
|
||
|
||
## Current State
|
||
|
||
### Active Todos (from TodoWrite)
|
||
|
||
**Completed:**
|
||
1. ✅ Create detailed Phase 2 implementation plan documents
|
||
2. ✅ Document all player data fields to cache in memory
|
||
|
||
**In Progress:**
|
||
3. 🔄 Review player data catalog and supplement with any missing fields
|
||
|
||
**Pending (Week 4):**
|
||
4. ⏳ Week 4: Create Pydantic game state models with rich player cache
|
||
5. ⏳ Week 4: Implement State Manager (in-memory game state)
|
||
6. ⏳ Week 4: Implement database operations layer
|
||
7. ⏳ Week 4: Build state recovery mechanism
|
||
|
||
**Pending (Week 5):**
|
||
8. ⏳ Week 5: Implement cryptographic dice system
|
||
9. ⏳ Week 5: Build play resolver (simplified charts)
|
||
10. ⏳ Week 5: Create game engine core logic
|
||
11. ⏳ Week 5: Implement rule validators
|
||
|
||
**Pending (Week 6):**
|
||
12. ⏳ Week 6: Create polymorphic player model architecture
|
||
13. ⏳ Week 6: Implement league configuration system
|
||
14. ⏳ Week 6: Build result charts (d20 tables)
|
||
15. ⏳ Week 6: Create league API client
|
||
16. ⏳ Week 6: End-to-end testing of complete at-bat flow
|
||
|
||
### Running Services
|
||
- Backend FastAPI: Multiple instances running on port 8000 (multiple background processes)
|
||
- Frontend SBA: Running on port 3000
|
||
- Frontend PD: Running on port 3001
|
||
|
||
### Git Status
|
||
```
|
||
Branch: implement-phase-2
|
||
Modified: .claude/implementation/02-game-engine.md
|
||
Recent commits:
|
||
d8a43fa - CLAUDE: Complete Phase 1 - Frontend Infrastructure Setup
|
||
fc7f53a - CLAUDE: Complete Phase 1 backend infrastructure setup
|
||
5c75b93 - CLAUDE: Initial project setup - documentation and infrastructure
|
||
```
|
||
|
||
### Key Files Being Worked On
|
||
- `.claude/implementation/02-game-engine.md` (updated with approach)
|
||
- `.claude/implementation/02-week4-state-management.md` (created)
|
||
- `.claude/implementation/02-week5-game-logic.md` (created)
|
||
- `.claude/implementation/02-week6-league-features.md` (created)
|
||
- `.claude/implementation/player-data-catalog.md` (created)
|
||
|
||
---
|
||
|
||
## Changes Made
|
||
|
||
### Files Created
|
||
|
||
1. **`.claude/implementation/02-week4-state-management.md`**
|
||
- Comprehensive Week 4 implementation plan
|
||
- Pydantic game state models specification
|
||
- StateManager class design
|
||
- DatabaseOperations async layer
|
||
- State recovery mechanism
|
||
- Complete test specifications
|
||
|
||
2. **`.claude/implementation/02-week5-game-logic.md`**
|
||
- Week 5 implementation plan
|
||
- DiceSystem with cryptographic RNG
|
||
- PlayResolver with simplified charts
|
||
- GameEngine orchestration
|
||
- Rule validators
|
||
- Integration test framework
|
||
|
||
3. **`.claude/implementation/02-week6-league-features.md`**
|
||
- Week 6 implementation plan
|
||
- Polymorphic player models (BasePlayer → SbaPlayer/PdPlayer)
|
||
- League configuration system
|
||
- Result charts for SBA and PD
|
||
- LeagueApiClient implementation
|
||
- End-to-end testing strategy
|
||
|
||
4. **`.claude/implementation/player-data-catalog.md`**
|
||
- **CRITICAL REFERENCE**: Complete player data field specifications
|
||
- Batting card data (8 basic fields + 54 rating values per player)
|
||
- Pitching card data (7 basic fields + 60 rating values per player)
|
||
- Defensive ratings (5 fields per position, multi-position support)
|
||
- Memory usage analysis (~500-700 bytes per player)
|
||
- Usage examples for gameplay scenarios
|
||
- Data loading and caching strategies
|
||
|
||
### Files Modified
|
||
|
||
1. **`.claude/implementation/02-game-engine.md`** (lines 171-209)
|
||
- Added "Implementation Approach" section
|
||
- Documented key decisions from user
|
||
- Added links to detailed weekly plans
|
||
- Updated status to "In Progress - Planning Complete"
|
||
|
||
### No Code Files Created/Modified
|
||
This session was **planning only** - no implementation code written yet.
|
||
|
||
---
|
||
|
||
## Key Decisions & Discoveries
|
||
|
||
### Architectural Decision: Rich In-Memory Caching
|
||
|
||
**Decision**: Cache complete player objects with ALL ratings in memory, not minimal state.
|
||
|
||
**Rationale** (from Discord bot experience):
|
||
- Gameplay requires frequent access to:
|
||
- Player images for display
|
||
- Defensive ratings for x-checks (unpredictable position)
|
||
- Catcher passed ball / pitcher wild pitch for chaos rolls
|
||
- Stealing ratings, bunting ratings, etc.
|
||
- Memory cost is negligible: ~10-15KB per game (20 players × ~500-700 bytes)
|
||
- 100 concurrent games = < 2MB total
|
||
- Discord bot suffered from slow DB queries - this solves that
|
||
|
||
**Pattern Established**:
|
||
```python
|
||
class CachedPlayer(BaseModel):
|
||
# Complete player data cached
|
||
- Identity & display (12 fields)
|
||
- Batting attributes (8 fields)
|
||
- Batting ratings vL and vR (54 values total)
|
||
- Pitching attributes (7 fields)
|
||
- Pitching ratings vL and vR (60 values total)
|
||
- Defense ratings per position (Dict[str, DefenseRatings])
|
||
|
||
# Cache in GameState
|
||
home_lineup: Dict[int, CachedPlayer] # {lineup_id: player}
|
||
away_lineup: Dict[int, CachedPlayer]
|
||
```
|
||
|
||
### Decision: SBA First, PD Second
|
||
|
||
**Approach**: Build each component for SBA league first, learn lessons, apply to PD.
|
||
|
||
**Rationale**:
|
||
- SBA is simpler (fewer fields, manual result selection)
|
||
- PD adds complexity (auto-selection via scouting model)
|
||
- Ensures base case works before adding complexity
|
||
- Matches user's request
|
||
|
||
### Decision: Automated Python Testing (No WebSocket UI Tests in Phase 2)
|
||
|
||
**Approach**: Test via Python scripts and unit/integration tests, not through UI.
|
||
|
||
**Benefits**:
|
||
- Faster iteration during development
|
||
- Easier to debug game logic
|
||
- Can test edge cases more thoroughly
|
||
- UI testing comes in Phase 3
|
||
|
||
**Test Script Pattern**:
|
||
```python
|
||
# scripts/test_game_flow.py
|
||
async def test_at_bat():
|
||
state = await state_manager.create_game(...)
|
||
await game_engine.start_game(game_id)
|
||
await game_engine.submit_defensive_decision(...)
|
||
await game_engine.submit_offensive_decision(...)
|
||
result = await game_engine.resolve_play(game_id)
|
||
```
|
||
|
||
### Decision: Hybrid State Management
|
||
|
||
**Pattern**:
|
||
```
|
||
User Action → WebSocket → Game Engine
|
||
↓
|
||
Update In-Memory State (fast, <200ms)
|
||
↓
|
||
Async Write to PostgreSQL (non-blocking, <100ms)
|
||
↓
|
||
Broadcast via WebSocket
|
||
```
|
||
|
||
**Data Consistency Strategy**:
|
||
- In-memory state is source of truth for active games
|
||
- Database is async backup + historical record
|
||
- On crash: Recover from DB plays, rebuild in-memory cache
|
||
- Write-through cache pattern
|
||
|
||
### Discovery: Discord Bot Data Model Complexity
|
||
|
||
**Finding**: Paper Dynasty Discord bot has extensive player data:
|
||
- **Batting**: 27 rating fields × 2 platoon splits (vs LHP/RHP) = 54 values
|
||
- **Pitching**: 30 rating fields × 2 platoon splits (vs LHB/RHB) = 60 values
|
||
- **Defense**: Multi-position support (player can have ratings for 2-8 positions)
|
||
- **Chaos Events**: Wild pitch, passed ball, balk, pickoff ratings
|
||
- **X-Checks**: 9 position-specific x-check probabilities on pitcher cards
|
||
|
||
**Implication**: Must cache ALL this data for fast gameplay. Initial "minimal state" approach would have failed.
|
||
|
||
### Pattern: Result Selection Models
|
||
|
||
**SBA League**:
|
||
- Players see dice roll FIRST
|
||
- Select from available results on chart
|
||
- Manual decision required
|
||
|
||
**PD League**:
|
||
- Flexible approach
|
||
- Manual selection OR auto-resolution via scouting model
|
||
- Scouting model uses detailed BattingCardRatings/PitchingCardRatings
|
||
|
||
---
|
||
|
||
## Problems & Solutions
|
||
|
||
### Problem: Initial Architecture Too Simple
|
||
|
||
**Issue**: Original plan had minimal in-memory state (just current batter ID, outs, score).
|
||
|
||
**Discovery**: User explained real gameplay needs:
|
||
- "On each play there is a chance for a chaos roll if there are baserunners - need catcher passed_ball and pitcher wild_pitch"
|
||
- "X-check plays require calling <RandomDefender>.range and .error values"
|
||
- "Need to display player images for batter, runners, pitcher, catcher"
|
||
|
||
**Solution**: Switched to rich player caching with complete data model.
|
||
|
||
**Lesson**: Real-world production experience (Discord bot) revealed requirements that weren't obvious from specs.
|
||
|
||
### Problem: Unclear Data Requirements
|
||
|
||
**Issue**: Didn't know all the fields that needed to be cached.
|
||
|
||
**Solution**: Deep dive into Discord bot codebase:
|
||
- Read `paper-dynasty/database/app/routers_v2/battingcards.py`
|
||
- Read `paper-dynasty/database/app/routers_v2/pitchingcards.py`
|
||
- Read `paper-dynasty/database/app/routers_v2/battingcardratings.py`
|
||
- Read `paper-dynasty/database/app/routers_v2/pitchingcardratings.py`
|
||
- Read `paper-dynasty/database/app/routers_v2/cardpositions.py`
|
||
- Read `paper-dynasty/database/app/routers_v2/players.py`
|
||
|
||
**Result**: Created comprehensive `player-data-catalog.md` documenting all 100+ fields.
|
||
|
||
### Problem: Performance vs Consistency Trade-off
|
||
|
||
**Issue**: How to balance fast gameplay with data consistency?
|
||
|
||
**Solution**: Async write-through cache
|
||
- In-memory cache updated synchronously (fast)
|
||
- Database write happens asynchronously (non-blocking)
|
||
- On crash, rebuild from database plays
|
||
|
||
**Guarantees**:
|
||
- Response time < 500ms (in-memory reads)
|
||
- Data persisted within seconds (async writes)
|
||
- Full recovery possible from database
|
||
|
||
---
|
||
|
||
## Technology Context
|
||
|
||
### Database Server
|
||
- **Location**: `10.10.0.42:5432`
|
||
- **Database**: `paperdynasty_dev`
|
||
- **User**: `paperdynasty`
|
||
- **Connection**: `postgresql+asyncpg://paperdynasty:PASSWORD@10.10.0.42:5432/paperdynasty_dev`
|
||
|
||
### Python Environment
|
||
- **Version**: Python 3.13.3
|
||
- **Virtual Env**: `backend/venv/`
|
||
- **Activation**: `source venv/bin/activate` (from backend directory)
|
||
|
||
### Critical Dependencies
|
||
- **Pydantic**: v2.10.6 (data validation)
|
||
- **SQLAlchemy**: v2.0.36 (async ORM)
|
||
- **asyncpg**: v0.30.0 (PostgreSQL async driver)
|
||
- **Pendulum**: v3.0.0 (datetime - ALWAYS use instead of Python datetime)
|
||
- **greenlet**: Required for SQLAlchemy async
|
||
|
||
### League API References
|
||
- **SBA API**: Integration pending (Week 6)
|
||
- **PD API**: Discord bot at `/mnt/NV2/Development/paper-dynasty/database/`
|
||
|
||
### Database Models (Phase 1 Complete)
|
||
- `Game`: UUID primary key, AI support, team tracking
|
||
- `Play`: 25+ statistics fields, player FKs, on_base_code bit field
|
||
- `Lineup`: Substitution tracking, fatigue flags
|
||
- `GameCardsetLink`: PD cardset validation
|
||
- `RosterLink`: PD roster management
|
||
- `GameSession`: WebSocket state tracking
|
||
|
||
---
|
||
|
||
## Next Steps
|
||
|
||
### Immediate Actions (User Review Required)
|
||
|
||
1. **Review Player Data Catalog** (`.claude/implementation/player-data-catalog.md`)
|
||
- Check for missing fields
|
||
- Verify field types
|
||
- Confirm usage scenarios
|
||
- Answer questions at end of document
|
||
|
||
2. **Answer Architecture Questions**:
|
||
- **Variant Cards**: Are these different versions of same player in same game?
|
||
- **Offensive Column**: What is `offense_col` used for?
|
||
- **SBA Simplifications**: Cache ratings or truly use simplified charts?
|
||
- **Scouting Data**: Is BattingCardRatings the scouting data or separate?
|
||
|
||
### Once Review Complete → Begin Week 4
|
||
|
||
**First Implementation Task**: Create Pydantic game state models
|
||
- Location: `backend/app/models/game_models.py`
|
||
- Models needed:
|
||
- `CachedPlayer` (complete player with all ratings)
|
||
- `BattingAttributes`, `BattingRatings`
|
||
- `PitchingAttributes`, `PitchingRatings`
|
||
- `DefensivePosition`
|
||
- `GameState` (with rich lineup caches)
|
||
- `RunnerState`, decision models
|
||
|
||
**Test First**: Write unit tests before implementation
|
||
- `tests/unit/models/test_game_models.py`
|
||
- Test model validation
|
||
- Test helper methods
|
||
- Test platoon split lookups
|
||
|
||
### Week 4 Complete Deliverables
|
||
- ✅ Pydantic models with full player data
|
||
- ✅ StateManager with in-memory game states
|
||
- ✅ DatabaseOperations for async persistence
|
||
- ✅ State recovery from database
|
||
- ✅ All tests passing
|
||
|
||
### Week 5-6 (After Week 4)
|
||
Follow plans in:
|
||
- `.claude/implementation/02-week5-game-logic.md`
|
||
- `.claude/implementation/02-week6-league-features.md`
|
||
|
||
---
|
||
|
||
## Reference Information
|
||
|
||
### Critical Planning Documents
|
||
|
||
1. **`.claude/implementation/02-game-engine.md`**
|
||
- Phase 2 overview
|
||
- Implementation approach and decisions
|
||
- Links to weekly plans
|
||
|
||
2. **`.claude/implementation/02-week4-state-management.md`**
|
||
- Complete Week 4 plan with code examples
|
||
- Pydantic models specification
|
||
- StateManager design
|
||
- Database operations layer
|
||
- Testing strategy
|
||
|
||
3. **`.claude/implementation/02-week5-game-logic.md`**
|
||
- Dice system (cryptographic d20 rolls)
|
||
- Play resolver with result charts
|
||
- Game engine orchestration
|
||
- Rule validators
|
||
- Integration tests
|
||
|
||
4. **`.claude/implementation/02-week6-league-features.md`**
|
||
- Polymorphic player models
|
||
- League configurations (SBA vs PD)
|
||
- Result charts
|
||
- API client
|
||
- E2E testing
|
||
|
||
5. **`.claude/implementation/player-data-catalog.md`** ⭐ **MOST CRITICAL**
|
||
- Complete field specifications for caching
|
||
- Memory usage analysis
|
||
- Usage examples
|
||
- Loading strategies
|
||
- **MUST READ before implementing models**
|
||
|
||
### Discord Bot Reference Locations
|
||
|
||
**Player Data Models**:
|
||
- `/mnt/NV2/Development/paper-dynasty/database/app/routers_v2/players.py:35-62` - PlayerPydantic
|
||
- `/mnt/NV2/Development/paper-dynasty/database/app/routers_v2/battingcards.py:22-33` - BattingCardModel
|
||
- `/mnt/NV2/Development/paper-dynasty/database/app/routers_v2/pitchingcards.py:22-33` - PitchingCardModel
|
||
- `/mnt/NV2/Development/paper-dynasty/database/app/routers_v2/cardpositions.py:22-39` - CardPositionModel
|
||
- `/mnt/NV2/Development/paper-dynasty/database/app/routers_v2/battingcardratings.py:29-60` - BattingCardRatingsModel
|
||
- `/mnt/NV2/Development/paper-dynasty/database/app/routers_v2/pitchingcardratings.py:28-61` - PitchingCardRatingsModel
|
||
|
||
### Existing Backend Structure
|
||
|
||
**Database Models** (Phase 1 Complete):
|
||
- `backend/app/models/db_models.py:34-70` - Game model
|
||
- `backend/app/models/db_models.py:72-205` - Play model (extensive stats)
|
||
- `backend/app/models/db_models.py:207-233` - Lineup model
|
||
- `backend/app/models/db_models.py:10-20` - GameCardsetLink
|
||
- `backend/app/models/db_models.py:22-31` - RosterLink
|
||
- `backend/app/models/db_models.py:235-246` - GameSession
|
||
|
||
**Backend Infrastructure** (Phase 1 Complete):
|
||
- `backend/app/main.py` - FastAPI app with Socket.io
|
||
- `backend/app/config.py` - Settings with Pydantic
|
||
- `backend/app/database/session.py` - Async database session
|
||
- `backend/app/websocket/connection_manager.py` - WebSocket lifecycle
|
||
- `backend/app/websocket/handlers.py` - Socket.io event handlers
|
||
- `backend/app/utils/logging.py` - Rotating logger setup
|
||
|
||
**Empty Directories Ready for Phase 2**:
|
||
- `backend/app/core/` - Game engine, state manager, play resolver
|
||
- `backend/app/config/` - League configs (currently just app config)
|
||
- `backend/app/data/` - API client
|
||
|
||
### Important Patterns from CLAUDE.md
|
||
|
||
**DateTime Handling** - ALWAYS use Pendulum:
|
||
```python
|
||
import pendulum
|
||
now = pendulum.now('UTC') # ✅ Correct
|
||
formatted = now.format('YYYY-MM-DD HH:mm:ss')
|
||
|
||
# ❌ NEVER use:
|
||
from datetime import datetime
|
||
```
|
||
|
||
**Logging Pattern**:
|
||
```python
|
||
import logging
|
||
logger = logging.getLogger(f'{__name__}.ClassName')
|
||
logger.info(f"Message with context: {variable}")
|
||
```
|
||
|
||
**Error Handling** - "Raise or Return" pattern:
|
||
```python
|
||
# ✅ Raise exceptions for errors
|
||
def get_player(player_id: int) -> Player:
|
||
player = find_player(player_id)
|
||
if not player:
|
||
raise ValueError(f"Player {player_id} not found")
|
||
return player
|
||
|
||
# ❌ Don't return Optional unless specifically required
|
||
def get_player(player_id: int) -> Optional[Player]: # Avoid this
|
||
```
|
||
|
||
**Git Commits** - Prefix with "CLAUDE: ":
|
||
```bash
|
||
git commit -m "CLAUDE: Implement Week 4 state manager"
|
||
```
|
||
|
||
### Common Operations
|
||
|
||
**Start Backend**:
|
||
```bash
|
||
cd /mnt/NV2/Development/strat-gameplay-webapp/backend
|
||
source venv/bin/activate
|
||
python -m app.main
|
||
# Available at http://localhost:8000
|
||
# API docs at http://localhost:8000/docs
|
||
```
|
||
|
||
**Run Tests**:
|
||
```bash
|
||
cd /mnt/NV2/Development/strat-gameplay-webapp/backend
|
||
source venv/bin/activate
|
||
pytest tests/ -v
|
||
pytest tests/unit/models/test_game_models.py -v # Specific test
|
||
```
|
||
|
||
**Database Connection Test**:
|
||
```bash
|
||
psql postgresql://paperdynasty:PASSWORD@10.10.0.42:5432/paperdynasty_dev
|
||
```
|
||
|
||
---
|
||
|
||
## Performance Targets (Phase 2)
|
||
|
||
**Critical Metrics**:
|
||
- Action response: < 500ms (user action → state update)
|
||
- WebSocket delivery: < 200ms
|
||
- Database write: < 100ms (async, non-blocking)
|
||
- State recovery: < 2 seconds (rebuild from DB)
|
||
- Concurrent games: 10+ simultaneous active games
|
||
- Memory per game: ~10-15KB (20 cached players)
|
||
|
||
**How We'll Achieve Them**:
|
||
- ✅ In-memory state (no DB queries during plays)
|
||
- ✅ Async database writes (non-blocking)
|
||
- ✅ Lightweight Pydantic models (fast serialization)
|
||
- ✅ Efficient state recovery (single query with joins)
|
||
|
||
---
|
||
|
||
## Architecture Summary
|
||
|
||
### The "Two-Model" Pattern
|
||
|
||
**In-Memory (Pydantic)**:
|
||
```python
|
||
class GameState(BaseModel):
|
||
# Fast, lightweight, optimized for game logic
|
||
game_id: UUID
|
||
inning: int
|
||
outs: int
|
||
home_score: int
|
||
away_score: int
|
||
home_lineup: Dict[int, CachedPlayer] # Complete player data
|
||
away_lineup: Dict[int, CachedPlayer]
|
||
runners: List[RunnerState]
|
||
current_batter_id: int
|
||
# ...
|
||
```
|
||
|
||
**Database (SQLAlchemy)**:
|
||
```python
|
||
class Game(Base):
|
||
# Persistent, complete, auditable
|
||
id = Column(UUID, primary_key=True)
|
||
league_id = Column(String)
|
||
current_inning = Column(Integer)
|
||
home_score = Column(Integer)
|
||
# Relationships
|
||
plays = relationship("Play", cascade="all, delete-orphan")
|
||
lineups = relationship("Lineup", cascade="all, delete-orphan")
|
||
# ...
|
||
```
|
||
|
||
**Why Both?**:
|
||
- Pydantic: Fast reads, easy WebSocket serialization, optimized structure
|
||
- SQLAlchemy: Persistence, relationships, audit trail, crash recovery
|
||
|
||
**Translation Layer**: StateManager handles conversion between models
|
||
|
||
---
|
||
|
||
## Questions for User (Awaiting Answers)
|
||
|
||
1. **Variant Cards**: I saw `variant: int = 0` in batting/pitching card models. Are variants different versions of the same player that could be in the same game simultaneously? Or are they alternate ratings for different seasons?
|
||
|
||
2. **Offensive Column**: What is `offense_col` (BattingCard, PitchingCard) used for? Is this for result chart lookups or something else?
|
||
|
||
3. **SBA Simplifications**: For SBA league, should we:
|
||
- Option A: Still cache BattingCardRatings/PitchingCardRatings but use simplified result selection
|
||
- Option B: Truly simplify and not cache detailed ratings at all
|
||
|
||
4. **Scouting Data**: The PRD mentions "scouting data" for PD. Is the detailed `BattingCardRatings` / `PitchingCardRatings` (with all the probability fields) THE scouting data, or is there additional scouting information beyond those rating tables?
|
||
|
||
5. **Missing Fields**: Are there any player attributes or ratings used in gameplay that aren't captured in the player-data-catalog.md document?
|
||
|
||
---
|
||
|
||
## Success Criteria - Phase 2 Complete
|
||
|
||
By end of Phase 2, we will have:
|
||
|
||
- [x] Comprehensive planning documents ✅ (THIS SESSION)
|
||
- [ ] In-memory game state management working
|
||
- [ ] Play resolution engine with dice rolls
|
||
- [ ] League configuration system (SBA and PD configs)
|
||
- [ ] Polymorphic player models (BasePlayer, SbaPlayer, PdPlayer)
|
||
- [ ] Database persistence layer with async operations
|
||
- [ ] State recovery mechanism from database
|
||
- [ ] Basic game flow (start → plays → end)
|
||
- [ ] Complete ONE at-bat for SBA league
|
||
- [ ] Complete ONE at-bat for PD league
|
||
- [ ] All unit tests passing (90%+ coverage)
|
||
- [ ] All integration tests passing
|
||
- [ ] Dice distribution verified as uniform
|
||
- [ ] Performance targets met (<500ms response)
|
||
|
||
---
|
||
|
||
## Final Status
|
||
|
||
**Planning Phase: COMPLETE** ✅
|
||
|
||
**Ready to Begin**: Week 4 - State Management & Persistence
|
||
|
||
**Blockers**: None - awaiting user review of player-data-catalog.md
|
||
|
||
**Confidence Level**: High - comprehensive planning with proven Discord bot reference
|
||
|
||
**Next Session**: Implement Pydantic game state models after user review
|
||
|
||
---
|
||
|
||
**Session saved**: 2025-10-22 01:13
|
||
**Document**: `.claude/status-2025-10-22-0113.md` |