The Enemy Behavior Sandbox
What you'll learn
~60 min- Generate a Phaser 3 combat room with multiple enemy types and configurable AI
- Implement a finite state machine for enemy behavior with six states
- Tune enemy aggression, pursuit, and attack patterns with real-time sliders
- Build three distinct enemy archetypes: melee grunt, ranged soldier, and boss
What you’re building
The combat prototype gave you one enemy that patrols and punches. BloodRayne had dozens of enemy types — soldiers with rifles, supernatural creatures that lunged from shadows, and bosses that demanded pattern recognition and patience. The enemies are what make combat interesting. A perfect combo system is meaningless if the enemies just walk back and forth waiting to die.
In this lesson you are building an enemy behavior sandbox — a Phaser 3 combat room with three enemy types, each running a finite state machine with tunable parameters. A side panel lets you adjust aggression, pursuit distance, attack cooldowns, and more in real time. You will use this sandbox to design enemies that force the player to use every tool from Lesson 10: combos for the grunts, dodges for the ranged shots, and pattern reading for the boss.
A finite state machine (FSM) is one of the most widely used patterns in software: an entity can be in exactly one state at a time, and transitions between states are triggered by conditions. In games, enemy AI uses FSMs. In business software, order processing uses FSMs (pending, approved, shipped, delivered). The same mental model applies — states, transitions, and conditions.
The showcase
Here is what the finished sandbox gives you:
- Combat room with floor, platforms, and three enemy types active simultaneously
- Player character (Rayne) with combat controls from Lesson 10
- Melee Grunt (green) — state machine: idle, patrol, alert, chase, attack, hurt, dead
- Ranged Soldier (purple) — state machine: idle, patrol, alert, retreat, shoot, hurt, dead
- Boss (large red) — state machine: idle, approach, telegraph, heavy attack, summon, enrage, hurt, dead
- Tuning panel with tabs for each enemy type, containing sliders for:
- Detection range (how far they “see” the player)
- Pursuit speed (how fast they chase)
- Attack cooldown (time between attacks)
- Attack damage
- Aggression (0-100%, affects how quickly they transition from passive to aggressive states)
- Telegraph duration (how long the warning animation plays before attacking)
- Health
- State indicator above each enemy showing their current FSM state in small text
- Spawn controls — buttons to add or remove each enemy type from the room
The prompt
Open your terminal, navigate to your project folder, start your AI CLI tool, and paste this prompt:
Build a Phaser 3 enemy behavior sandbox for a BloodRayne-inspired side-scrollingaction game. The sandbox has three configurable enemy types with finite statemachine AI, plus a tuning panel for real-time parameter adjustment.
PROJECT STRUCTURE:enemy-behavior-sandbox/ index.html (Phaser 3 game + HTML tuning panel, all inline)
SPECIFICATIONS:
1. PAGE LAYOUT - Split layout: game canvas on left (680px wide), tuning panel on right (300px) - Tuning panel has three tabs at the top: "Grunt", "Ranged", "Boss" - Each tab shows sliders for that enemy type's parameters - Dark panel background (#1a1a2e), light text, styled range inputs - Spawn buttons at the bottom: "Add Grunt", "Add Ranged", "Add Boss", "Clear All"
2. GAME SCENE (680x450 canvas) - Background: dark dungeon aesthetic (dark gray gradient) - Ground floor full width, two elevated platforms (left-high, right-mid) - Player (Rayne): 32x48 dark red rectangle, same controls as combat prototype: arrow keys to move, Z for 3-hit combo attack, X for dodge roll with i-frames - Player has 150 HP with a health bar at top-left - Enemies spawn from the right side
3. MELEE GRUNT (green rectangle, 28x44) Finite state machine with these states:
IDLE: Stand still for 1-3 seconds. Transition to PATROL after timer. PATROL: Walk back and forth in a 150px range at 60px/s. Transition to ALERT if player is within detectionRange. ALERT: Stop moving, flash yellow exclamation mark above head for 0.5s. Transition to CHASE after alert animation. CHASE: Move toward player at pursuitSpeed. Transition to ATTACK when within 45px. Transition to PATROL if player moves beyond detectionRange * 1.5 (hysteresis to prevent flickering). ATTACK: Stop. Telegraph by flashing yellow for telegraphDuration ms. Then deal attackDamage to player if still in range (45px). Enter cooldown. Transition to CHASE after cooldown expires. HURT: Flash white, knockback 80px away from damage source. 300ms stagger. Transition to CHASE when stagger ends (or DEAD if HP <= 0). DEAD: Play death animation (shrink + fade over 500ms). Remove from scene. If "auto-respawn" is checked in panel, respawn after 4 seconds.
Default tunable values: - detectionRange: 220px - pursuitSpeed: 130px/s - attackCooldown: 1200ms - attackDamage: 12 - telegraphDuration: 350ms - health: 80 - aggression: 50 (affects: at 100%, skip ALERT state and go straight to CHASE; at 0%, stay in PATROL even when player is close for up to 2 extra seconds)
4. RANGED SOLDIER (purple rectangle, 24x40) Finite state machine:
IDLE: Stand still briefly. Transition to PATROL. PATROL: Walk back and forth at 50px/s in a 180px range. Transition to ALERT if player within detectionRange. ALERT: Stop, flash yellow for 0.4s. Transition to RETREAT or SHOOT based on distance. RETREAT: If player is within 120px, move away from player at 100px/s until preferred range (200-280px) is reached. Then transition to SHOOT. SHOOT: Stand still. Telegraph by raising arm (small rectangle extends upward) for telegraphDuration ms. Fire a projectile (small yellow circle, 8px diameter) at projectileSpeed toward player's current position. Projectile deals attackDamage on hit. Enter cooldown, transition to IDLE. If player closes distance below 120px during cooldown, transition to RETREAT. HURT: Same as grunt (flash white, knockback, stagger). DEAD: Same as grunt (shrink, fade, optional respawn).
Projectile: travels in a straight line, destroyed on hit or after 3 seconds. Player can dodge through projectiles with i-frames.
Default tunable values: - detectionRange: 320px - pursuitSpeed: 100px/s (retreat speed) - attackCooldown: 2000ms - attackDamage: 15 - projectileSpeed: 280px/s - telegraphDuration: 400ms - health: 60 - aggression: 40
5. BOSS (large dark red rectangle, 48x64) Finite state machine:
IDLE: Stand center-right of arena. Transition to APPROACH when player enters detectionRange. APPROACH: Walk toward player at pursuitSpeed. Transition to TELEGRAPH when within 80px. TELEGRAPH: Flash bright red and grow slightly (scale 1.1x) for telegraphDuration ms. Shows a red danger zone on the ground indicating attack area. Transition to HEAVY_ATTACK. HEAVY_ATTACK: Slam attack dealing attackDamage in a 100px radius around the boss. Screen shake on impact. Particles scatter. 30 damage default. Transition to SUMMON or APPROACH based on a cooldown cycle. SUMMON: Every third attack cycle, instead of approaching again, pause for 1 second and spawn one melee grunt. Max 2 summoned grunts alive at a time. Transition to APPROACH after summon. ENRAGE: When health drops below 30%, permanently increase pursuitSpeed by 50%, reduce attackCooldown by 30%, and tint the boss sprite bright red. Flash "ENRAGED" text. This transition happens once. HURT: Flash white, minimal knockback (boss is heavy -- only 30px). 500ms stagger. Transition to APPROACH (or ENRAGE if health threshold crossed). DEAD: Dramatic death -- screen freeze 200ms, large particle explosion, "BOSS DEFEATED" text center screen. Does not respawn.
Default tunable values: - detectionRange: 350px - pursuitSpeed: 80px/s - attackCooldown: 2500ms - attackDamage: 30 - telegraphDuration: 700ms - health: 300 - aggression: 60 - enrageThreshold: 30 (percent HP)
6. TUNING PANEL Each enemy tab has sliders that update in real time: - Detection Range: range varies per type, step 10 - Pursuit Speed: range 30-300, step 10 - Attack Cooldown: range 500-4000, step 100 - Attack Damage: range 5-50, step 5 - Telegraph Duration: range 100-1500, step 50 - Health: range 20-500, step 10 - Aggression: range 0-100, step 5 - (Ranged only) Projectile Speed: range 100-500, step 20 - (Boss only) Enrage Threshold: range 10-80, step 5
Changes apply to newly spawned enemies AND update existing enemies of that type in real time.
Preset buttons per type: - "Cannon Fodder" -- low HP, low damage, low aggression (easy grunt) - "Dangerous" -- high pursuit speed, high aggression, short telegraphs - "BloodRayne Classic" -- balanced for action game feel - "Reset" -- back to defaults
7. STATE DEBUG DISPLAY - Above each enemy, show current state in small white text: "IDLE", "PATROL", "ALERT", "CHASE", "ATTACK", "SHOOT", "RETREAT", etc. - This text updates in real time as states transition - Toggle on/off with a checkbox in the panel labeled "Show AI States"
8. VISUAL FEEDBACK - Telegraph animations are critical -- the player MUST be able to see the attack coming and react. Make telegraphs obvious: color flash + ground indicator for boss slam, arm raise for ranged shot. - Projectiles leave a faint trail (3 semi-transparent copies behind) - Hit particles on all damage events (same as combat prototype) - Screen shake on boss heavy attack - Kill counter in top-right: "Grunts: 3 | Soldiers: 1 | Boss: 0"
TECHNICAL: Phaser 3 from CDN, Arcade physics, colored rectangles only, runsby opening index.html. The tuning panel communicates with the game througha shared window.enemyConfig object with grunt, ranged, and boss sub-objects.That prompt is long because enemy AI has more moving parts than player movement. Each state machine has six to eight states, each with transition conditions and tunable values. The specificity ensures you get enemies that actually behave differently — a grunt that charges, a soldier that kites, and a boss that demands respect. Vague enemy prompts produce enemies that all walk toward you and punch.
What you get
After the AI finishes:
enemy-behavior-sandbox/ index.htmlPlay it
cd enemy-behavior-sandboxopen index.htmlClick “Add Grunt” a couple of times. Watch them patrol. Walk into their detection range and watch the exclamation mark flash before they chase. Attack them and watch the HURT state stagger. Now add a Ranged Soldier — notice how it backs away when you get close. Add the Boss. Respect the telegraph.
If something is off
| Problem | Follow-up prompt |
|---|---|
| Enemies all do the same thing | The enemy types are not differentiated. Each type needs its own state machine class or configuration. The grunt should chase and melee, the ranged soldier should retreat and shoot projectiles, and the boss should telegraph heavy slams and summon grunts. Make sure each enemy type reads from its own config sub-object (window.enemyConfig.grunt, .ranged, .boss). |
| State transitions are instant — no telegraph visible | The telegraph state is too fast or being skipped. Make sure the TELEGRAPH state sets a timer (this.scene.time.delayedCall(telegraphDuration, ...)) and the enemy does NOT deal damage until that timer completes. During the telegraph, the enemy should flash yellow (grunt/ranged) or red (boss) using a tint tween. |
| Ranged soldier doesn’t retreat | The ranged soldier never enters RETREAT state. Add a distance check in update: if player is within 120px AND the soldier is in IDLE/SHOOT/ALERT state, transition to RETREAT. In RETREAT, set velocity away from the player until distance exceeds 200px, then transition to SHOOT. |
| Boss enrage never triggers | The ENRAGE state is not being checked. In the HURT state handler, after reducing HP, check if health <= maxHealth * (enrageThreshold / 100) AND a boolean hasEnraged is false. If so, set hasEnraged to true, increase pursuitSpeed by 50%, reduce attackCooldown by 30%, apply red tint, and show "ENRAGED" text. |
Deep dive
Why telegraphs are non-negotiable
A telegraph is the visual warning before an enemy attacks. The grunt flashes yellow. The boss flashes red and shows a ground indicator. Without telegraphs, attacks feel unfair — the player cannot react to something they cannot see coming. With telegraphs, attacks become a conversation: the enemy says “I’m about to hit you” and the player says “I dodge” or “I counter-attack.” Every great action game uses telegraphs. Dark Souls bosses wind up for a full second. Hades enemies flash before lunging. BloodRayne enemies had distinct pre-attack animations. Your telegraph duration slider lets you find the right balance between “readable” and “challenging.”
The aggression slider changes the game
Aggression is a meta-parameter that affects how quickly enemies escalate from passive to hostile. At 0% aggression, grunts linger in PATROL even when they see you — they give you time. At 100%, they skip the ALERT state entirely and sprint at you the moment you enter detection range. This single slider transforms the same enemy from a training dummy into a threat. In the final game, you might set early-level grunts to 30% aggression and late-level grunts to 80% — same code, different feel.
The boss is a pattern test
The boss exists to test whether the player has learned the systems. The heavy slam is dodgeable if you read the telegraph. The summoned grunts force you to manage adds while watching the boss. The enrage phase punishes slow play. This is classic action game boss design: each mechanic is tested individually in the encounter. Your tuning panel lets you dial in exactly how forgiving or demanding each phase is.
🔍Why three enemy types is enough for a prototype
Three archetypes — melee, ranged, boss — cover the fundamental design space. Every other enemy in BloodRayne (or any action game) is a variant of these three. A fast melee enemy is a grunt with higher pursuit speed and lower health. A shotgun enemy is a ranged soldier with a spread pattern. A mini-boss is a boss with fewer phases. Once you have the tuning infrastructure for these three, creating new variants is just adjusting slider values and maybe adding one new state. Start with three, prove the design, then expand.
Customize it
Add a shield grunt variant
Add a "shield" checkbox to the Grunt tab. When enabled, the grunt holds ashield (small gray rectangle in front). Frontal attacks deal 0 damage andproduce a "clang" particle effect (gray sparks). The player must dodge behindthe grunt to deal damage. The grunt turns to face the player every 0.8 seconds(not instantly -- the turn delay is the exploit window). Add a Shield TurnSpeed slider (0.3-2.0 seconds, default 0.8).Add enemy group coordination
When 2+ grunts are alive, they should coordinate attacks. Only one gruntattacks at a time -- the others circle at detection range edge, waitingtheir turn. After one grunt's attack cooldown expires, the next gruntin the queue attacks. This prevents "enemy pile" where all grunts overlapon the player simultaneously. Add a "Coordinated" checkbox to the Grunt tab.Add a boss phase 2 attack
Give the boss a second attack pattern: a charge. After every other heavyslam, instead of approaching slowly, the boss dashes toward the player at300px/s across the full arena width. The charge is telegraphed with a 1-secondwind-up where the boss crouches (scale to 0.8x height, 1.2x width) andthe ground shakes. The charge deals 25 damage and continues past the playerto the far wall. The boss is vulnerable for 1.5 seconds after hitting thewall (stagger state). Add a Charge Damage slider and Charge Stagger Durationslider to the Boss tab.Try it yourself
- Paste the prompt and open the sandbox in your browser.
- Add one of each enemy type. Turn on “Show AI States” and watch the state labels change in real time as you interact with each enemy.
- Set grunt aggression to 100%. Notice the difference. Set it to 0%. Notice the difference. Find the value where the grunt feels dangerous but fair.
- Fight the ranged soldier without dodging. Now fight it using only dodge rolls to close distance. The ranged soldier should force you to use dodge — if you can just walk up and combo it, increase its retreat speed or reduce its attack cooldown.
- Fight the boss. Die on purpose. Pay attention to the telegraph timing — if you cannot reliably dodge the heavy slam, the telegraph duration is too short. If you can stand in front of the boss and ignore the telegraph, it is too long.
- Add 3 grunts and 2 ranged soldiers at once. This is a “crowd” test. If you feel overwhelmed in under 5 seconds, reduce aggression. If you feel unchallenged, add more enemies or increase their stats.
Write down the values that felt best. You will need them when the AI stitches everything together in the demo assembly.
Not big brains — but enough to force the player to think. The grunt pressures, the ranged soldier controls space, and the boss demands respect. These three archetypes, with the tuning infrastructure you just built, can produce dozens of enemy variants. BloodRayne’s enemy roster is closer than it looks. Next up: making every hit, slash, and explosion feel like it matters.