Stage 7: Rolling Rocks + enemy AI
Finish Stage 6. Every fighter has a health bar. Today's enemy will get one automatically — that's the DescendantAdded line you wrote paying off.
a rolling-rocks ramp with cover, the Stage 8 checkpoint, and an enemy that hunts the player
how an enemy detects the nearest player by distance, walks to them with MoveTo, attacks in range, and respawns when defeated
a roaming enemy that chases you, hits you up close, dies to your sword and fireball, and comes back
90-second demo:
- Press Play. An enemy stands near the ramp. Walk toward it — once you're close enough, it turns and chases you.
- Let it reach you: it hits you and your health bar drops. Back off past its detection range and it loses interest.
- Fight back with sword and fireball. When its health hits zero it falls — then a few seconds later a fresh one spawns.
- Explain: "A turret just sat there. This enemy makes decisions: who's nearest, am I close enough to hit, am I still alive. That's the start of AI."
The big idea
The turret in Stage 5 was a statue that fired on a timer. A real enemy moves and decides. Today you build one that runs a tiny decision loop, over and over: find the nearest player in range → walk toward them → if I'm close enough, attack → if I die, come back.
The enemy is a character rig with its own Humanoid, just like your dummy — but unanchored, so it can walk. To make it walk somewhere, you call Humanoid:MoveTo(position); the Humanoid figures out the steps. "Nearest player in range" reuses the exact Magnitude distance idea from the turret. "Close enough to attack" is another distance check. And "come back when defeated" uses the Humanoid's Died event to clone a fresh enemy at the original spot.
Because of the work you did in Stage 6, this enemy gets a health bar the moment it spawns — you don't write a single line of UI today.
- MoveTo
- a Humanoid method that walks the character toward a position; the engine handles the steps
- detection range
- how close a player must be before the enemy notices and reacts
- attack range
- how close the enemy must be to land a hit
- Died
- a Humanoid event that fires once when its Health reaches 0 — the trigger to respawn
- Clone
- makes a fresh copy of an object; we keep a template enemy and clone it to respawn
- task.spawn
- runs a loop alongside the rest of the script so one enemy's loop doesn't block others
Build it
Step 1 — Build the rolling-rocks ramp
A ramp with boulders rolling down it and a block to hide behind. This is the obby hazard; the enemy is the combat layer.

Build this partRockRamp
BlockOpen recipe
RockRamp
Block- Size
- 16 × 1 × 30
- Color
- Dark stone grey
- Material
- Slate
- Anchored
- ✓ Yes
- Place
- Sloping down from the Stage 7 orange pad — rotate it so it tilts
Tilt it about 20° so boulders roll down on their own.
Build this partCoverBlock
BlockOpen recipe
CoverBlock
Block- Size
- 6 × 5 × 1
- Color
- Brown
- Material
- Wood
- Anchored
- ✓ Yes
- Place
- Partway down RockRamp, to one side — somewhere to duck behind
Build this partBoulderSpawner
BlockOpen recipe
BoulderSpawner
Block- Size
- 2 × 1 × 2
- Color
- Bright red
- Material
- Neon
- Anchored
- ✓ Yes
- Place
- At the TOP of RockRamp
Boulders spawn here and roll down. Make it small and out of the way.
Right-click BoulderSpawner → Insert Object → Script. Name it Boulders:
local spawner = script.Parent
local Debris = game:GetService("Debris")
while true do
task.wait(2.5)
local rock = Instance.new("Part")
rock.Shape = Enum.PartType.Ball
rock.Size = Vector3.new(6, 6, 6)
rock.Color = Color3.fromRGB(90, 80, 70)
rock.Material = Enum.Material.Slate
rock.Position = spawner.Position + Vector3.new(0, 3, 0)
rock.Parent = workspace
Debris:AddItem(rock, 8)
end
Press Play. Boulders roll down the ramp; duck behind CoverBlock to dodge them as you climb.