Both deal_damage and attack_damage now check if the target is knocked out
after applying damage. If KO'd, EffectResult includes:
- details['knockout'] = True
- details['knockout_pokemon_id'] = target's instance_id
- Message includes 'knocked out!' notification
Knockout check correctly respects HP modifiers via effective_hp().
Added 9 tests covering knockout detection, HP modifier behavior,
weakness-triggered knockouts, and resistance preventing knockouts.
Major refactor to properly track attached cards and evolution history:
Model Changes (app/core/models/card.py):
- Change attached_energy from list[str] to list[CardInstance]
- Change attached_tools from list[str] to list[CardInstance]
- Add cards_underneath field for evolution stack tracking
- Update attach_energy/detach_energy to work with CardInstance
- Add attach_tool/detach_tool methods
- Add get_all_attached_cards helper
Engine Changes (app/core/engine.py):
- _execute_attach_energy: Pass full CardInstance to attach_energy
- _execute_evolve: Build evolution stack, transfer attachments, clear status
- _execute_retreat: Detached energy goes to discard pile
- Fix: Evolution now clears status conditions (Pokemon TCG standard)
Game State (app/core/models/game_state.py):
- find_card_instance now searches attached_energy, attached_tools, cards_underneath
Turn Manager (app/core/turn_manager.py):
- process_knockout: Discard all attached energy, tools, and evolution stack
Effects (app/core/effects/handlers.py):
- discard_energy: Find owner's discard pile and move detached energy there
- NEW devolve effect: Remove evolution stages with configurable destination
- Fix: Use EffectType.SPECIAL instead of non-existent EffectType.ZONE
Rules Validator (app/core/rules_validator.py):
- Update energy type checking to iterate CardInstance objects
Tests:
- Update existing tests for new CardInstance-based energy attachment
- NEW test_evolution_stack.py with 28 comprehensive tests covering:
- Evolution stack building (Basic -> Stage 1 -> Stage 2)
- Energy/tool transfer and damage carryover on evolution
- Devolve effect (single/multi stage, hand/discard destination, KO check)
- Knockout processing with all attachments going to discard
- find_card_instance for attached cards and evolution stack
All 765 tests pass.
- 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.