Add CardRarityTier enum for pull rate calculations (common through crown_rare). Add CardSubtype enum for Pokemon classifications (basic, stage1, stage2, ex, etc.). Update CardDefinition model with new fields for subtypes and rarity display. |
||
|---|---|---|
| .. | ||
| effects | ||
| models | ||
| __init__.py | ||
| AGENTS.md | ||
| config.py | ||
| engine.py | ||
| enums.py | ||
| README.md | ||
| rng.py | ||
| rules_validator.py | ||
| turn_manager.py | ||
| visibility.py | ||
| win_conditions.py | ||
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 for details on this design goal.
Import Boundaries
# 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.
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.
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.
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.
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.
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.
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.
from app.core.effects import resolve_effect, EffectContext
result = resolve_effect("deal_damage", ctx)
Testing
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 - System architecture
- /docs/GAME_RULES.md - Game rules
- /docs/ACTIVE_EFFECTS_DESIGN.md - Effects system design
- effects/README.md - Effects module
- models/README.md - Models module