mantimon-tcg/backend/app/core/effects
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
..
__init__.py Move enums to app/core/enums.py and set up clean module exports 2026-01-26 14:45:26 -06:00
base.py Add effects system with configurable weakness/resistance 2026-01-25 00:25:38 -06:00
handlers.py Move enums to app/core/enums.py and set up clean module exports 2026-01-26 14:45:26 -06:00
README.md Add Active Effects system design and module README files 2026-01-26 22:39:02 -06:00
registry.py Add exception logging to effect registry (Issue #14) 2026-01-26 13:32:43 -06:00

Effects Module

The effects module provides the card effect system for Mantimon TCG, handling abilities, attack effects, and persistent game modifiers.

Design Document

For the complete system design including the Active Effects registry, see: /docs/ACTIVE_EFFECTS_DESIGN.md


Files

File Description
__init__.py Module exports (EffectContext, EffectResult, resolve_effect, etc.)
base.py Core types: EffectContext, EffectResult, EffectType
registry.py Effect handler registry and @effect_handler decorator
handlers.py Built-in effect handlers for common card effects

Future Additions

File Description
active_effects.py ActiveEffect model and ActiveEffectsManager for persistent effects

Quick Reference

Registering an Effect Handler

from app.core.effects.registry import effect_handler

@effect_handler("my_effect_id")
def handle_my_effect(ctx: EffectContext) -> EffectResult:
    """Handler for my_effect_id.
    
    Called when a card with effect_id="my_effect_id" is used.
    """
    # Extract parameters
    amount = ctx.get_int_param("amount", 0)
    
    # Apply effect to game state
    # ...
    
    return EffectResult.success_result("Effect applied")

Resolving an Effect

from app.core.effects import EffectContext, resolve_effect

ctx = EffectContext(
    game=game_state,
    source_player_id="player1",
    rng=rng,
    source_card_id="pikachu-001",
    target_card_id="bulbasaur-001",
    params={"damage": 30},
)

result = resolve_effect("deal_damage", ctx)
if result.success:
    print(result.message)

Listing Available Effects

from app.core.effects import list_effects

for effect_id in list_effects():
    print(effect_id)

Built-in Effect Handlers

Damage Effects

Effect ID Description Parameters
deal_damage Raw damage (poison, burn, recoil) damage, target
attack_damage Combat damage with W/R damage
coin_flip_damage Damage based on coin flips base_damage, bonus_on_heads
bench_damage Damage to benched Pokemon damage, target_count

Healing & Status

Effect ID Description Parameters
heal Heal damage from Pokemon amount, target
apply_status Apply status condition status
remove_status Remove status condition status

Card Movement

Effect ID Description Parameters
draw_cards Draw from deck count, discard_hand
discard_from_hand Discard cards count
shuffle_deck Shuffle deck -

Energy & Modifiers

Effect ID Description Parameters
discard_energy Discard energy from Pokemon count, energy_type
modify_hp Change HP modifier amount
modify_retreat_cost Change retreat cost amount

EffectContext

The EffectContext provides all information needed by effect handlers:

class EffectContext:
    game: GameState           # Current game state
    source_player_id: str     # Player using the effect
    rng: RandomProvider       # For coin flips, random selection
    source_card_id: str       # Card providing the effect
    target_card_id: str       # Target of the effect (if any)
    params: dict              # Effect-specific parameters
    
    # Helper methods
    def get_int_param(key: str, default: int = 0) -> int
    def get_str_param(key: str, default: str = "") -> str
    def get_param(key: str, default: Any = None) -> Any
    def get_source_pokemon() -> CardInstance | None
    def get_target_pokemon() -> CardInstance | None

EffectResult

Effect handlers return an EffectResult:

class EffectResult:
    success: bool
    message: str
    effect_type: EffectType
    details: dict
    
    @classmethod
    def success_result(cls, message: str, ...) -> EffectResult
    
    @classmethod
    def failure_result(cls, message: str) -> EffectResult

See Also