How to make a horror game in Roblox Studio

Lighting, sound and a monster that hunts players through your map — plus the pacing tricks that make a Roblox horror game scary instead of just dark.

Updated November 1, 202610 min read

Roblox horror runs on atmosphere more than code. One good monster script, careful lighting and sound, and a map with a clear goal (find the keys, escape the house) are enough for a game people record and share.

The core loop

Every horror game comes down to one loop that players repeat. Build this first, in grey blocks:

  1. Explore a dark area
  2. Find an item or solve a small puzzle
  3. Hide or run when the monster comes
  4. Unlock the next area or escape

Systems you need

Lighting

Low Brightness, ClockTime around 0, Atmosphere with density, and a flashlight (a SpotLight in the character's head or a tool).

Sound

Ambient loops, footsteps, and a chase music layer that fades in when the monster sees someone.

Monster AI

Pathfinding toward the nearest player in range, wandering when nobody is close.

Objectives

Keys, generators or notes that open the way forward and give players a reason to move.

Hiding spots

Lockers or beds that the monster ignores — the tension comes from choosing when to leave.

Build order

  1. 1

    Map blockout

    Rooms, corridors and one exit. Make sure there are loops so players can escape a chase.

  2. 2

    Lighting and sound

    Set the mood before writing any code; walk the map in Play with headphones.

  3. 3

    The monster

    A rig in Workspace with the script below. Tune its speed to be just slower than a sprinting player.

  4. 4

    Objectives

    Three to five items to collect with ProximityPrompts, and a door that opens when all are found.

  5. 5

    Pacing

    Quiet stretches, then a scare. Constant chasing stops being scary within minutes.

The key script: Monster that chases the nearest player

Where it goes: Workspace > Monster (Model) > MonsterAI (Script).

  • The monster is a rig (Avatar tab → Rig Builder) with a Humanoid and HumanoidRootPart, placed in Workspace.
  • Anchored walls and floors are what pathfinding walks around — make doorways at least 5 studs wide.
Workspace > Monster (Model) > MonsterAI (Script)
local Players = game:GetService("Players")
local PathfindingService = game:GetService("PathfindingService")

local monster = script.Parent
local humanoid = monster:WaitForChild("Humanoid")
local root = monster:WaitForChild("HumanoidRootPart")
root:SetNetworkOwner(nil)

local SIGHT_RANGE = 80
local path = PathfindingService:CreatePath({ AgentRadius = 2, AgentHeight = 5, AgentCanJump = true })

local function nearestTarget()
	local best, bestDistance = nil, SIGHT_RANGE
	for _, player in Players:GetPlayers() do
		local character = player.Character
		local target = character and character:FindFirstChild("HumanoidRootPart")
		local targetHumanoid = character and character:FindFirstChildOfClass("Humanoid")
		if target and targetHumanoid and targetHumanoid.Health > 0 then
			local distance = (target.Position - root.Position).Magnitude
			if distance < bestDistance then
				best, bestDistance = target, distance
			end
		end
	end
	return best
end

-- Touching the monster is fatal.
root.Touched:Connect(function(hit)
	local victim = hit.Parent:FindFirstChildOfClass("Humanoid")
	if victim and hit.Parent ~= monster then
		victim.Health = 0
	end
end)

while true do
	local target = nearestTarget()
	if target then
		local ok = pcall(function()
			path:ComputeAsync(root.Position, target.Position)
		end)
		if ok and path.Status == Enum.PathStatus.Success then
			-- Walk a few points, then plan again: the player keeps moving.
			local points = path:GetWaypoints()
			for i = 2, math.min(#points, 5) do
				if points[i].Action == Enum.PathWaypointAction.Jump then
					humanoid.Jump = true
				end
				humanoid:MoveTo(points[i].Position)
				humanoid.MoveToFinished:Wait()
			end
		else
			humanoid:MoveTo(target.Position)
		end
	end
	task.wait(0.2)
end

How it works

  • Re-planning every few waypoints keeps the monster on the player's trail without computing a path every frame.
  • To make it fair, check line of sight with workspace:Raycast before it starts a chase, and let hiding spots set an attribute the monster skips.
  • Give the monster a sound (a breathing loop in its HumanoidRootPart) so players hear it before they see it.

How horror games make Robux

  • Cosmetic flashlights and character skins.
  • Extra lives or revives as developer products in longer chapters — keep them optional.
  • New chapters as free updates bring players back; paid access to whole chapters tends to hurt growth.

You receive 70% of what players spend on game passes and developer products; Roblox keeps 30%.

Common mistakes

Too dark to play

Dark is not scary if players can't see where to go. Light the path forward a little and make the unknown darker.

Constant chasing

Fear needs quiet moments. Let the monster wander or leave, then return.

Monster stuck on doors

Narrow doorways and unanchored furniture block pathfinding. Widen doors and test the monster's route in every room.

FAQ

How do I make a monster chase players in Roblox?

Use PathfindingService: compute a path from the monster to the nearest player, walk a few waypoints with Humanoid:MoveTo, then compute again. The script on this page does exactly that.

How do I make my Roblox game dark and scary?

Lower Lighting.Brightness, set ClockTime near midnight, add an Atmosphere with some density, and give players a flashlight. Sound matters as much as light.

Can a Roblox horror game be for all ages?

Only if it fits the maturity rating you select in the content questionnaire. Intense or gory horror will get an older age rating, which limits who can play.

Keep reading