Debounce turning true even when impossible to do so

local humanoidRootPart = character:WaitForChild('HumanoidRootPart')
humanoidRootPart.Touched:Connect(function(hit)    
if not debounce then
	debounce = true
	local hasPass = false
											
	print(debounce, 'tagging')
	taggedCharacter.Humanoid.WalkSpeed = 0					
	taggedCharacter.Humanoid.JumpPower = 0	
	taggedCharacter.HumanoidRootPart.Anchored = true
											
	if marketplaceService:UserOwnsGamePassAsync(game.Players:GetPlayerFromCharacter(taggedCharacter).UserId, rainbowIceID.Value) then
		hasPass = true
	end
											
	tagging:FireAllClients('Tagging', taggedCharacter, hasPass)
											
	local frozen = Instance.new('BoolValue')
	frozen.Name = 'Frozen'
	frozen.Parent = taggedCharacter
																	
	local tagPlayer = game.Players:GetPlayerFromCharacter(character)
	if tagPlayer then
		updateTags:Fire(tagPlayer)
	end
	wait(1)
	print('changing debounce')
	debounce = false
	print(debounce, 'Changed')
end

For some reasion by the end of this script the debounce is set back to true? It prints the true at the top, then the changing debounce, debounce changed, then true tagging again and then stops. I do not know why this is happening and any help would be greatly appreciated :smiley:

Iā€™m not sure if i should edit the wait time, because if two players get tagged at the same time then it could cause only becomming tagged, as this is in a server script along with the main game. If anything Iā€™d like the wait to be like 0.01

This seems to be an incomplete version of the function, is there anything else in the function that could be yielding? (For example, taggedCharacter is not defined in the given code and the end to close the function is not present.)

Another thing to look out for is that you have function calls that might throw and error in this code such as marketplaceService:UserOwnsGamePassAsync, if it throws an error you will leave debounce as true. You should pcall this function. In general most functions that make web requests should be pcalled as they typically throw errors if they canā€™t reach the website.

game.Players:GetPlayerFromCharacter(taggedCharacter).UserId

Code like this is also dangerous because if GetPlayerFromCharacter returns nil it will error and debounce will remain true.

When you say ā€˜tag them on the clientā€™ what exactly does that mean, take away their speed and and what not? because last time i tried that it ended up messing up with multiple players and youd tag the player and on your screen theyd be frozen, but on the tagged players screen they could still run around freely

Thatā€™s where validation from the server would come in.

Client:
-Tags a player (play some ā€˜hitā€™ graphic)
-Sends prompt to server to check if player is actually tag-able.

Server:
If Tag-able
-Tell Tagged player to freeze
-(return true)
else
-(return false)

Client (check response from server)
If True
-(idk, give coins?)
If False
-display a ā€˜Missedā€™ graphic

Yea, I only sent what I thought would be relevant to the debounce. Hereā€™s the entire thing:

player.CharacterAdded:Connect(function(character)
	if character then
		local debounce = false
		
		local humanoidRootPart = character:FindFirstChild('HumanoidRootPart')
		humanoidRootPart.Touched:Connect(function(hit)
			if active.Value then
				local taggedCharacter = hit.Parent
				if taggedCharacter and not taggedCharacter:FindFirstChild('Frozen') then
					-- Tagging player
					local humanoid = taggedCharacter:FindFirstChild('Humanoid')
					if humanoid then
						if player.Team == teams.Red then
							local player = game.Players:GetPlayerFromCharacter(taggedCharacter)
							if player and player.Team == teams.Blue then 
								if selectedGamemode.Name == 'Classic' then
									if not debounce then
										debounce = true
										local hasPass = false
										
										print(debounce, 'tagging')
										taggedCharacter.Humanoid.WalkSpeed = 0					
										taggedCharacter.Humanoid.JumpPower = 0	
										taggedCharacter.HumanoidRootPart.Anchored = true
										
										if marketplaceService:UserOwnsGamePassAsync(game.Players:GetPlayerFromCharacter(taggedCharacter).UserId, rainbowIceID.Value) then
											hasPass = true
										end
										
										tagging:FireAllClients('Tagging', taggedCharacter, hasPass)
										
										local frozen = Instance.new('BoolValue')
										frozen.Name = 'Frozen'
										frozen.Parent = taggedCharacter
																
										local tagPlayer = game.Players:GetPlayerFromCharacter(character)
										if tagPlayer then
											updateTags:Fire(tagPlayer)
										end
										wait(0.1)
										print('changing debounce')
										debounce = false
										print(debounce, 'Changed')
									end		
								end
							end
						end
					end
				elseif taggedCharacter and taggedCharacter:FindFirstChild('Frozen') then
					-- Untagging player
					local humanoid = taggedCharacter:FindFirstChild('Humanoid')
					if humanoid then
						print(debounce)
						if not debounce then
							debounce = true
							if hit and hit.Name == 'Freeze' then
								print('hittin freeze')
								local player = game.Players:GetPlayerFromCharacter(taggedCharacter)
								if player and player.Team == game.Players:GetPlayerFromCharacter(character).Team then
									print('finished')
									tagging:FireClient(player, 'Unfreeze', player.Character, false)
									_G.giveStats(player, 'Give', true)
														
									local tagPlayer = game.Players:GetPlayerFromCharacter(character)
									if tagPlayer then
										updateTags:Fire(tagPlayer)
									end
								end		
								wait(0.1)
								debounce = false
							end
						end
					end
				end
			end
		end)
	end
end)

This is inside a PlayerAdded function, but there was a lot of code above and below the character added function, so yeah. Basically thereā€™s 2 sections to it. 1 is the tagging of players, the other is the untagging of players. Thatā€™s where I am getting my problems. When a player touches a tagged player it doesnā€™t work, and Iā€™ve put prints on every line and found the problem to lie on the if not debounce then line

And so the line that has print(debounce) prints true, when it should be printing false

I think the issue with the code is probably here in the untagging a player section:

if not debounce then
  debounce = true
  if hit and hit.Name == 'Freeze' then
     print('hittin freeze')

     [Other code]

     debounce = false
   end
end

Debounce is set to true outside the inner if statement but only set to false again inside the inner if statement. So if a part inside the character named other than ā€œFreezeā€ is touched, debounce will become true but never false again.

It canā€™t be there, as the line above the if not debounce is a print, and I print(debounce) and it prints to true all the time. So basically if not true then, well itā€™s true, so it wonā€™t continue. Should I move the debounce to after that though as well just to make sure?

You should move the debounce = false line to outer condition. E.g

if not debounce then
  debounce = true
  if hit and hit.Name == 'Freeze' then
     print('hittin freeze')

     [Other code]
   end
   debounce = false
end

The key idea is you want to reset the debounce to false in every codepath where it is set to true.

local humanoidRootPart = character:FindFirstChild('HumanoidRootPart')
		humanoidRootPart.Touched:Connect(function(hit)
			if active.Value then
				print('active')
				local taggedCharacter = hit.Parent
				print(taggedCharacter)
				if taggedCharacter and not taggedCharacter:FindFirstChild('Frozen') then
					-- Tagging player
					local humanoid = taggedCharacter:FindFirstChild('Humanoid')
					if humanoid then
						if player.Team == teams.Red then
							local player = game.Players:GetPlayerFromCharacter(taggedCharacter)
							if player and player.Team == teams.Blue then 
								if selectedGamemode.Name == 'Classic' then
									if not debounce then
										debounce = true
										local hasPass = false
										
										taggedCharacter.Humanoid.WalkSpeed = 0					
										taggedCharacter.Humanoid.JumpPower = 0	
										taggedCharacter.HumanoidRootPart.Anchored = true
										
										if marketplaceService:UserOwnsGamePassAsync(game.Players:GetPlayerFromCharacter(taggedCharacter).UserId, rainbowIceID.Value) then
											hasPass = true
										end
										
										tagging:FireAllClients('Tagging', taggedCharacter, hasPass)
										
										local frozen = Instance.new('BoolValue')
										frozen.Name = 'Frozen'
										frozen.Parent = taggedCharacter
																
										local tagPlayer = game.Players:GetPlayerFromCharacter(character)
										if tagPlayer then
											updateTags:Fire(tagPlayer)
										end
										wait(0.1)
										debounce = false
									end		
								end
							end
						end
					end
				elseif taggedCharacter and taggedCharacter:FindFirstChild('Frozen') then
					print('1')
					-- Untagging player
					local humanoid = taggedCharacter:FindFirstChild('Humanoid')
					if humanoid then
						print(hit.Name)
						if hit and hit.Name == 'Freeze' then
							print('is freeze')
							if not debounce then
								print('after debounce')
								debounce = true
								local player = game.Players:GetPlayerFromCharacter(taggedCharacter)
								if player and player.Team == game.Players:GetPlayerFromCharacter(character).Team then
									tagging:FireClient(player, 'Unfreeze', player.Character, false)
									_G.giveStats(player, 'Give', true)
														
									local tagPlayer = game.Players:GetPlayerFromCharacter(character)
									if tagPlayer then
										updateTags:Fire(tagPlayer)
									end
								end		
								wait(0.1)
								debounce = false
							end
						end
					end
				end
			end
		end)

Here it is edited up and done some testing. Noticed that if a player it tagging a player, it also seems the run the untagging section of the script (the elseif part) which should only run if the player has been tagged

I think one thing that makes this hard to debug is the fact that the debounce is checked very late, so there are multiple overlapping calls making prints.

I would refactor it to something like:

humanoidRootPart.Touched:Connect(function(hit)
  if debounce then 
    return
  end
  debounce = true

  if active.Value then
  --- Rest of code here
  end

 debounce = false
end)

This should allow you to more easily keep track of what is going on, because only one set of prints of the function will happen at once. (Right now a lot of the function will print stuff while checking conditions even though it wonā€™t progress to actually do anything because of the debounce).

One other thing I noticed is you never remove the Frozen BoolValue in the untagging section and I think this might also be the cause of some problems.

I do, itā€™s through the client though, when I fire the tagging event. I thought it should be done through the server, but was told to do it through client so :man_shrugging: but the script never gets down that far anyway

local humanoidRootPart = character:FindFirstChild('HumanoidRootPart')
		humanoidRootPart.Touched:Connect(function(hit)
			if debounce then 
		    	return
			end
			
		  	debounce = true
			
			if active.Value then
				local taggedCharacter = hit.Parent
				if taggedCharacter and not taggedCharacter:FindFirstChild('Frozen') then
					-- Do the tagging stuff (this part is fine, so removing it just to keep things clean)
				elseif taggedCharacter then
					-- Untagging player
					print('423')
					local player = game.Players:GetPlayerFromCharacter(taggedCharacter)
					if player and player.Team == game.Players:GetPlayerFromCharacter(character).Team then
						print('runners teamate')
						if taggedCharacter and taggedCharacter:FindFirstChild('Frozen') then
							print('1')
							local humanoid = taggedCharacter:FindFirstChild('Humanoid')
							if humanoid then
								print(hit.Name)
								
								tagging:FireClient(player, 'Unfreeze', player.Character, false)
								_G.giveStats(player, 'Give', true)
													
								local tagPlayer = game.Players:GetPlayerFromCharacter(character)
								if tagPlayer then
									updateTags:Fire(tagPlayer)
								end
							end
						end
					end
				end
			end
			wait(0.1)
			debounce = false
		end)

Updated what Iā€™ve got and still getting no where. The print(432) doesnā€™t ever seem to print, and Iā€™m completely confused because I was printing taggedCharacter above it and it was printing something there, so it isnā€™t nil

EDIT Nvm, it is printing the 423, even if the player is a tagger though, but nothing after that

The localscript

tagging.OnClientEvent:Connect(function(tagType, character, hasPass)
	if tagType == 'Tagging' then
		for _, player in pairs(game.Players:GetChildren()) do
			character.Humanoid.WalkSpeed = 0					
			character.Humanoid.JumpPower = 0	
			character.HumanoidRootPart.Anchored = true
										
			local freezePart = Instance.new('Part')
			freezePart.BrickColor = BrickColor.new('Cyan')
			freezePart.Material = 'Ice'
			freezePart.Transparency = 0.25
			freezePart.Name = 'Freeze'
			freezePart.Anchored = true
			freezePart.Size = Vector3.new(5, 5.5, 4)
			freezePart.CFrame = character.HumanoidRootPart.CFrame	
			if hasPass then
				spawn(function()
					while wait(0.15) do
						freezePart.BrickColor = BrickColor.Random()
					end
				end)
			end
			freezePart.Parent = character
		end
	else
		for _, player in pairs(game.Players:GetChildren()) do
			local freeze = character:FindFirstChild('Freeze')
			if freeze then
				character.Freeze:Destroy()
			end
			local frozen = character:FindFirstChild('Frozen')
			if frozen then
				character.Frozen:Destroy()
			end
		end
	end
end)

Have you stepped through your code with break points? That should be your first step.

1 Like

Kind of hard to analyze on mobile, but this function will fire whenever the HumanoidRootPart is touched, meaning that even though you have a wait(1) before setting debounce to false again, that will be essentially ignored.

Not really. Yes it will fire constantly but if debounce is true then it just gets returned and does nothing.