Tutorial · Gameplay

How to make a kill brick (lava) in Roblox Studio

A kill brick is a part that resets any player who touches it: the lava in an obby, the spikes in a trap, the void under a parkour course. The whole trick is three lines: listen for Touched, find the Humanoid, set its Health to 0. This guide starts there, then moves to one script that runs every kill brick in your game, damage bricks that hurt a little at a time, and lava that rises.

Updated 23 October 20267 min readBeginnerLuau

In short

Put a Script inside the part. Connect to part.Touched, look for a Humanoid in the parent of the part that touched it, and set humanoid.Health = 0. For a game with many lava parts, tag them KillBrick and use one Script in ServerScriptService that sets up every tagged part.

  • Setting Health to 0 kills even through a ForceField. Humanoid:TakeDamage does nothing while a ForceField is on, which is why spawn protection blocks damage bricks.
  • Use a Script (server), not a LocalScript, so the death counts for everyone.
  • A part that moves into a standing player may not fire Touched, so rising lava checks positions instead (Step 3).

Get the script

Kill brick and damage brick script

One Script in ServerScriptService: parts tagged KillBrick kill on touch, parts tagged DamageBrick hurt players a little at a time.

Script in ServerScriptService named KillBricks
-- Script in ServerScriptService named KillBricks.
-- Tag parts "KillBrick" to kill on touch, or "DamageBrick" to hurt a little at a time.
local CollectionService = game:GetService("CollectionService")
local Players = game:GetService("Players")

local DAMAGE_PER_HIT = 20 -- health a DamageBrick takes each time
local DAMAGE_COOLDOWN = 0.5 -- seconds between hits from damage bricks for one player

local lastHit: { [Player]: number } = {}

local function getHumanoid(hit: BasePart): Humanoid?
	local character = hit.Parent
	-- Only player characters, not NPCs or loose parts
	if not (character and character:IsA("Model") and Players:GetPlayerFromCharacter(character)) then
		return nil
	end
	local humanoid = character:FindFirstChildOfClass("Humanoid")
	if humanoid and humanoid.Health > 0 then
		return humanoid
	end
	return nil
end

local function setUpKillBrick(part: Instance)
	if not part:IsA("BasePart") then
		return
	end
	part.Touched:Connect(function(hit: BasePart)
		local humanoid = getHumanoid(hit)
		if humanoid then
			-- Setting Health to 0 ignores a ForceField, so spawn protection does not save anyone
			humanoid.Health = 0
		end
	end)
end

local function setUpDamageBrick(part: Instance)
	if not part:IsA("BasePart") then
		return
	end
	part.Touched:Connect(function(hit: BasePart)
		local humanoid = getHumanoid(hit)
		local character = humanoid and humanoid.Parent
		local player = if character and character:IsA("Model") then Players:GetPlayerFromCharacter(character) else nil
		if not (humanoid and player) then
			return
		end
		local now = os.clock()
		if now - (lastHit[player] or 0) < DAMAGE_COOLDOWN then
			return
		end
		lastHit[player] = now
		-- TakeDamage does nothing while the character has a ForceField
		humanoid:TakeDamage(DAMAGE_PER_HIT)
	end)
end

for _, part in CollectionService:GetTagged("KillBrick") do
	setUpKillBrick(part)
end
CollectionService:GetInstanceAddedSignal("KillBrick"):Connect(setUpKillBrick)

for _, part in CollectionService:GetTagged("DamageBrick") do
	setUpDamageBrick(part)
end
CollectionService:GetInstanceAddedSignal("DamageBrick"):Connect(setUpDamageBrick)

Players.PlayerRemoving:Connect(function(player: Player)
	lastHit[player] = nil
end)

RoCode builds it in the place you have open in Roblox Studio, on Windows or macOS with a desktop browser; on a phone the button sends the prompt and the link to your computer. Free to start, with free credits every day. More Roblox Studio scripts

Where to put it

Explorer: one Script, then tag your parts
ServerScriptService
  KillBricks Script new
Workspace
  Lava Part (tag: KillBrick)
  Spikes Part (tag: DamageBrick)

Settings you can change

DAMAGE_PER_HITIn the script
Health a DamageBrick takes each time it hurts a player. Players have 100 health by default. Default: 20.
DAMAGE_COOLDOWNIn the script
Seconds between hits from damage bricks for one player, so standing on spikes does not kill in one frame. Default: 0.5.

Add tags in the Properties window: select the part, scroll to Tags, click + and type KillBrick or DamageBrick.

Type-checked with luau-lsp strict against Roblox's API definitions on 23 October 2026. Not playtested in Studio yet: press Play and watch the Output window before you publish.

Prompt for RoCode

Add kill bricks to my game: one Script in ServerScriptService that makes every part tagged KillBrick kill a player on touch and every part tagged DamageBrick deal 20 damage with a half-second cooldown per player, only for player characters.

On this page
  1. Get the script
  2. How it works
  3. 1. One part
  4. 2. Tags
  5. 3. Rising lava
  6. 4. Test
  7. Common errors
  8. With RoCode
  9. Questions
  10. Sources

How a kill brick works

Every part fires a Touched event when another part touches it, and passes that other part to your function. When a player walks onto lava, the part that touches it is a foot or a leg, and its parent is the character Model. The character has a Humanoid, which holds the player's health. Set that health to 0 and Roblox breaks the character apart and respawns the player.

Two ways to hurt a player
CodeWhat it doesWith a ForceField
humanoid.Health = 0Kills at once.Still kills.
humanoid:TakeDamage(20)Takes 20 health away.Does nothing.

Step 1: The simplest kill brick

  1. Insert a Part in the Workspace. Make it red or orange, set Material to Neon for a lava look, and tick Anchored so it does not fall.
  2. Hover over the part in the Explorer, click + and insert a Script. Name it KillScript.
  3. Replace its contents with the code below and press Play. Walk onto the part.
Script in the part named KillScript
-- Script inside the part you want to kill players, named KillScript.
local part = script.Parent :: BasePart

part.Touched:Connect(function(hit: BasePart)
	local character = hit.Parent
	local humanoid = character and character:FindFirstChildOfClass("Humanoid")
	if humanoid then
		humanoid.Health = 0
	end
end)

hit.Parent is the Model the touching part belongs to. FindFirstChildOfClass("Humanoid") returns nil for anything that is not a character, such as a loose brick rolling past, so nothing happens then. This version also kills NPCs, which may be what you want for a trap.

It works, but 30 lava parts would mean 30 copies of the script, and a fix has to be made 30 times. Step 2 replaces them with one script.

Step 2: One script for every kill brick

Tags are labels you put on parts. CollectionService:GetTagged("KillBrick") returns every part with that tag, so one script can set them all up, including parts added later while the game runs.

  1. Delete the KillScript from Step 1 if you made it.
  2. Select each lava part, find Tags at the bottom of the Properties window, click + and type KillBrick. Tag spikes or other things that should only hurt with DamageBrick.
  3. Hover over ServerScriptService, click +, insert a Script named KillBricks and paste the code below.
Script in ServerScriptService named KillBricks
-- Script in ServerScriptService named KillBricks.
-- Tag parts "KillBrick" to kill on touch, or "DamageBrick" to hurt a little at a time.
local CollectionService = game:GetService("CollectionService")
local Players = game:GetService("Players")

local DAMAGE_PER_HIT = 20 -- health a DamageBrick takes each time
local DAMAGE_COOLDOWN = 0.5 -- seconds between hits from damage bricks for one player

local lastHit: { [Player]: number } = {}

local function getHumanoid(hit: BasePart): Humanoid?
	local character = hit.Parent
	-- Only player characters, not NPCs or loose parts
	if not (character and character:IsA("Model") and Players:GetPlayerFromCharacter(character)) then
		return nil
	end
	local humanoid = character:FindFirstChildOfClass("Humanoid")
	if humanoid and humanoid.Health > 0 then
		return humanoid
	end
	return nil
end

local function setUpKillBrick(part: Instance)
	if not part:IsA("BasePart") then
		return
	end
	part.Touched:Connect(function(hit: BasePart)
		local humanoid = getHumanoid(hit)
		if humanoid then
			-- Setting Health to 0 ignores a ForceField, so spawn protection does not save anyone
			humanoid.Health = 0
		end
	end)
end

local function setUpDamageBrick(part: Instance)
	if not part:IsA("BasePart") then
		return
	end
	part.Touched:Connect(function(hit: BasePart)
		local humanoid = getHumanoid(hit)
		local character = humanoid and humanoid.Parent
		local player = if character and character:IsA("Model") then Players:GetPlayerFromCharacter(character) else nil
		if not (humanoid and player) then
			return
		end
		local now = os.clock()
		if now - (lastHit[player] or 0) < DAMAGE_COOLDOWN then
			return
		end
		lastHit[player] = now
		-- TakeDamage does nothing while the character has a ForceField
		humanoid:TakeDamage(DAMAGE_PER_HIT)
	end)
end

for _, part in CollectionService:GetTagged("KillBrick") do
	setUpKillBrick(part)
end
CollectionService:GetInstanceAddedSignal("KillBrick"):Connect(setUpKillBrick)

for _, part in CollectionService:GetTagged("DamageBrick") do
	setUpDamageBrick(part)
end
CollectionService:GetInstanceAddedSignal("DamageBrick"):Connect(setUpDamageBrick)

Players.PlayerRemoving:Connect(function(player: Player)
	lastHit[player] = nil
end)

The script only reacts to player characters: Players:GetPlayerFromCharacter returns nil for an NPC, so a zombie can walk across your lava. Remove that check if traps should kill NPCs too. Damage bricks keep a time per player in lastHit, so a player standing on spikes loses 20 health every half second instead of dying in a single frame, which is what happens without a cooldown because Touched fires many times while a foot rests on a part.

Many obbies stack a kill brick under every jump. If your course has checkpoints, the player then respawns at the last one: the obby checkpoint guide builds that, and it works with these tags as they are.

Step 3: Lava that rises

A rising lava floor turns any map into a race to the top. The lava is an anchored part moved by TweenService. A part moved this way can pass into a player who is standing still without firing Touched, so this script does not rely on it: every frame it checks whether each character's root part is inside the lava.

  1. Make a large flat Neon part at the bottom of your map and name it Lava. It does not need the KillBrick tag.
  2. Insert a Script inside it named RisingLava with the code below.
Script in the Lava part named RisingLava
-- Script inside a lava part, named RisingLava.
-- The lava climbs, waits, sinks and repeats. Anyone below its top surface dies.
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local TweenService = game:GetService("TweenService")

local RISE_STUDS = 40 -- how far the lava climbs
local RISE_SECONDS = 60 -- how long the climb takes
local PAUSE_SECONDS = 5 -- wait at the top and the bottom

local lava = script.Parent :: BasePart
lava.Anchored = true
local bottom = lava.CFrame
local top = bottom + Vector3.new(0, RISE_STUDS, 0)

-- A moving anchored part does not always fire Touched on a player who stands still,
-- so check every frame whether each character's root is inside the lava
RunService.Heartbeat:Connect(function()
	local half = lava.Size / 2
	for _, player in Players:GetPlayers() do
		local character = player.Character
		local humanoid = character and character:FindFirstChildOfClass("Humanoid")
		local root = humanoid and humanoid.RootPart
		if humanoid and root and humanoid.Health > 0 then
			-- The root's position in the lava's own space: inside when every axis is within half its size
			local offset = lava.CFrame:PointToObjectSpace(root.Position)
			if math.abs(offset.X) <= half.X and math.abs(offset.Z) <= half.Z and offset.Y <= half.Y then
				humanoid.Health = 0
			end
		end
	end
end)

local riseInfo = TweenInfo.new(RISE_SECONDS, Enum.EasingStyle.Linear)
local fallInfo = TweenInfo.new(RISE_SECONDS / 4, Enum.EasingStyle.Sine)

while true do
	local rise = TweenService:Create(lava, riseInfo, { CFrame = top })
	rise:Play()
	rise.Completed:Wait()
	task.wait(PAUSE_SECONDS)
	local fall = TweenService:Create(lava, fallInfo, { CFrame = bottom })
	fall:Play()
	fall.Completed:Wait()
	task.wait(PAUSE_SECONDS)
end

PointToObjectSpace turns the root part's position into the lava's own coordinates, where the lava runs from minus half its size to plus half its size on each axis. Anything below the top surface and inside the edges is in the lava. Change RISE_STUDS and RISE_SECONDS to set how high and how fast it climbs.

Step 4: Test it

  1. Open the Output window (Window menu, then Output) and press Play.
  2. Walk onto a KillBrick part: your character breaks apart and respawns after a few seconds.
  3. Stand on a DamageBrick: the health bar in the top-right drops by 20 every half second.
  4. If a damage brick does nothing right after you spawn, that is the SpawnLocation's ForceField. Wait 10 seconds or set its Duration to 0.
  5. For rising lava, lower RISE_SECONDS to 10 while testing so you do not wait a minute.

Common errors and fixes

If the lava does nothing, check the Output window first: a red line names the script and the line.

Touching the part does nothing

Check that it is a Script, not a LocalScript, and for Step 2 that the tag is spelled exactly KillBrick (capital K and B). Also check the part's CanTouch property is ticked.

The damage brick does not hurt right after spawning

The SpawnLocation gave you a ForceField, and TakeDamage does nothing through one. Set the SpawnLocation's Duration to 0, or use a KillBrick, which sets Health to 0 and ignores the ForceField.

Players die the moment they spawn

A kill brick is touching or overlapping the SpawnLocation, or the lava rose above it. Move the spawn up or the lava down.

The kill brick kills NPCs too

Step 1's script kills any Humanoid. Step 2's checks GetPlayerFromCharacter first, so it only kills players.

Build it with RoCode

If you would rather not set this up by hand, RoCode can build it in the place you have open. RoCode is an independent AI agent for Roblox Studio, not made by Roblox: you describe the change in a web chat, and its Studio plugin creates the parts and scripts in your Explorer, so there is no code to paste.

You type

Turn every red neon part in my obby into a kill brick, add spikes that do 20 damage, and make lava under the tower that rises 40 studs over a minute.

RoCode does
  • Can read your place first to find the parts you mean, then tags them and writes one script for all of them
  • Writes the scripts with Create Script and is told to compile-check each one with Check Script
  • Sets an undo point before and after each batch of changes, so Ctrl+Z steps back one batch at a time

After a build, RoCode can run its test robot: it plays your game in Studio, walking and touching parts, and reports PASS or FAIL. It checks only what it chose to test, so play the course yourself too. A whole obby is a few prompts: how building one system per prompt works. How RoCode connects to Studio.

Questions

How do I make a kill brick in Roblox?

Put a Script inside a part with part.Touched:Connect(function(hit) ... end), find the Humanoid in hit.Parent and set its Health to 0. Step 1 has the full script.

How do I make lava kill you in Roblox?

Lava is a kill brick with a Neon orange material. For many lava parts, tag them KillBrick and use the one script in Step 2.

Why does my kill brick not work with a ForceField?

If it uses TakeDamage, a ForceField blocks it. Setting Health = 0 kills through a ForceField.

How do I make a part that only hurts a little?

Use Humanoid:TakeDamage with a cooldown per player, as the DamageBrick part of Step 2 does.

Sources and further reading

How the code was checked: every script on this page passes Luau's strict type checker against Roblox's API definitions (luau-lsp, 23 October 2026). A type check catches misspelt APIs and wrong types, not game logic, so playtest in Studio before you publish.

Try RoCode on your own place.

Free every day, no card required. Install the plugin, describe the feature, and review what lands in Studio.