# Defining Attacks in pokeemerald This document analyzes how pokeemerald defines battle actions (moves/attacks) and their effects, providing a clear system architecture for implementing similar battle mechanics in Pokemon-style games. ## Architecture Overview pokeemerald uses a **multi-layered, data-driven approach** to define attacks: 1. **Move Constants** - Unique IDs for each move 2. **Move Data Structure** - Statistical properties and effect assignments 3. **Effect Constants** - Categorization of move behaviors 4. **Battle Scripts** - Implementation logic for each effect 5. **Script Commands** - Low-level operations for battle mechanics ## Layer 1: Move Constants (`include/constants/moves.h`) Each move gets a unique constant identifier: ```c #define MOVE_NONE 0 #define MOVE_POUND 1 #define MOVE_KARATE_CHOP 2 #define MOVE_DOUBLE_SLAP 3 // ... continues for all moves ``` **Key Benefits:** - Type-safe move references throughout codebase - Easy to add new moves without conflicts - Clear naming convention ## Layer 2: Move Data Structure (`src/data/battle_moves.h`) Each move is defined using the `BattleMove` struct: ```c [MOVE_POUND] = { .effect = EFFECT_HIT, // What the move does .power = 40, // Base damage .type = TYPE_NORMAL, // Move type (Normal, Fire, etc.) .accuracy = 100, // Hit chance (0-100) .pp = 35, // Power Points (usage count) .secondaryEffectChance = 0, // Chance of secondary effect .target = MOVE_TARGET_SELECTED, // Who can be targeted .priority = 0, // Move speed priority .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_KINGS_ROCK_AFFECTED, }, ``` **Key Features:** - **Separation of Concerns**: Stats vs. behavior logic - **Flag System**: Modular properties (contact, protection, etc.) - **Secondary Effects**: Built-in chance system for additional effects - **Targeting System**: Flexible target selection ## Layer 3: Effect Constants (`include/constants/battle_move_effects.h`) Effects categorize move behaviors into reusable types: ```c #define EFFECT_HIT 0 // Basic damage #define EFFECT_SLEEP 1 // Status effect #define EFFECT_POISON_HIT 2 // Damage + poison #define EFFECT_ABSORB 3 // Drain HP #define EFFECT_BURN_HIT 4 // Damage + burn #define EFFECT_MULTI_HIT 29 // Multiple strikes #define EFFECT_HIGH_CRITICAL 43 // Increased crit chance // ... 200+ different effects ``` **Benefits:** - **Reusability**: Multiple moves can share the same effect - **Extensibility**: New effects can be added without changing existing moves - **Organization**: Related behaviors grouped together ## Layer 4: Battle Scripts (`data/battle_scripts_1.s`) Each effect maps to a battle script that defines the actual implementation: ```assembly gBattleScriptsForMoveEffects:: .4byte BattleScript_EffectHit @ EFFECT_HIT .4byte BattleScript_EffectSleep @ EFFECT_SLEEP .4byte BattleScript_EffectPoisonHit @ EFFECT_POISON_HIT // ... maps all effects to their scripts ``` ### Example Battle Scripts: **Basic Hit:** ```assembly BattleScript_EffectHit:: attackcanceler # Check if attack can proceed accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE attackstring # Display move name ppreduce # Consume PP critcalc # Calculate critical hits damagecalc # Calculate damage typecalc # Apply type effectiveness adjustnormaldamage # Apply damage modifications attackanimation # Play visual effects waitanimation # Wait for animation effectivenesssound # Play sound effects # ... continues with damage application ``` **Poison Hit (Damage + Status):** ```assembly BattleScript_EffectPoisonHit:: setmoveeffect MOVE_EFFECT_POISON # Set secondary effect goto BattleScript_EffectHit # Use standard hit logic ``` **Multi-Hit:** ```assembly BattleScript_EffectMultiHit:: attackcanceler accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE attackstring ppreduce setmultihitcounter 0 # Initialize hit counter initmultihitstring # Setup hit count display BattleScript_MultiHitLoop:: jumpifhasnohp BS_ATTACKER, BattleScript_MultiHitEnd jumpifhasnohp BS_TARGET, BattleScript_MultiHitPrintStrings # ... hit logic with loop control ``` ## Layer 5: Script Commands (`src/battle_script_commands.c`) Low-level commands that scripts use: - **Flow Control**: `jumpif*`, `goto`, `call`, `return` - **Battle Mechanics**: `accuracycheck`, `critcalc`, `damagecalc` - **Status Effects**: `setmoveeffect`, `seteffectprimary` - **Animation**: `attackanimation`, `waitanimation` - **State Management**: `attackcanceler`, `movevaluescleanup` ## Complex Effect Patterns ### 1. **Composite Effects** (Hit + Status) ```c // Move data specifies base effect .effect = EFFECT_BURN_HIT, // Script combines damage with status BattleScript_EffectBurnHit:: setmoveeffect MOVE_EFFECT_BURN # Add burn chance goto BattleScript_EffectHit # Execute standard damage ``` ### 2. **Multi-Stage Effects** (Charging moves) ```c // Sky Attack: charge turn, then hit .effect = EFFECT_SKY_ATTACK, BattleScript_EffectSkyAttack:: jumpifstatus2 BS_ATTACKER, STATUS2_MULTIPLETURNS, BattleScript_TwoTurnMovesSecondTurn jumpifword CMP_COMMON_BITS, gHitMarker, HITMARKER_NO_ATTACKSTRING, BattleScript_TwoTurnMovesSecondTurn # First turn: charge up # Second turn: attack ``` ### 3. **Variable Effects** (Power/behavior changes) ```c // Moves that change behavior based on conditions jumpifnotmove MOVE_SURF, BattleScript_HitFromAtkCanceler jumpifnostatus3 BS_TARGET, STATUS3_UNDERWATER, BattleScript_HitFromAtkCanceler orword gHitMarker, HITMARKER_IGNORE_UNDERWATER setbyte sDMG_MULTIPLIER, 2 # Double damage underwater ``` ## Key Design Principles ### 1. **Separation of Data and Logic** - Move stats (power, accuracy, PP) separate from behavior logic - Enables easy balancing without code changes - Clear data-driven approach ### 2. **Effect Reusability** - Many moves share the same effect type - New moves can reuse existing effects - Reduces code duplication ### 3. **Modular Flag System** ```c .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED ``` - Each flag represents an independent property - Easy to combine properties - Consistent interaction rules ### 4. **Script-Based Flexibility** - Complex logic implemented in battle scripts - Scripts can call other scripts (`goto`, `call`) - Allows for sophisticated move interactions ### 5. **Centralized Effect Handling** - All effect implementations in one location - Easy to debug and maintain - Consistent patterns across similar effects ## Implementation Recommendations For a Pokemon-style battle system: ### 1. **Start with Core Structure** ```c struct Move { u16 effect; // Links to effect implementation u8 power; // Base damage u8 type; // Element type u8 accuracy; // Hit chance u8 pp; // Usage count u8 secondaryChance; // Secondary effect probability u8 target; // Targeting rules s8 priority; // Speed priority u32 flags; // Behavior flags }; ``` ### 2. **Define Effect Categories** - Start with basic effects (HIT, SLEEP, POISON_HIT, ABSORB) - Add complex effects as needed - Group related effects together ### 3. **Implement Script System** - Use command-based scripts for flexibility - Implement basic commands first (damage, accuracy, animation) - Add advanced commands for complex interactions ### 4. **Use Flag-Based Properties** ```c #define FLAG_CONTACT (1 << 0) #define FLAG_PROTECTABLE (1 << 1) #define FLAG_REFLECTABLE (1 << 2) #define FLAG_KINGS_ROCK (1 << 3) ``` ### 5. **Design for Extensibility** - Keep effect constants sequential for easy addition - Use lookup tables for effect-to-script mapping - Design script commands to be composable ## Special Effects Implementation ### Status Effects ```c // In move data: .effect = EFFECT_POISON_HIT, .secondaryEffectChance = 30, // In script: setmoveeffect MOVE_EFFECT_POISON // What status to apply goto BattleScript_EffectHit // How to apply it ``` ### Multi-Hit Moves ```c // Requires special counter management setmultihitcounter 0 // Initialize BattleScript_MultiHitLoop:: // Loop label // Hit logic here decrementmultihit // Reduce counter jumpifnotdone BattleScript_MultiHitLoop // Continue if more hits ``` ### Priority System ```c // In move data: .priority = 1, // +1 priority (Quick Attack) .priority = -6, // -6 priority (Counter) // Processed during move selection phase ``` This architecture allows for clean separation between move definitions, their statistical properties, and their complex behavioral implementations, making it easy to add new moves while maintaining code organization and reusability.