Help with debounce in this script

I was wondering if someone can show me how to correctly debounce this script? Or does canGive do the same thing?

Basically this script picks up items off a shop table. If you spam click the button, it breaks the script and nobody can get the item until the server is reset. I think a debounce will fix this maybe?

I am new to scripting and I can debounce simple scripts, but I am not sure where exactly to put it in this one.

local ClickDetector = script.Parent.ClickDetector
local canGiveGun = true
local sound = script.Parent.Buy

ClickDetector.MouseClick:Connect(function(player)
	local backpack = player.Backpack
	local Gun = game.ServerStorage.Equipment["Elf Bow"]

	if player.leaderstats.Gold.Value >= script.Parent.Gold.Value then
		for i,v in pairs(backpack:GetChildren()) do
			if v.Name == "Elf Bow" then
				canGiveGun = false
			end
		end
		if canGiveGun then
			local gunClone = Gun:Clone()
			gunClone.Parent = backpack
			sound:Play()
			player.leaderstats.Gold.Value = player.leaderstats.Gold.Value - script.Parent.Gold.Value
			canGiveGun = true
		end
	end
end) 

I am testing various positions right now.

Here is my latest attempt.

local ClickDetector = script.Parent.ClickDetector
local canGiveGun = true
local sound = script.Parent.Buy
local debounce = false

ClickDetector.MouseClick:Connect(function(player)
	local backpack = player.Backpack
	local Gun = game.ServerStorage.Equipment["Elf Bow"]
	
	if debounce then return end
	
	debounce = true
	
	if player.leaderstats.Gold.Value >= script.Parent.Gold.Value then
		for i,v in pairs(backpack:GetChildren()) do
			if v.Name == "Elf Bow" then
				canGiveGun = false
			end
		end
		if canGiveGun then
			local gunClone = Gun:Clone()
			gunClone.Parent = backpack
			sound:Play()
			player.leaderstats.Gold.Value = player.leaderstats.Gold.Value - script.Parent.Gold.Value
			canGiveGun = true
			
			debounce = false
			
		end
	end
end) 

Hows this look?

The issue is, it will immediatly turn the Debounce off, so add like a wait(5) before setting the debounce to true

It looks like “canGiveGun” is already debouncing for you so the extra debounce is not necessary.

I think your issue might lie on the if canGiveGun statement:

For some reason, you’re setting canGiveGun to true after the gun is given…which…unless there’s a purposeful intention…doesn’t make much sense.

Try setting “canGiveGun” to false instead in that area of the script and see if it works.

Didnt make a difference. The problem is the script works perfectly, unless you spam click the item. Then it breaks the script and wont work next time. If you click once, it works forever perfectly.

On which script. The first or the second?

The debounce would still be good because someone can spam the button before the function completes. This version is assuming you don’t want to give the player the gun if they have an Elf Bow in their backpack.

local ClickDetector = script.Parent.ClickDetector
local sound = script.Parent.Buy
local debounce = false

ClickDetector.MouseClick:Connect(function(player)
	local backpack = player.Backpack
	local Gun = game.ServerStorage.Equipment["Elf Bow"]
	
	if not debounce then
	
		debounce = true
		
		local canGiveGun = true
		if player.leaderstats.Gold.Value >= script.Parent.Gold.Value then
			for i,v in pairs(backpack:GetChildren()) do
				if v.Name == "Elf Bow" then
					canGiveGun = false
				end
			end
			if canGiveGun then
				local gunClone = Gun:Clone()
				gunClone.Parent = backpack
				sound:Play()
				player.leaderstats.Gold.Value = player.leaderstats.Gold.Value - script.Parent.Gold.Value
			end
		end

		task.wait(2)
		debounce = false
	end
end) 
1 Like

You are a champion among men. This works perfect. I tried my hardest to break it with spamming and it still works fine.

1 Like

Glad it works! I hope you don’t mind… I peeked at the code again and noticed that the “gun” is actually the Elf Bow. So, I made some changes that should improve the code a bit.

local TOOL_NAME = "Elf Bow"
local Gun = game.ServerStorage.Equipment[TOOL_NAME]
local ClickDetector = script.Parent.ClickDetector
local sound = script.Parent.Buy
local debounce = false

ClickDetector.MouseClick:Connect(function(player)
	local backpack = player.Backpack
	
	if not debounce then
		debounce = true
		
		local canGiveGun = true
		if player.leaderstats.Gold.Value >= script.Parent.Gold.Value then
			-- Check if tool is already in backpack; if not, then add it
			if not backpack:FindFirstChild(TOOL_NAME) then
				local gunClone = Gun:Clone()
				gunClone.Parent = backpack
				sound:Play()
				player.leaderstats.Gold.Value = player.leaderstats.Gold.Value - script.Parent.Gold.Value
			end
		end

		task.wait(2)
		debounce = false
	end
end) 

Hopefully this didn’t break anything since I can’t actually run the code to test it. But I tried to be careful when refactoring it. You can also rename “gun” to “tool” to make it less misleading if you want.

Yeah I have a bunch of tools in the game and just change their name in the code. I just left Elf Bow in that code when I copied it over.

Thanks for the help.

No problem. In that case, using a variable like TOOL_NAME in the last example would help so you only have to change the name in one place. Just the little things to make our lives easier.

Oh yeah a variable for tool name would have just saved me a bunch of time. I changed the names twice per script like 15 times. haha.

When I stare at code for hours I can barely think anymore. And being a new coder im surprised I am not brain dead when I got back to my real job.

1 Like