Preventing spam for task.wait()

Tag player

wait(seconds)

Untag player

The issue is that it can be spammed, which means the script will spam tag, untag, tag, untag because of it, then it bugs out the system

Mimic the tried and tested method that gears use, ObjectValue instances, and use Debris:AddItem() to clean up expired tags (as opposed to yielding the thread).

1 way I use to add some kind of “debounce” system for remote events is by using 2 tables and a coroutine. This method was inspired by @Volieb in this thread: Roblox data store broken. Random players losing their stats every server shutdown - #30 by Volieb

Basically how it works is that there is 2 tables (or dictionaries), one for the player’s cooldown, and another for the player’s coroutine.
So when a player joins, a coroutine while loop will start where it will reset the player’s cooldown for every x amount of seconds, and will keep going until the player leaves.

Here’s an example:

local remoteEvent = Path.To.RemoteEvent.Here
local PlayerCooldown = {}
local PlayerCoroutines = {}
local cooldown = 3 --In seconds
game.Players.PlayerAdded:Connect(function(plr)
        PlayerCooldown[plr.Name] = 0
        PlayerCoroutines[plr.Name] = coroutine.wrap(function()
                  while task.wait(cooldown) do
                         PlayerCooldown[plr.Name] = 0
                  end
         end)
         PlayerCoroutines[plr.Name]()
end)
remoteEvent.OnServerEvent:Connect(function(plr)
            if PlayerCooldown[plr.Name] == 0 then
                    PlayerCooldown[plr.Name] = 1
                    --your script here
            end
end)
game.Players.PlayerRemoving:Connect(function(player)
    PlayerCooldown[player.Name] = nil
	coroutine.yield(PlayerCoroutines[player.Name])
	PlayerCoroutines[player.Name] = nil
end)

This is way better than debounce, as server-side debounces is a global cooldown, meaning that everyone would have the cooldown if 1 player were to do something that would trigger the cooldown.

1 Like

I see what you mean, but how can I tell which tag is which for my script?
How can the script know who to award the kills to if there are 100 tags?

The approach used by gears is that they destroy any existing tag and replace it with a new tag.

OldTag:Destroy()
local NewTag = Instance.new("ObjectValue")
--Assign 'NewTag' properties.
Debris:AddItem(NewTag, 3) --Schedule for tag to be destroyed in three seconds.
1 Like

Yes that works, but what if there are like 5 tags when the player die, how does it know who to give the kill to, the one that last tagged the person or someone completely random? I see that the object values stack in studio testing.

Nevermind about that, I didn’t see that you destroyed the old tag, I’ll just need to see if it exists, then destroy it.
Thanks!