Stamina regeneration delay not working, how to delay / pause a loop?

I have a stamina system where the stamina takes a second to start regenerating after performing an action that spends stamina. However, this delay I implemented does not work as intended; when repeatedly performing actions that spend stamina, the stamina will continue regenerating while performing the actions.

I want the regeneration loop to stop when an action that spends stamina is done, but I could not achieve that no matter what I tried. I attempted to use a BoolValue to get it to work, but it just doesn’t help at all. I also tried using the break function and it didn’t help either.

Here is the code for the stamina regeneration:

local stamina = script.Parent
local canregen = stamina.CanRegen
local oldstaminavalue = stamina.Value
local newstaminavalue = stamina.Value

stamina.Changed:Connect(function()
	newstaminavalue = stamina.Value
	if oldstaminavalue > newstaminavalue then
		oldstaminavalue = stamina.Value
		canregen.Value = false
		task.wait(1)
		canregen.Value = true
	end
end)

canregen.Changed:Connect(function()
	while task.wait(0.01) and canregen.Value == true and stamina.Value < 100 do
		stamina.Value += 1
	end
end)

The regeneration itself works, but I just can’t get it to stop regenerating when I perform an action that spends stamina while it is regenerating. How can I get this to work? Thank you.

1 Like

Bump. I still could not get it fixed, no matter what I did.

The problem lies within this function:

stamina.Changed:Connect(function()
	newstaminavalue = stamina.Value
	if oldstaminavalue > newstaminavalue then
		oldstaminavalue = stamina.Value
		canregen.Value = false
		task.wait(1)
		canregen.Value = true
	end
end)

Since the line oldstaminavalue = stamina.Value is within the if statement, the oldstaminavalue variable is not being updated when stamina regen begins because currentstaminavalue becomes larger than oldstaminavalue leading to the if statement to evaluate as false. This can be fixed by simply moving it after the if statement so that it is always updated.

However, if you run the script after changing that, you will notice that stamina will start regenerating extremely fast. This is because each time stamina.Changed:Connect() occurs, it spawns a separate thread. All the threads spawned start setting canregen to true after a second while new threads set it to false, causing multiple stamina loops to be created. This can be prevented by implementing a check to make sure that stamina hasn’t changed over the course of that second.

Here is the fixed function:

stamina.Changed:Connect(function()
	local newstaminavalue = stamina.Value
	--During ongoing stamina drain, we want to make sure that we use the value of stamina at the time this thread was made.
		
	if oldstaminavalue >= newstaminavalue then
		--Changed the > to a >= because if the stamina drain is as fast as the stamina regen, it will get stuck on a number and keep the regen on.
		canregen.Value = false
	end
	
	oldstaminavalue = stamina.Value
	
	task.wait(1)
	
	if oldstaminavalue == newstaminavalue then
		canregen.Value = true
	end	
end)

You may also want to implement a check to make sure there can only be one stamina regeneration loop active at a time.