How to make a gun debounce on the server so it's not exploitable?

So I want a debounce that waits the firerate of the weapon but for each player can anyone help?
I have tried to make one but its just not working.

For example after this the gun would be able to shoot again: wait(game.ServerStorage.Guns[gun.Name].Stats.Firerate.Value)

What’s not working? Show your full code or people won’t be able to help you fix it.

1 Like
delay(game.ServerStorage.Guns[game.Name].Stats.Firerate.Value, function()
    db = true
end

fixed layout

local rs = game:GetService("ReplicatedStorage")
rs.Events.Shoot.OnServerInvoke = function(plr,gun,target)
	if gun and gun.Handle and target and game.ServerStorage.Guns:FindFirstChild(gun.Name) and (gun.Handle.Position - target.Position).Magnitude < game.ServerStorage.Guns[gun.Name].Stats.Range.Value then
       	 if target.Parent then 
            if gun.Handle:FindFirstChild("Sound") then
                gun.Handle.Sound:Play()
           	end
			if target.Parent:FindFirstChild("Humanoid") then
           target.Parent.Humanoid:TakeDamage(game.ServerStorage.Guns[gun.Name].Stats.Damage.Value)
			end
            wait(game.ServerStorage.Guns[gun.Name].Stats.Firerate.Value)
        end
    end
end
1 Like

Throw your code in code blocks, like this:

```
-- code here
```

This adds the player to a debounce table, and checks if they are debounced sets it to false and sets it to true. Effectively working like local debounce, but on a script that is used throughout the game.

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local debounce = {}
ReplicatedStorage.Events.Shoot.OnServerInvoke = function(plr,gun,target) 
	 if debounce[plr.Name] == nil then
	 	 debounce[plr.Name] = true
	 end
	 if not debounce[plr.Name] then 
	 	 return
	 end
	 if gun and gun.Handle and target and game.ServerStorage.Guns:FindFirstChild(gun.Name) and (gun.Handle.Position - target.Position).Magnitude < game.ServerStorage.Guns[gun.Name].Stats.Range.Value then 
	 	 debounce[plr.Name] = false
	 	 if target.Parent then 
	 	 	 if gun.Handle:FindFirstChild("Sound") then 
	 	 	 	 gun.Handle.Sound:Play() 
	 	 	 end 
	 	 	 if target.Parent:FindFirstChild("Humanoid") then 
	 	 	 	 target.Parent.Humanoid:TakeDamage(game.ServerStorage.Guns[gun.Name].Stats.Damage.Value)
	 	 	 end
	 	 	delay(game.ServerStorage.Guns[gun.Name].Stats.Firerate.Value, function()
	 	 	 	 debounce[plr.Name] = true
	 	 	 end)
	 	 end
	 end
end
2 Likes

Well, you could have a db table which has the __index set to true for players which don’t exist yet in the table:

local tbl = setmetatable({}, {
    __index = true
})

Then OnServerInvoke set their db false if it’s true, wait the firerate and then set it true again:

if tbl[plr.UserId] then
    tbl[plr.UserId] = false
    --whatever code you need to run
    wait(game.ServerStorage.Guns[gun.Name].Stats.Firerate.Value)
    tbl[plr.UserId] = true
end
1 Like

Using what he said, he can make use of what I made in a very nice fashion.

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local debounce = setmetatable({}, {
	__index = true
})

function ReplicatedStorage.Events.Shoot.OnServerInvoke(plr, gun, target) 
	 if not debounce[plr.UserId] then 
	 	 return
	 end
	 if gun and gun.Handle and target and game.ServerStorage.Guns:FindFirstChild(gun.Name) and (gun.Handle.Position - target.Position).Magnitude < game.ServerStorage.Guns[gun.Name].Stats.Range.Value then 
	 	 debounce[plr.UserId] = false
	 	 if target.Parent then 
	 	 	 if gun.Handle:FindFirstChild("Sound") then 
	 	 	 	 gun.Handle.Sound:Play() 
	 	 	 end 
	 	 	 if target.Parent:FindFirstChild("Humanoid") then 
	 	 	 	 target.Parent.Humanoid:TakeDamage(game.ServerStorage.Guns[gun.Name].Stats.Damage.Value)
	 	 	 end
	 	 	 delay(game.ServerStorage.Guns[gun.Name].Stats.Firerate.Value, function()
	 	 	 	 debounce[plr.UserId] = true
	 	 	 end)
	 	 end
	 end
end
1 Like

so this part didn’t work for me did I put it in wrong? I put this here

rs.Events.Shoot.OnServerInvoke = function(plr,gun,target)
	if tbl[plr.UserId] then

You didn’t define tbl I’m assuming.

1 Like

line 6 didn’t work like his it errored

local rs = game:GetService("ReplicatedStorage")
local debounce = setmetatable({}, {
	__index = true
})
rs.Events.Shoot.OnServerInvoke = function(plr,gun,target)
	if not debounce[plr.Name] then 
	 	 return
	end
	if gun and gun.Handle and target and game.ServerStorage.Guns:FindFirstChild(gun.Name) and (gun.Handle.Position - target.Position).Magnitude < game.ServerStorage.Guns[gun.Name].Stats.Range.Value then 
		debounce[plr.Name] = false
		if target.Parent then 
	 		if gun.Handle:FindFirstChild("Sound") then 
	 	 		gun.Handle.Sound:Play() 
	 	 	end 
	 	 	if target.Parent:FindFirstChild("Humanoid") then 
	 	 	 	target.Parent.Humanoid:TakeDamage(game.ServerStorage.Guns[gun.Name].Stats.Damage.Value)
	 	 	end
	 	 	wait(game.ServerStorage.Guns[gun.Name].Stats.Firerate.Value)
			debounce[plr.Name] = true
	 	end
	end
end
``` I had this

Mind showing me it?

uggghhh 30chars

1 Like

Would checking if the key is a string work?

local debounce = setmetatable({}, {
    __index = function(self, key)
        if typeof(key) == "string" then
            return true
        end
    end
})
2 Likes

Ok so that worked thank you. I will use this in the future

1 Like