Create Dual-Mode Enemy
Creates a new GameMaker enemy that can switch between melee and ranged attacks based on distance, formation role, cooldowns, and line of sight. Use when the user asks to create an enemy with both melee and ranged capabilities, context-based attack switching, or tactical combat behavior.
$ 설치
git clone https://github.com/majiayu000/claude-skill-registry /tmp/claude-skill-registry && cp -r /tmp/claude-skill-registry/skills/development/create-dual-mode-enemy ~/.claude/skills/claude-skill-registry// tip: Run this command in your terminal to install the skill
name: Create Dual-Mode Enemy description: Creates a new GameMaker enemy that can switch between melee and ranged attacks based on distance, formation role, cooldowns, and line of sight. Use when the user asks to create an enemy with both melee and ranged capabilities, context-based attack switching, or tactical combat behavior.
Create Dual-Mode Enemy Skill
This skill creates GameMaker enemies that intelligently switch between melee and ranged attacks based on tactical context.
Core Requirements
1. Object Setup
- Create object inheriting from
obj_enemy_parent - Call
event_inherited()in Create event before setting properties
2. Enable Dual-Mode System
// In enemy Create event (after event_inherited())
enable_dual_mode = true;
3. Configure Attack Preference
preferred_attack_mode = "ranged"; // Options: "none", "melee", or "ranged"
Attack Preferences:
"melee": Prefers close combat, uses ranged as backup"ranged": Maintains distance, retreats when player gets close"none": No preference, purely distance-based decisions
4. Set Both Attack Stat Sets
Melee Stats:
attack_damage = 5; // Base melee damage
attack_speed = 1.0; // Animation speed multiplier
attack_range = 32; // Pixels for melee range
damage_type = DamageType.physical;
Ranged Stats:
ranged_damage = 3; // Base ranged damage (often lower than melee)
ranged_attack_speed = 0.8; // Animation speed multiplier
ranged_attack_range = 150; // Pixels for ranged range
ranged_damage_type = DamageType.physical;
5. Configure Tactical Behavior
Range Thresholds:
melee_range_threshold = attack_range * 0.5; // Distance below which melee is preferred
ideal_range = attack_range * 0.75; // Preferred standoff distance for ranged
Retreat Behavior (for ranged-preferred enemies):
retreat_when_close = true; // Retreat if player breaches ideal_range
6. Sprite Requirements
47-Frame Layout (dual-mode enemies need ranged animations):
- Frames 0-10: Idle (down, left, right, up)
- Frames 11-22: Walking (down, left, right, up)
- Frames 23-31: Melee attacking (down, left, right, up)
- Frames 35-46: Ranged attacking (down, left, right, up) ← Required for dual-mode
- Frames 32-34: Death animation
Note: Melee-only enemies use 35-frame layout (no ranged frames).
7. Sound Configuration
Set separate sounds for melee vs ranged attacks:
custom_attack_sfx = "snd_sword_hit"; // Melee attack sound
custom_ranged_sfx = "snd_arrow_fire"; // Ranged attack sound
Variant Support: Use numbered variants (e.g., snd_sword_hit_1, snd_sword_hit_2) for automatic randomization.
8. Apply Traits via Tags
array_push(tags, "fireborne"); // Example: fire immunity, fire damage
apply_tag_traits(); // Call after adding all tags
Common Tags: fireborne, arboreal, aquatic, glacial, swampridden, sandcrawler
See /docs/TRAIT_SYSTEM.md for tag definitions and trait bundles.
Attack Mode Decision Logic
The enemy uses this priority order to decide melee vs ranged:
-
Formation Role Override (if in enemy party)
- "rear" or "support" → Force ranged
- "front" or "vanguard" → Force melee
-
Distance Thresholds
dist < melee_range_threshold→ Prefer meleedist > ideal_range→ Prefer ranged
-
Cooldown Availability
- If chosen mode is on cooldown, try other mode
-
Line of Sight (for ranged)
- No LOS → Fall back to melee
Complete Example: Orc Raider
// obj_orc_raider Create event
event_inherited();
// Dual-mode configuration
enable_dual_mode = true;
preferred_attack_mode = "melee";
melee_range_threshold = 48;
ideal_range = 60;
retreat_when_close = false; // Aggressive positioning
// Base stats
hp_total = 20;
move_speed = 1.0;
detection_range = 200;
// Melee stats (primary)
attack_damage = 5;
attack_speed = 1.0;
attack_range = 32;
damage_type = DamageType.physical;
// Ranged stats (backup)
ranged_damage = 3;
ranged_attack_speed = 0.8;
ranged_attack_range = 150;
ranged_damage_type = DamageType.physical;
// Sounds
custom_attack_sfx = "snd_sword_hit";
custom_ranged_sfx = "snd_arrow_fire";
// Traits
array_push(tags, "fireborne");
apply_tag_traits();
// Flanking behavior
flank_chance = 0.3;
flank_trigger_distance = 120;
// Sprite (must have 47-frame layout with ranged animations)
sprite_index = spr_orc_raider;
Key Files Reference
/docs/ENEMY_AI_ARCHITECTURE.md- Complete dual-mode documentation/objects/obj_enemy_parent/Create_0.gml- Parent initialization/scripts/scr_enemy_state_targeting/scr_enemy_state_targeting.gml- Attack mode logic/scripts/scr_enemy_state_ranged_attacking/scr_enemy_state_ranged_attacking.gml- Ranged state/docs/TRAIT_SYSTEM.md- Trait and tag system
Important Notes
- Dual-mode enemies have independent cooldowns for melee (Alarm[0]) and ranged (Alarm[1])
- Ranged attacks allow movement while shooting (unlike melee which commits to position)
- Retreat behavior only triggers for
preferred_attack_mode = "ranged"enemies - Formation role (from enemy party system) overrides distance-based decisions
- Always test line of sight blocking with walls/obstacles in your test rooms
Testing Checklist
After creating a dual-mode enemy:
- Test melee attack at close range
- Test ranged attack at medium range
- Verify switching between modes based on distance
- Test retreat behavior (if ranged-preferred)
- Verify both cooldowns work independently
- Test line of sight blocking (ranged should fail, fallback to melee)
- Verify sprite has all 47 frames with ranged animations
- Test sounds play correctly for both attack types
- Verify traits apply correctly from tags
Repository
