Small change creating big consequences

Hello everyone, I have this simple little code that acts like a trap:

local part = script.Parent
local isTouched = false

local function touchedFunc(otherPart)
	local parent = otherPart.Parent
	local humanoid = parent:FindFirstChild("Humanoid")
	if humanoid then
		if not isTouched then
			isTouched = true
			humanoid.Health = humanoid.Health - 10
			wait(1)
			isTouched = false
		end
	end
end

part.Touched:Connect(touchedFunc)

And it works. But before I ended up with this script, I was using this same script, except that the wait() and isTouched = false were outside the if not isTouched then. Like this:

if humanoid then
		if not isTouched then
			isTouched = true
			humanoid.Health = humanoid.Health - 10
		end
            wait(1)
			isTouched = false
	end

I am saying this because the first script, with the wait() and isTouched = false inside the if not isTouched then, works as intended, the debouce stops the function from firing to many times. But the second one, with them both outside of the if statement, the debounce does not work.

And I am not being able to comprehend on why that happens, could someone shine a light on this for me?

When it is outside, isTouched is never set to true, but isTouched is set to false 1 second later anyways. So if the part touches anything that is not a player, the debounce will be reset one second later. So if it touches something else, and then I step on it 0.9 seconds later, the debounce for me is effectively only 0.1 seconds.

1 Like

I just ran a test with the part floating in the air and just touching the player, and the same result happened. I have been slamming by face on the table and I still can’t understand what happens with the code…

It also happens if a player touches it during the debounce. So if I touch it 20 times during the 1 second debounce, then after the 1 second debounce, I can touch it and activate it 20 times in the next 1 second and at least that many times if not more in the seconds afterwards.

Yeah, I appreciate you for your help but I still did not manage to make sense out of it. I am new to programming and Roblox Lua, that’s why I am having such a hard time to understand. Thank you for your time!

I’ll start with an easy measurement of time, half seconds, but remember that this can happen much much faster.

0 seconds: If I touch the part, I take damage. isTouched is set to true and a 1 second countdown is started.
0.5 seconds: If I touch the part again, isTouched is true and so I don’t take damage. But I still start another 1 second countdown.
1 seconds: The first countdown finishes and isTouched is set to false. I touch it again, and take damage again, and start a new 1 second countdown. isTouched is set back to true.
1.5 seconds: The second countdown ends and isTouched is set to false. I can touch it again to take damage again, even though it’s only been 0.5 seconds since I last took damage. isTouched is set to true and another countdown starts.
2 seconds: The third countdown ends and isTouched is set to false again. I can touch it and take damage again.

This example is in half-second increments, but it can actually happen lightning fast. Basically, you’re setting up a way for isTouched to be set to false before it is supposed to be set to false.

1 Like

Ohhh, I think I got it now. I don’t really know how to explain it, but I am basically overlapping a bunch of wait()s and isTouched = false. And that does not happen when they are inside the if humanoid, because they are following the order, correct?

1 Like

Yep, that’s exactly right. Good luck in your scripting!

1 Like

Thank you for everything! Good luck in yours too!

1 Like