Table of Contents
Why Every Game Needs a Health System
A health system is one of the most common player systems in Roblox games. It controls how much damage a player can take, when they die, and how they recover. In Roblox, characters already come with a built-in health system, so you do not have to build everything from scratch. Instead, you learn how to use and customize what is already there so it fits your game design.
A good health system supports the experience you want. A difficult obby might remove all health in one touch, while a combat game might allow players to take many hits, regenerate, or use shields. In this chapter you focus on how to work with the default Roblox Humanoid health, how to change it, and how to react to health changes using scripts.
The Humanoid and Health Properties
Player characters in Roblox use a Humanoid object. The Humanoid is responsible for many character-related features, and one of the most important ones is health. Each character model has a Humanoid inside it, and this Humanoid gives you two key properties for health systems.
The first property is Health. This is the current health of the character. When Health reaches 0, the character dies and the humanoid triggers its death behavior. The second property is MaxHealth. This is the maximum value that Health is allowed to reach. If you try to set Health above MaxHealth, Roblox automatically clamps it so that $Health \leq MaxHealth$.
Important rule: The character dies when Humanoid.Health is less than or equal to 0. The health value is always between 0 and MaxHealth.
By default, most characters have MaxHealth = 100 and start with Health = 100. You can change these values in the Properties window of a Humanoid, or you can change them with scripts. Adjusting these values is the first step when you want tougher or weaker players.
Changing Health with Scripts
To control the health system, you frequently change the Health property using scripts. Any Script or LocalScript that has a reference to a Humanoid can modify its health at runtime. The most direct way is to assign a new value to Health.
For example, imagine you have a reference called humanoid. You can set health to 50 like this:
local humanoid = script.Parent:FindFirstChild("Humanoid")
if humanoid then
humanoid.Health = 50
end
This instantly sets the current health. In many situations, you want to reduce or increase health relative to its current value. To apply damage you subtract from Health. To heal you add to Health.
-- Deal 20 points of damage
humanoid.Health = humanoid.Health - 20
-- Heal 10 points of health
humanoid.Health = humanoid.Health + 10
To avoid errors in more complex games, it is common to check if the humanoid still exists and is alive before you change the health. The Humanoid has an Health value that must be greater than 0 to be considered alive.
local humanoid = script.Parent:FindFirstChild("Humanoid")
if humanoid and humanoid.Health > 0 then
humanoid.Health = humanoid.Health - 20
end
Health changes automatically replicate from the server to all clients when you modify Humanoid.Health on the server. Because of that, any health logic that must be secure should run on the server so that players cannot easily cheat by changing their own health.
Using TakeDamage and Healing Safely
Roblox provides a helper function on the Humanoid object called TakeDamage. This function subtracts a specified amount of health and applies all default death behavior for you. Instead of writing humanoid.Health = humanoid.Health - 10, you can simply call:
humanoid:TakeDamage(10)
TakeDamage will never increase health and will never reduce health below 0. It is designed specifically for dealing damage. Because it is a built-in function, it is usually safer and clearer to use it in damage scripts. For example, a lava brick that deals damage when touched might use:
local DAMAGE = 25
local function onTouched(otherPart)
local character = otherPart.Parent
local humanoid = character and character:FindFirstChild("Humanoid")
if humanoid then
humanoid:TakeDamage(DAMAGE)
end
end
script.Parent.Touched:Connect(onTouched)
For healing, there is no Heal function on the Humanoid, so you still use direct assignments. To avoid going over the maximum, you can use the minimum of the new value and MaxHealth. In math terms, this is
$$
NewHealth = \min(CurrentHealth + HealAmount, MaxHealth)
$$
In code you can write:
local HEAL_AMOUNT = 20
local function heal(humanoid)
if humanoid.Health > 0 then
local newHealth = humanoid.Health + HEAL_AMOUNT
if newHealth > humanoid.MaxHealth then
newHealth = humanoid.MaxHealth
end
humanoid.Health = newHealth
end
end
Key pattern: Use Humanoid:TakeDamage(amount) for damage. When healing, clamp the health value so it never exceeds Humanoid.MaxHealth.
Using these patterns keeps your health system predictable and stable, even when many things in the game are affecting health at the same time.
Customizing Max Health and Difficulty
Changing MaxHealth lets you control how durable a player is in your game. This directly affects game difficulty and pacing. For example, you might give new players higher maximum health, or you might increase MaxHealth as a reward when they level up.
You can change MaxHealth at any time with a script. For a simple example, to set a player character’s max health to 200 and fully heal them, you could do:
local humanoid = script.Parent:FindFirstChild("Humanoid")
if humanoid then
humanoid.MaxHealth = 200
humanoid.Health = humanoid.MaxHealth
endIn combat based games you might want to scale health based on some stat like level. A simple formula could be:
$$
MaxHealth = BaseHealth + Level \times HealthPerLevel
$$
You can implement this in Roblox like this:
local BaseHealth = 100
local HealthPerLevel = 20
local level = 5 -- example
local humanoid = script.Parent:FindFirstChild("Humanoid")
if humanoid then
local newMax = BaseHealth + level * HealthPerLevel
humanoid.MaxHealth = newMax
humanoid.Health = newMax
endBy using formulas, you can maintain a consistent curve of difficulty instead of setting health manually for every situation. This becomes important when your game has many enemies, bosses, or progression systems that rely on health values.
Listening to Health Changes with Events
Roblox gives you a useful way to react when health changes, by using the HealthChanged event on the Humanoid. This event fires every time the Health value changes. It sends the new health value as a parameter to your function.
You can use HealthChanged to update health bars in the user interface, to play hurt sounds, or to trigger special effects when a player is low on health.
Here is a basic example that prints the new health value:
local humanoid = script.Parent:FindFirstChild("Humanoid")
local function onHealthChanged(newHealth)
print("New health:", newHealth)
end
if humanoid then
humanoid.HealthChanged:Connect(onHealthChanged)
endFor a more game-like behavior, you might want to detect when the player falls below a certain percentage of their maximum health. A low health warning could happen at 25 percent of max health. The math is:
$$
LowHealthThreshold = 0.25 \times MaxHealth
$$
In code:
local humanoid = script.Parent:FindFirstChild("Humanoid")
local function onHealthChanged(newHealth)
if newHealth <= 0 then
print("Player died")
elseif newHealth <= humanoid.MaxHealth * 0.25 then
print("Warning, low health!")
end
end
if humanoid then
humanoid.HealthChanged:Connect(onHealthChanged)
end
Useful pattern: Connect to Humanoid.HealthChanged to update UI and feedback instead of constantly checking health in a loop.
By relying on HealthChanged, your health system becomes event driven. This keeps your scripts efficient and makes it easier to organize things like sound, screen effects, and UI bars around health.
Handling Death and Respawn Logic
When a character’s Health reaches 0, the Humanoid fires the Died event. Roblox then handles default death effects and respawning behavior for you, but you often need to add custom logic when a player dies. For example, you might remove coins, reset a combo counter, or show a custom death screen.
To run code when a character dies, connect to Humanoid.Died:
local humanoid = script.Parent:FindFirstChild("Humanoid")
local function onDied()
print("Character has died")
-- Custom logic, such as giving a death message or logging stats
end
if humanoid then
humanoid.Died:Connect(onDied)
end
On the server, you can also connect to Player.CharacterAdded and then to that character’s humanoid events. This lets you manage death and health behavior for each player from a central script in ServerScriptService. You can attach health logic every time the player respawns.
The important point is that the health system drives the death system. As soon as health reaches zero, the Died event happens. By listening for Died, you can connect your health system to other player systems such as leaderboards or stats that care about deaths.
Basic Health Regeneration
Many games use health regeneration to make encounters feel more forgiving. Regeneration slowly restores health over time while the player is alive. Roblox humanoids can support regeneration either through built-in properties or through your own code.
A common pattern is to increase health by a small amount every few seconds, as long as the player is not already at full health and is not dead. A simple script might look like this:
local humanoid = script.Parent:FindFirstChild("Humanoid")
local REGEN_AMOUNT = 2
local REGEN_DELAY = 1
local function startRegen()
while humanoid and humanoid.Health > 0 do
if humanoid.Health < humanoid.MaxHealth then
local newHealth = humanoid.Health + REGEN_AMOUNT
if newHealth > humanoid.MaxHealth then
newHealth = humanoid.MaxHealth
end
humanoid.Health = newHealth
end
wait(REGEN_DELAY)
end
end
if humanoid then
coroutine.wrap(startRegen)()
end
This code regenerates 2 health every second until the humanoid dies. The idea is simple. You keep checking if the humanoid is alive, and if so, you gently nudge the health back up toward MaxHealth. By changing REGEN_AMOUNT and REGEN_DELAY, you control how fast health regenerates.
Regeneration formula: If RegenPerSecond is your rate, then after $t$ seconds the regenerated health is approximately $RegenPerSecond \times t$. Always clamp the result so it does not exceed MaxHealth.
For more advanced designs, you might stop regeneration while the player is taking damage, or after using certain abilities. These variations all use the same base idea: adjust Health over time, but stay inside the [0, MaxHealth] range.
Using Health with Other Player Systems
The health system does not exist alone. It connects directly to damage systems and indirectly to player stats and saving systems. Damage systems modify Health through TakeDamage or direct changes. Leaderboards might track how many times a player dies by listening to the Died event and updating a stat. Saving systems might store upgrades that increase MaxHealth and apply them again when the player rejoins.
When building your game, think of health as a shared resource that other systems read and write. Scripts that need to know if a player is alive should check Humanoid.Health. Scripts that reward surviving should watch Humanoid.Died to know when players fail. Scripts that show UI should respond to Humanoid.HealthChanged to keep the display accurate.
By separating these responsibilities, you can keep your health system clear and simple. One part of your code focuses on changing health values safely. Other parts listen for those changes and provide feedback, rewards, or penalties. This structure makes it much easier to expand your game without breaking the core health logic.