Custom health regeneration script

(Please note this is my first attemp at a tutorial)
Hello,
In this post, I will show you how to create your own custom health regeneration script. One might however ask, why would one prefer a custom health regeneration script over the default one? Well, this script allows you to easily customise the regeneration limit (for example 0.2 * humanoid.MaxHealth is 20%, it will not regenerate past 20% of MaxHealth), the regeneration rate (essentially cooldown), size (in hp). Of course, you can probably implement all of this into the default roblox script, however I just felt like rewriting it, and I made this. If there are any problems, please comment them and I will read them when I have time.

Tutorial:

  1. Setting up the script

First, you have to prepare the script. In explorer, find StarterPlayer. Expand it, and you should see StarterCharacterScripts. Insert a Script into it, and name the script “Health”

Note: It is essential to name the script exactly “Health” so it replaces the default roblox script. Having two scripts might cause errors or otherwise heal the player twice as fast.

  1. Variables

Once you have prepared your health script, it is time to determine some variables. We need to get the player character and its Humanoid object as that is where the player’s Health is stored. We also need a variable to determine the player’s last health, and two variables to measure time passed since the last damage and the last regen. Finally, we need the regeneration limit, rate and size.

Your script should look like this now:

local character = script.Parent
local humanoid = character:FindFirstChild("Humanoid")

local currentHealth = humanoid.Health -- We will use this to measure all health changes and differentiate between a regeneration and a loss.
local lastDamage = nil -- We will use this variable to measure time from the last damage, incase you want the script to only heal when the player isn't actively taking damage.
local lastRegen = tick() -- We will use this to measure time since the last regen and add a cooldown.

local regenerationLimit = 0.2 * humanoid.MaxHealth -- The script will not heal above this point. 0.2 is 20% in percentages, you can change this to your liking.
local regenerationRate = 1 -- How long it takes between every regen.
local regenerationSize = 0.01 * humanoid.MaxHealth -- What portion of the health will be regenerated every heal.
  1. Detecting health changes

Now that we have our variables set up, we will soon start scripting the main function. Before we do that, however, we need to detect health changes. This is to add a damage cooldown. We will start by detecting when the health changes, later determining whether it was a regeneration or a loss, and check if there was a damage loss in the same time as the regeneration.

For detecting health changes, we will use a .Changed event. We want to get the property to check if it is health.

humanoid.Changed:Connect(function(property)
	
end

We now want to check if it is the property we are looking for. We will check for Health and MaxHealth.

humanoid.Changed:Connect(function(property)
	if property == "Health" or property == "MaxHealth" then
	
	end
end

The reason we are checking for MaxHealth is if the MaxHealth changes, we want the script to know if the health is still above the regeneration limit.

Now, we will check to see if damage was actually taken. We will also check for health gained, as if for example your regen is 1 but someone took 0.6 damage, it will still be a +0.4 gain for health and the script will not detect that. We will also ignore the health if the player is dead.

humanoid.Changed:Connect(function(property)
	if property == "Health" or property == "MaxHealth" then
		if humanoid.Health < currentHealth and humanoid.Health > 0 then
			
		elseif humanoid.Health > currentHealth and humanoid.Health > 0 then
			
		end
	end
end

Finally, we will set our variables in order to be prepared for the next change.

humanoid.Changed:Connect(function(property)
	if property == "Health" or property == "MaxHealth" then
		if humanoid.Health < currentHealth and humanoid.Health > 0 then
			currentHealth = humanoid.Health
			lastDamage = tick()
		elseif humanoid.Health > currentHealth and humanoid.Health > 0 then
			if currentHealth + regenerationSize > humanoid.Health then
				lastDamage = tick()
			end
			currentHealth = humanoid.Health
		end
	end
end)

As you can see in the elseif statement, we check if the HP would normally be the same after a regen. If the calculation is less than the actual HP, damage was taken during the regeneration.

  1. Regenerating health

Now that we have a function that detects health changes, we can finally make a function that regenerates health. Each second, we will check if the humanoid is eligible to recieve a regeneration, if it is heal it and restart the cooldown timer. We will start from a while true do loop.

while true do
	
end

We will now check for the aforementioned cooldown to prevent healing during active taking damage. We will also add a wait to prevent exhaustion.

while true do
	if lastDamage == nil or (tick() - lastDamage) >= 5 then
		
	end
	wait()
end

Since by default the lastDamage is set to nil, we must check for that. LastDamage == nil means that the humanoid has not taken any damage.

We now want to check for the regeneration limit.

What is regeneration limit?

Oh, you still don’t understand what that is? Let me explain.

Let’s say Player1 just got shot by Player2 but managed to get away. We now have 2 scenarios.

SCENARIO 1: Player1 lost so much HP to the point that it went below 20%. In the script, 0.2 (20%) is set as the regeneration limit. Player1 will regenerate until their HP is equal to 20%.

SCENARIO 2: Player2 didn’t lose much HP, and it only went down to 50%. In the script, 0.2 (20%) is set as the regeneration limit. Player1 will not regenerate any HP until it goes below the limit.

I hope that clarified everything if you didn’t understand.

Here is how we will check for the regeneration limit.

while true do
	if lastDamage == nil or (tick() - lastDamage) >= 5 then
			if currentHealth < regenerationLimit then
					
			end
		end
	end
	wait()
end

We now want to check for the last regeneration. After all, we don’t want health to regenerate to the limit instantly as it would be impossible to kill said person.

while true do
	if lastDamage == nil or (tick() - lastDamage) >= 5 then
			if currentHealth < regenerationLimit then
				local timePassed = (tick() - lastRegen)
				if timePassed >= regenerationRate then
					
				end
			end
		end
	end
	wait()
end

Everything we have to do now is change the player’s health.

while true do
	if lastDamage == nil or (tick() - lastDamage) >= 5 then
		if currentHealth < regenerationLimit then
			local timePassed = (tick() - lastRegen)
			if timePassed >= regenerationRate then
				lastRegen = tick()
				local healthToAdd = regenerationSize
				humanoid.Health = math.min(humanoid.Health + healthToAdd, humanoid.MaxHealth)
			end
		end
	end
	wait()
end

What does math.min mean?

Here, we are looking for the lowest one of the given arguments. For example, if your regeneration limit is humanoid.MaxHealth, adding the healthToAdd might give us a value over the MaxHealth. While roblox will still automatically change the HP, a healthbar may glitch out for a second. To prevent this, we check if the humanoid.Health + healthToAdd is higher than the MaxHealth, and if it is we choose MaxHealth as it is lower.

Full script if you miswrote something:

local character = script.Parent
local humanoid = character:FindFirstChild("Humanoid")

local currentHealth = humanoid.Health
local lastDamage = nil
local lastRegen = tick()

local regenerationLimit = 0.2 * humanoid.MaxHealth
local regenerationRate = 1
local regenerationSize = 0.01 * humanoid.MaxHealth

humanoid.Changed:Connect(function(property)
	if property == "Health" or property == "MaxHealth" then
		if humanoid.Health < currentHealth and humanoid.Health > 0 then
			currentHealth = humanoid.Health
			lastDamage = tick()
		elseif humanoid.Health > currentHealth and humanoid.Health > 0 then
			if currentHealth + regenerationSize > humanoid.Health then
				lastDamage = tick()
			end
			currentHealth = humanoid.Health
		end
	end
end)

while true do
	if lastDamage == nil or (tick() - lastDamage) >= 5 then
		if currentHealth < regenerationLimit then
			local timePassed = (tick() - lastRegen)
			if timePassed >= regenerationRate then
				lastRegen = tick()
				local healthToAdd = regenerationSize
				humanoid.Health = math.min(humanoid.Health + healthToAdd, humanoid.MaxHealth)
			end
		end
	end
	wait()
end

And there we have it, a fully working custom health regeneration script. I hope this tutorial was helpful, that you understood everything and that the code worked for you. If you would like to rate this tutorial or ask for help, feel free to comment down below. Thanks, and have a nice day!

22 Likes

It’s better to use task.wait

task (roblox.com)

Oh, yeah, true. I forgot about task.wait. Thanks for mentioning it.

1 Like

Great guide, I’m working on my health system for my new game atm. Do you recommend Humanoid.HealthChanged over .Changed?

While true do 

is less efficient than using a recursive function because it runs forever using a lot of memory.
Or another option is using;

repeat 

-- Regen code

until Humanoid.Health >= 100

Example for a recursive function:

function RegenHealth()

-- Code for regenning

RegenHealth() -- Call the function
  
end

RegenHealth() -- Call it again to make a endless loop.

I personally only use repeat when I’m slowly incrementing a number.

I recommend using

Humanoid:GetPropertyChangedSignal("Health"):Connect(function()

-- Your code

end)

Because it only runs when the Humanoids [ Health ] changes, and is more efficient on performance.

1 Like

Yeah what I Do in my system is HealthChanged and then i do

if profile.Data.CurrentHealth < 0 then return end
			while profile.Data.CurrentHealth  > 0 and profile.Data.CurrentHealth < profile.Data.MaxHealth do

Thank you very much. I will be using this from now on

1 Like

Your welcome! Thanks for the reply!

2 Likes