Implements the main public API for the core game engine:
- create_game(): deck validation, shuffling, dealing hands
- execute_action(): validates and executes all 11 action types
- start_turn()/end_turn(): turn management integration
- get_visible_state(): hidden info filtering for clients
- handle_timeout(): timeout handling for turn limits
Integrates turn_manager, rules_validator, win_conditions, and
visibility filter into a cohesive orchestration layer.
22 integration tests covering game creation, action execution,
visibility filtering, and error handling.
711 tests passing (29/32 tasks complete)
SECURITY: Implement hidden information filtering to prevent cheating.
- Create VisibleGameState, VisiblePlayerState, VisibleZone models
- get_visible_state(game, player_id): filtered view for a player
- get_spectator_state(game): filtered view for spectators
Hidden Information (NEVER exposed):
- Opponent's hand contents (count only)
- All deck contents and order
- All prize card contents
- Energy deck order
Public Information (always visible):
- Active and benched Pokemon (full details)
- Discard piles (full contents)
- Energy zone (available energy)
- Scores, turn info, phase
- Stadium in play
- 44 security-critical tests verifying no information leakage
- Tests check JSON serialization for hidden card ID leaks
- Also adds test for configurable burn damage
Completes HIGH-008 and TEST-012 from PROJECT_PLAN.json
Updates security checklist: 4/5 items now verified
- Implement rules_validator.py with config-driven action validation for all 11 action types
- Implement win_conditions.py with point/prize-based, knockout, deck-out, turn limit, and timeout checks
- Add ForcedAction model to GameState for blocking actions (e.g., select new active after KO)
- Add ActiveConfig with max_active setting for future double-battle support
- Add TrainerConfig.stadium_same_name_replace option
- Add DeckConfig.starting_hand_size option
- Rename from_energy_deck to from_energy_zone for consistency
- Fix unreachable code bug in GameState.get_opponent_id()
- Add 16 coverage gap tests for edge cases (card registry corruption, forced actions, etc.)
- 584 tests passing at 97% coverage
Completes HIGH-005, HIGH-006, TEST-009, TEST-010 from PROJECT_PLAN.json
Provides a ready-to-use REPL environment with:
- Pre-configured game state with two players and active Pokemon
- Sample card definitions (Pikachu, Charmander, Bulbasaur, Potion, Energy)
- Helper functions: make_ctx(), reset_game(), show_board()
- All imports ready (effects, models, config, RNG)
Usage: cd backend && uv run python -i references/console_testing.py
Core game state models:
- Zone: Card collection with deck operations (draw, shuffle, peek, etc.)
- PlayerState: All player zones, score, and per-turn action flags
- GameState: Complete game state with card registry, turn tracking, win conditions
Test fixtures (conftest.py):
- Sample card definitions: Pokemon (Pikachu, Raichu, Charizard, EX, V, VMAX)
- Trainer cards: Item (Potion), Supporter (Professor Oak), Stadium, Tool
- Energy cards: Basic and special energy
- Pre-configured game states: empty, mid-game, near-win scenarios
- Factory fixtures for CardInstance and SeededRandom
Tests: 55 new tests for game state models (259 total passing)
Note: GameState imported directly from game_state module to avoid
circular imports with config module.
Add long-term design consideration for forking the RPG campaign as a
standalone offline experience.
ARCHITECTURE.md:
- Add 'Offline Standalone Fork' section explaining:
- Why offline support matters (single-player RPG focus)
- Architecture principles for fork compatibility
- Core engine independence requirements
- Potential package structures and distribution options
- What stays vs what goes in a fork
AGENTS.md:
- Add 'Core Engine Independence' section with:
- Rules for keeping app/core/ decoupled
- Import boundary examples (allowed vs forbidden)
- Link to full architecture docs
This ensures all contributors understand the design constraint:
the game engine must remain completely independent of network,
database, and authentication concerns.
- Add CardDefinition and CardInstance models for card templates and in-game state
- Add Attack, Ability, and WeaknessResistance models for Pokemon card components
- Add 11 action types as discriminated union (PlayPokemon, Evolve, Attack, etc.)
- Split PokemonStage (BASIC, STAGE_1, STAGE_2) from PokemonVariant (NORMAL, EX, GX, V, VMAX, VSTAR)
- Stage determines evolution mechanics, variant determines knockout points
- Update PrizeConfig to use variant for knockout point calculation
- VSTAR and VMAX both worth 3 points; EX, GX, V worth 2 points; NORMAL worth 1 point
Tests: 204 passing, all linting clean
- Create core module structure with models and effects subdirectories
- Add enums module with CardType, EnergyType, TurnPhase, StatusCondition, etc.
- Add RulesConfig with Mantimon TCG defaults (40-card deck, 4 points to win)
- Add RandomProvider protocol with SeededRandom (testing) and SecureRandom (production)
- Include comprehensive tests for all modules (97 tests passing)
Defaults reflect GAME_RULES.md: Pokemon Pocket-style energy deck,
first turn can attack but not attach energy, 30-turn limit enabled.
- Initialize FastAPI backend with uv package manager
- Configure Black, Ruff, pytest, mypy in pyproject.toml
- Add health check endpoint and initial test
- Create AGENTS.md with coding guidelines for AI agents
- Add pre-commit hook to enforce linting and tests
- Add PROJECT_PLAN.md with 7-phase development roadmap
- Add CLAUDE.md with AI agent coding guidelines
- Add docs/ARCHITECTURE.md with technical deep-dive
- Add docs/GAME_RULES.md template for home rule definitions
- Create directory structure for frontend, backend, shared