Health script attempts to heal character after death ( Causes triple kills )

The Health script continues to attempt to heal the character even after they’ve died causing the Humanoids HealthChanged to fire multiple times after death

  • How often does the bug happen (Everytime/sometimes/rarely)? What are the steps that reproduce the bug?
    Occurs everytime, can repro via the following code in the command bar in play solo:
game.Players:GetPlayers()[1].Character.Humanoid.HealthChanged:connect( function( a ) print( a ) end )
game.Players:GetPlayers()[1].Character.Humanoid.Health = 0
  • Where does the bug happen (www, gametest, etc) Is it level-specific? Is it game specific?
    Occurs in www in every place using the default ROBLOX health script

  • When did the bug start happening? If we can tie it to a specific release that helps us figure out what we broke.
    When it was changed to the new Health script ( Not sure of the date, only recently noticed the script was changed, may have been this one for a while now )

Can be fixed by adding the following or something similar to replace the while true do:

while true do
	while true do
		local dt = wait(REGEN_STEP)
		if Humanoid.Health >= Humanoid.MaxHealth or Humanoid:GetState() == Enum.HumanoidStateType.Dead then break end
		Humanoid.Health = math.min(Humanoid.Health + dt * REGEN_RATE * Humanoid.MaxHealth, Humanoid.MaxHealth)
	end
	Humanoid.HealthChanged:Wait()
end
5 Likes

Can be done even simpler with a minor change.

Existing:
-- Gradually regenerates the Humanoid's Health over time.

local REGEN_RATE = 1/100 -- Regenerate this fraction of MaxHealth per second.
local REGEN_STEP = 1 -- Wait this long between each regeneration step.

--------------------------------------------------------------------------------

local Character = script.Parent
local Humanoid = Character:WaitForChild'Humanoid'

--------------------------------------------------------------------------------

while true do
	while Humanoid.Health < Humanoid.MaxHealth do
		local dt = wait(REGEN_STEP)
		local dh = dt*REGEN_RATE*Humanoid.MaxHealth
		Humanoid.Health = math.min(Humanoid.Health + dh, Humanoid.MaxHealth)
	end
	Humanoid.HealthChanged:Wait()
end
Modified:
-- Gradually regenerates the Humanoid's Health over time.
local REGEN_RATE = 1/100 -- Regenerate this fraction of MaxHealth per second.
local REGEN_STEP = 1 -- Wait this long between each regeneration step.

--------------------------------------------------------------------------------

local Character = script.Parent
local Humanoid = Character:WaitForChild("Humanoid")

--------------------------------------------------------------------------------

while true do
	while Humanoid.Health < Humanoid.MaxHealth and Humanoid:GetState() ~= Enum.HumanoidStateType.Dead do
		local dt = wait(REGEN_STEP)
		local dh = dt*REGEN_RATE*Humanoid.MaxHealth
		Humanoid.Health = math.min(Humanoid.Health + dh, Humanoid.MaxHealth)
	end
	Humanoid.HealthChanged:Wait()
end

This also is forward-compatible with future changes to Humanoids that would allow developers to undo death (e.g. second chance ability), as the script would resume once the Humanoid was revived. Unfortunately, due to how hacky humanoids are, undoing death is not possible right now. Humanoids are told to go “DIE DIE DIE” to any joints added after the character dies, even after the death state is disabled.

1 Like

Looks like your way still heals them once after they die:

So it would need to check if it’s 0 too:
while Humanoid.Health < Humanoid.MaxHealth and Humanoid.Health > 0 and Humanoid:GetState() ~= Enum.HumanoidStateType.Dead do

Found this bug while looking for what was causing KOs to sometimes register three times and it seems it is a byproduct of this bug. I believe the following is happening:

Player1 Dies
Died is triggered for their humanoid
at the same time Player1 is healed, thus preventing them from actually dieing
Player1 is still alive and thus, if the Player2 is still shooting at them, they’re killed again, resulting in multiple KOs

In that image - First word is my username, that’s whos humanoid it is ( Backwards in the healing one, not sure why I did that )
Second word is what happened ( i.e. they were healed by the health script, they were damaged ( Humanoid.HealthChanged ) or they died ( Humanoid.Died ) ) and the third arg is their old health, fourth arg is their new health.

This was before I added the check for 0 Health, which is why it’s still attempting to heal them after their dead.

I can’t repro this in play solo and it only rarely happens although it’s not happened since I added the fix that’s in OP to the game.

If that makes sense would anyone object to me making this ROBLOXCRITICAL?

This definitely doesn’t meet the criteria of ROBLOXCRITICAL. ROBLOXCRITICAL is reserved for bugs that make top games unplayable and affect tens of thousands of players. A display issue for stats doesn’t make a game unplayable, and niche war groups don’t amount to a significant number of players. This is not a newly introduced bug either, so this is more on your game for not properly handling existing behavior.

2 Likes

It affects anyone using the Died event as it fires three times per death under certain circumstances, and sometimes the player doesn’t actually die when they should.

But OK.

Just wanted to add, we’ve seen this in all our group games for Vortex Security as well. Triple kills, issues with the death event, people healing after being killed, etc. I think the first reports for this started coming in a few weeks ago.

2 Likes

Just a note; the code in op and this thread does not fix this issue. For some reason that I’m still debugging it continues to heal them once after they die, even printing 0 health when it heals them.

I’ll post a true fix once I find it.

Big derp on my behalf, it was running once after they die because it was checking if they were dead before the wait. Fixed while loop:

while true do
	while true do
		local dt = wait(REGEN_STEP)
		if Humanoid.Health >= Humanoid.MaxHealth or Humanoid:GetState() == Enum.HumanoidStateType.Dead then break end
		Humanoid.Health = math.min(Humanoid.Health + dt * REGEN_RATE * Humanoid.MaxHealth, Humanoid.MaxHealth)
	end
	Humanoid.HealthChanged:Wait()
end

I’ll test if this fixes the triple kills today. If this fixes the triple kills it seems like this is a bug that ROBLOX needs to fix ( Being healed after Died is fired ) otherwise developers that have custom heal scripts could be causing triple kills / people not to die.

I can confirm that this bug is live and should be looked into, has happend to plenty of group places that I’ve visited over the week.

1 Like

After a day of testing it appears the latest code in the OP does indeed fix the triple kill bug.

@Kuas @NoCollider If either of you guys want a quick fix just copy the Health script from your character in play solo, paste it into game.StarterPlayer.StarterCharacterScripts and change the while loop for the one in OP.

EDIT: Thought it was still broken but it isn’t, was being healed by something else ( A tool that doesn’t have this fix ). If you have anything else that heals make sure they check if the character is alive ( Humanoid:GetState( ) ~= Enum.HumanoidStateType.Dead )

@EchoReaper
Should I make a separate bug report about the .Died event firing multiple times under certain circumstances?

Can confirm that the health script does in fact heal after a humanoid dies but it looks hacky in the way it shows a bit of red before being pushed back down. I was wondering why my turret was shooting at six pieces on the ground in my test server.

On live servers, if you have custom health regeneration logic or replace the Health script with a blank one, this does not serve as a problem.

Just wanted to mention this is still happening. The health script is still attempting to heal the player after they have died.

Not sure if this is still causing the .Died event of the humanoid to fire multiple times under certain circumstances though.

1 Like