mantimon-tcg/backend/app/core/README.md
Cal Corum 3ed67ea16b Add Active Effects system design and module README files
Design Documentation:
- docs/ACTIVE_EFFECTS_DESIGN.md: Comprehensive design for persistent effect system
  - Data model (ActiveEffect, EffectTrigger, EffectScope, StackingMode)
  - Core operations (register, remove, query effects)
  - Integration points (damage calc, energy counting, retreat, lifecycle)
  - Effect categories from Pokemon Pocket card research (~372 cards)
  - Example implementations (Serperior, Greninja, Mr. Mime, Victreebel)
  - Post-launch TODO for generic modifier system

Module README Files:
- backend/app/core/README.md: Core engine overview and key classes
- backend/app/core/effects/README.md: Effects module index and quick reference
- backend/app/core/models/README.md: Models module with relationship diagram

Minor cleanup:
- Revert Bulbasaur weakness to Fire (was test change for Lightning)
- Clean up debug output in game walkthrough
2026-01-26 22:39:02 -06:00

196 lines
5.1 KiB
Markdown

# Core Game Engine Module
The `app.core` module contains the platform-independent game engine for Mantimon TCG. This module is designed to be **completely decoupled** from network and database concerns to enable both online multiplayer and a future offline/standalone version.
## Architecture Principle
> **The core engine should remain forkable as a standalone offline game.**
See [ARCHITECTURE.md](/docs/ARCHITECTURE.md#offline-standalone-fork) for details on this design goal.
### Import Boundaries
```python
# ALLOWED in app/core/
from app.core.models import CardDefinition, GameState
from app.core.config import RulesConfig
from app.core.rng import RandomProvider
# FORBIDDEN in app/core/
from app.services import CardService # NO - DB dependency
from app.api.deps import get_current_user # NO - Auth dependency
from sqlalchemy import Session # NO - DB dependency
```
---
## Submodules
| Directory/File | Description |
|----------------|-------------|
| `models/` | Pydantic models for cards, game state, actions |
| `effects/` | Effect system for abilities and attacks |
| `engine.py` | `GameEngine` - main orchestrator |
| `config.py` | `RulesConfig` and sub-configs |
| `turn_manager.py` | Turn/phase state machine |
| `rules_validator.py` | Action validation |
| `rng.py` | Random number generation |
| `visibility.py` | Hidden information filtering |
| `win_conditions.py` | Win/loss detection |
| `enums.py` | Shared enumerations |
---
## Key Classes
### GameEngine (`engine.py`)
The primary public API for all game operations.
```python
from app.core import GameEngine, RulesConfig
engine = GameEngine(rules=RulesConfig())
result = engine.create_game(
player_ids=["p1", "p2"],
decks={"p1": deck1, "p2": deck2},
card_registry=registry,
)
game = result.game
# Execute actions
action_result = await engine.execute_action(game, "p1", AttackAction(attack_index=0))
```
### RulesConfig (`config.py`)
Configures all game rules - deck sizes, prize counts, per-turn limits, etc.
```python
from app.core import RulesConfig
rules = RulesConfig(
deck=DeckConfig(min_size=60, energy_deck_enabled=False),
prizes=PrizeConfig(count=6),
)
```
### GameState (`models/game_state.py`)
Complete state of a game in progress. Self-contained and serializable.
```python
from app.core.models import GameState
# Access player zones
player = game.players["player1"]
active = player.get_active_pokemon()
hand_size = len(player.hand)
```
### TurnManager (`turn_manager.py`)
Handles turn phases and transitions.
```python
from app.core import TurnManager
manager = TurnManager()
manager.advance_phase(game) # DRAW -> MAIN -> ATTACK -> END
manager.advance_turn(game) # Switch to next player
```
### RandomProvider (`rng.py`)
Protocol for random operations. Supports seeded RNG for testing.
```python
from app.core import create_rng, SeededRandom
# Production: cryptographically secure
rng = create_rng()
# Testing: deterministic
rng = SeededRandom(seed=42)
```
---
## Enumerations (`enums.py`)
| Enum | Description |
|------|-------------|
| `CardType` | `POKEMON`, `TRAINER`, `ENERGY` |
| `PokemonStage` | `BASIC`, `STAGE_1`, `STAGE_2` |
| `EnergyType` | `FIRE`, `WATER`, `GRASS`, `LIGHTNING`, etc. |
| `TrainerType` | `ITEM`, `SUPPORTER`, `STADIUM`, `TOOL` |
| `StatusCondition` | `POISONED`, `BURNED`, `ASLEEP`, `PARALYZED`, `CONFUSED` |
| `TurnPhase` | `SETUP`, `DRAW`, `MAIN`, `ATTACK`, `END` |
| `GameEndReason` | `PRIZES`, `DECK_OUT`, `NO_POKEMON`, `RESIGNATION`, etc. |
| `ModifierMode` | `ADDITIVE`, `MULTIPLICATIVE` |
---
## Action Types (`models/actions.py`)
| Action | Description |
|--------|-------------|
| `AttackAction` | Use an attack |
| `AttachEnergyAction` | Attach energy to Pokemon |
| `PlayPokemonAction` | Play Basic to bench/active |
| `EvolvePokemonAction` | Evolve a Pokemon |
| `PlayTrainerAction` | Play a Trainer card |
| `UseAbilityAction` | Use a Pokemon's ability |
| `RetreatAction` | Retreat active Pokemon |
| `SelectActiveAction` | Choose new active (after KO) |
| `PassAction` | End turn without attacking |
| `ResignAction` | Forfeit the game |
---
## Visibility System (`visibility.py`)
Filters game state to hide information opponents shouldn't see.
```python
from app.core import get_visible_state, get_spectator_state
# Player sees own hand, opponent sees card count
visible = get_visible_state(game, "player1")
# Spectator sees neither hand
spectator_view = get_spectator_state(game)
```
---
## Effects System (`effects/`)
Handles card abilities and attack effects. See [effects/README.md](./effects/README.md).
```python
from app.core.effects import resolve_effect, EffectContext
result = resolve_effect("deal_damage", ctx)
```
---
## Testing
```bash
cd backend && uv run pytest tests/core/ -v
```
All core module tests are in `tests/core/` with ~800+ tests at 97% coverage.
---
## See Also
- [/docs/ARCHITECTURE.md](/docs/ARCHITECTURE.md) - System architecture
- [/docs/GAME_RULES.md](/docs/GAME_RULES.md) - Game rules
- [/docs/ACTIVE_EFFECTS_DESIGN.md](/docs/ACTIVE_EFFECTS_DESIGN.md) - Effects system design
- [effects/README.md](./effects/README.md) - Effects module
- [models/README.md](./models/README.md) - Models module