How would I prevent recursion on changing Humanoid.Health?

It’s a lot more pain staking than the title displays XD

So I have a damage buffer on the server, I detect changes in a player’s health on the client (I’ve tried both the health propertychangedsignal and HealthChanged, but they’re both technically similar) and then simply fire the health value to the server.

Now the issue is that after doing so, it works fine… but after a few seconds it fires by itself again? Then again repeatedly. I’m confused because I’ve tried using debounce but the delay differs between it firing again.

You can mimic the behaviour on your own by creating a RemoteEvent and doing this:

-- Client
Player.Character.Humanoid.HealthChanged:Connect(function(Health)
    RemoteEvent:FireServer(Health)
end)
-- Server
local PlayerDebounces = {}
game:GetService("Players").PlayerAdded:Connect(function(Player)
    PlayerDebounces[Player.Name] = false
end)
RemoteEvent.OnServerEvent:Connect(function(Player, Health)
    if PlayerDebounces[Player.Name] then return end
    Player.Character.Humanoid:TakeDamage(20) -- Example buff.
    PlayerDebounces[Player.Name] = true
    coroutine.wrap(function() -- Create a separate thread for debounce handle.
        wait(0.1) -- I've tried changing the delay even upto 10 seconds, no luck.
        PlayerDebounces[Player.Name] = false
    end)()
end)

I’d appreciate any help as I’ve been stuck on this issue for a while now.
(I’ve tried client debounce too.)

That is because when the health changes you tell the server to damage you by 20, which changes your health, therefore fires HealthChanged again, which damages you again, and it repeats. Are you sure you need to do it like this?

lets say we do the :fireserver

this reduces the health by 20

the health has changed so now we trigger the remote event again

wich reduces the health by 20

etc.etc

I understand that that’s what happens which is why I’m confused the debounce did not work. All I need to do is apply the buff generically whenever the player takes damage (as there are multiple ways they can take damage). I suppose another way would be to fire an event specifically for the damage bugg thats not applied to any other connections but is there not a solution to my current situation?

ALSO: It’s based on a stack increasing system where you have a chance to increase the damage buff each time your health decreases which is why I’m trying to achieve it this way.

As I said before I know why it’s happening but I am lost on how to prevent it as what I’ve tried hasn’t worked.

quick whipout , maybe this?

-- Server
local PlayerDebounces = {}
game:GetService("Players").PlayerAdded:Connect(function(Player)
    PlayerDebounces[Player.Name] = false
end)
RemoteEvent.OnServerEvent:Connect(function(Player, Health)
    if  PlayerDebounces [Player.Name] == false or not PlayerDebounces [Player.Name] then
      PlayerDebounces[Player.Name] = true
        Player.Character.Humanoid:TakeDamage(20)
        wait(0.1) 
        PlayerDebounces[Player.Name] = false
end
    end)()
end)

Yeah I’ve done that check but I forgot to include it in the reproduction script, edited post.

Well could you anticipate what the new health will be once the server changes it, and set the health to a variable. Then before firing the server next time check if the current health is what you had anticipated the health to become last time. Does that make sense?

Yeah I’ve already done that too. I’m pretty sure I’ve tried everything, plus the health change is unpredictable, somehow remarkably the health increases?

You fired the server with the parameter “Health”, but the script you showed us doesn’t use that parameter. Do you use that parameter in your actual script?

This doesn’t matter as HealthChanged is triggered anyway on modifying the player’s health.

try moving the PlayerDebounces[Player.Name] = true before the damage being done

Well you mentioned that sometimes the health goes up after you fired the server so I was wondering if that had to do with it. Do you do:

 humanoid:TakeDamage(health)

Yes as you can see in the original post.

Good idea but didn’t make any difference.

ok so, roblox has an automatic healt regeneration over time…
you need to disable this.

I. Create a blank script, name it ‘Health’.
II. Place it in Game > StarterPlayer > StarterCharacterScript
(from here https://scriptinghelpers.org/questions/34410/how-to-stop-that-players-heal-automatic-answered)

AH YES YOU’RE RIGHT THAT’S IT!
Thanks for this! Though I’m probably going to have to not use the event at all then since it would be impractical, I’ll just put the function in a module and be able to set it from different scripts.

1 Like