Source: Roblox Creator Hub · CC BY 4.0 · View source · Code samples: MIT Imported 2026-10-03. Formatting adapted for this site.
Create player hazards
Right now, players can fall off any platform with no consequence. This section walks you through creating a large invisible hazard at the same height as the water in your game. When a player falls into the hazard, their health is reduced to zero and they respawn at the start of the game.
Create a basic water hazard
Build with Assistant
In Workspace > World, create a new folder named Hazards.
Inside the Hazards folder, create a block Part named Hazard with Size 825, 1, 576 and CFrame.Position 174, -6.5, 38 so the part covers the water around the island and platforms.
Set Transparency to 1 so the part is invisible and the actual water appears to be the hazard, disable CanCollide so players fall through it into the water, and enable Anchored so physics doesn't move it. Build it Yourself
In the Explorer, hover over the World model, click ⊕, and insert a new Folder. Rename it
Hazards.Inside the
Hazardsfolder, insert a block part and rename itHazard. Use the Move and Scale tools to flatten and stretch the part so it covers the water around the island and platforms. The sample uses Size =825, 1, 576and CFrame.Position =174, -6.5, 38.
With the part still selected, in the Properties window:
- Set Transparency to
1so the part is invisible — the actual water below is what the player sees as the hazard. - Disable CanCollide so players fall through the part and into the water instead of standing on the part.
- Enable Anchored so physics doesn't push the part around.
- Set Transparency to
Detect when players touch the hazard
The hazard doesn't do anything until you write a script that listens Touched and lowers the player's health to zero.
Build with Assistant
In ServerScriptService, create a Script named HazardService with the following code:
```lua
local Players = game:GetService("Players")
local Workspace = game:GetService("Workspace")
local hazardsFolder = Workspace.World.Hazards
local hazards = hazardsFolder:GetChildren()
local function onHazardTouched(otherPart)
local character = otherPart.Parent
local player = Players:GetPlayerFromCharacter(character)
if player then
local humanoid = character:FindFirstChildWhichIsA("Humanoid")
if humanoid then
humanoid.Health = 0
end
end
end
for _, hazard in hazards do
hazard.Touched:Connect(onHazardTouched)
end
``` Build it Yourself
- In the Explorer, hover over ServerScriptService, click ⊕, and insert a new Script. Rename it
HazardService. Put it inServerScriptServiceto keep the code on the server, where players can't read or make changes to it. - Replace the default code with the following code to loop through every part in the
Hazardsfolder and set the player's health to zero when they touch the hazard:
local Players = game:GetService("Players")
local Workspace = game:GetService("Workspace")
local hazardsFolder = Workspace.World.Hazards
local hazards = hazardsFolder:GetChildren()
local function onHazardTouched(otherPart)
local character = otherPart.Parent
local player = Players:GetPlayerFromCharacter(character)
if player then
local humanoid = character:FindFirstChildWhichIsA("Humanoid")
if humanoid then
humanoid.Health = 0
end
end
end
for _, hazard in hazards do
hazard.Touched:Connect(onHazardTouched)
end Code explanation
The HazardService has many similarities to CoinService. However, instead of collecting a coin, the player has their health set to 0 when they touch a hazard.
Feel free to modify, add, or remove hazard objects in your game to create unique obstacles. As long as they are contained in the Hazards folder, the code loop connects the event handler to all of your hazards.
Connect to the player lifecycle
The player lifecycle represents events that occur when players interact in your game, such as joining, leaving, or respawning. You need to connect handlers to these events to execute logic for each major lifecycle event.
Build with Assistant
In ServerScriptService, append the following code to the bottom of the existing CoinService Script (don't replace any of the existing code — add this after it):
```lua
local function onPlayerAdded(player)
-- Reset player coins to 0
updatePlayerCoins(player, function(_)
return 0
end)
player.CharacterAdded:Connect(function(character)
-- WaitForChild would stop the player loop, so below should be done in a separate thread
task.spawn(function()
-- When a player dies
character:WaitForChild("Humanoid").Died:Connect(function()
-- Reset player coins to 0
updatePlayerCoins(player, function(_)
return 0
end)
end)
end)
end)
end
-- Initialize any players added before connecting to PlayerAdded event
for _, player in Players:GetPlayers() do
onPlayerAdded(player)
end
local function onPlayerRemoved(player)
updatePlayerCoins(player, function(_)
return nil
end)
end
Players.PlayerAdded:Connect(onPlayerAdded)
Players.PlayerRemoving:Connect(onPlayerRemoved)
``` Build it Yourself
- In the Explorer, open the
CoinServicescript inside ServerScriptService. - Scroll to the bottom of the file (don't replace the existing coin-collection code) and add the following lifecycle handlers to reset a player's coin count when they join the game and when they die:
local function onPlayerAdded(player)
-- Reset player coins to 0
updatePlayerCoins(player, function(_)
return 0
end)
player.CharacterAdded:Connect(function(character)
-- WaitForChild would stop the player loop, so below should be done in a separate thread
task.spawn(function()
-- When a player dies
character:WaitForChild("Humanoid").Died:Connect(function()
-- Reset player coins to 0
updatePlayerCoins(player, function(_)
return 0
end)
end)
end)
end)
end
-- Initialize any players added before connecting to PlayerAdded event
for _, player in Players:GetPlayers() do
onPlayerAdded(player)
end
local function onPlayerRemoved(player)
updatePlayerCoins(player, function(_)
return nil
end)
end
Players.PlayerAdded:Connect(onPlayerAdded)
Players.PlayerRemoving:Connect(onPlayerRemoved) Code explanation
The code defines functions to reset coin counts during the appropriate lifecycle events:
Players.PlayerAddedfires when a player joins the game, and sets the coin count to0.Player.CharacterAddedfires when a player's character model is added to the world. It occurs afterPlayerAddedand whenever the player respawns.Humanoid.Diedfires when a player dies, and sets the coin count to0.task.spawn()creates a separate thread for handling this, so other aspects of the player life cycle can execute.Player.PlayerRemovedfires when a player leaves the game to clean up player state.- This code contains a potential issue where players could collect coins before the
Players.PlayerAddedevent executes and then have their coin counts reset to zero. To mitigate this issue, consider solutions such as code scheduling or freezing the player's character until initialization finishes. However, these solutions involve more complex scripting concepts that are beyond the scope of this tutorial.
Playtest
Select Test from the dropdown and click Play. Collect a few coins, then jump into the water. You character should die and respawn at the start, with their coin count reset to 0.