Preventing spam for task.wait()

I’ve found a possible solution.
Here’s an example of what I mean:

local tagger

if not tagger then
	task.wait(3)
	--do what you want
	tagger = nil
end

This will only work if tagger does not exist, meaning that only one player will be able to tag them.

The player being damaged will have the tag.
So that wouldn’t make sense.

meaning that only one player will be able to tag them.

That’s what I didn’t want. But I have come to fear that this might be the only solution, even before I posted.

Oh. Then, you might be able to use table.find() with a table of tagger players stored:

local taggers = {}

if not table.find(taggers, tagger) then
	table.insert(taggers, tagger)
	--do code here
	task.wait(3)
	taggers = {}
end

That also means that they cannot tag them again before it expires, which is still preventing them from tagging.

In cases where there are 2 players chasing them, this wouldn’t work.

Okay then. I’ll just focus on preventing the bug, since I have no idea how the tagging thing will work:

local debounce = true
local taggers = {}

if not table.find(taggers, tagger) then
	table.insert(taggers, tagger)
	if debounce then
		debounce = false
		--do code here
		task.wait(3)
		taggers = {}
		debounce = true
	end
end

That doesn’t work either.
So I have no idea.

Well, your task.wait() spam should be fixed with it.

Not sure about your tagging system, though.

Yeah but still, only 1 can tag the player at a time, which is another issue.

You could try storing the timestamp of when they were last tagged and if it is old enough, let them leave combat. Or move the tag tracking into a single script so that you can properly terminate threads when they are no longer needed.

Of course, it would help if you told us what you needed this for. It seems like you just need it for checking if they are in combat, in which case you could just use the timestamp approach.

I don’t even know what you’re trying to achieve at this point

You can look for the tag, if it exists than change its value if not than create a new one.

The tag is created when the player joins, it’s never deleted, and I only run into the same issue when removing it again if I’m gonna do what you suggest.

1 Like

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!