I have a very simple question. So currently, my combat system rely on client-sided debounce for more consistency. Though I believe it can lead to inaccuracies in some instances when the player has a high ping, the player finished the debounce before the server did any of its own actions.
Now my question is should I do the debounces on the client or on the server, or both ?
Example:
Client:
local db = false
function attack()
if not db then
db = true
someRemote:FireServer()
task.wait(1)
db = false
end
end
Server:
someRemote.onServerEvent:Connect(function(plr)
task.wait(1)
--* Do stuff here
end)
But I will still need a debounce on the client as there are still actions / effects spawned initially in it. Is it possible to sync those wait from 2 sides together ?
You would do it on the server, since the client isn’t synced correctly with the server so I would just have it fire a remote to the server and handle the actions from there. Of course if you need the client to do something use a remote function and then just return true or false if they are able to attack.
Perhaps a possible solution is to add a short debounce on the server and also check if the server debounce is active on the client.
local db = false
function attack()
if not db and character:GetAttribute("SDebounce") ~= true then
db = true
someRemote:FireServer()
task.wait(1)
db = false
end
end
-- server
someRemote.onServerEvent:Connect(function(plr)
if plr.Character:GetAttribute("SDebounce") == true then return end
plr.Character:SetAttribute("SDebounce", true)
task.delay(0.1, function()
plr.Character:SetAttribute("SDebounce", false)
end)
task.wait(1)
--* Do stuff here
end)
Keep the debounce on the client, but detect cheats on the server.
If the debounce is 5 seconds on the client, the server should detect if someone fires the event twice in 3 or 4 seconds. If they have, they’re obviously cheating. Kick them. This prevents them from spamming RemoteEvents, doesn’t require synchronization with the client debounce, and the looser margin for error is forgiving of latency and mistakes. A cheater isn’t going to spend the time testing the limits of the system, so you can afford to be lenient in your server side checks.
I recommend using a RemoteFunction as opposed to a RemoteEvent. Handle a debounce on the client which is set to true when called and false when a return value is made. On the server, handle another debounce and do your task.wait(1) there instead