What is the best method in implement a debounce?

The cleanest way would be to use the functions meant to handle tables, such as table.insert, table.remove and table.find, in my opinion.

Here’s an example:

local Debounces = {}

if (table.find(Debounces, Player.UserId)) -- Check if player is already in the table.
then return end -- Return end if they already exist.

table.insert(Debounces, Player.UserId) -- Add player.
table.remove(Debounces, table.find(Debounces, Player.UserId)) -- Remove player.
1 Like

I already use this on my module script

function busHandler:AddPlayer(PlayersTable, Player)
	local CurrentTable = PlayersTable
	table.insert(CurrentTable, Player.Name)
	return CurrentTable
end

function busHandler:RemovePlayer(PlayersTable, Player)
	local CurrentTable = PlayersTable
	local Check = table.find(CurrentTable, Player.Name)
	if Check then
		table.remove(CurrentTable, Check)
		return CurrentTable
	end
	
end

Then that’s good, I see no room for improvements if that’s what you already have.

It seems I didn’t quite portray a better explanation of the problem. As I said I need to find a way to prevent players from Listing and Un-listing immediately. Since I want the players to get inside and had to touch the door again to get out.

And I didn’t want to use delay or wait() to fix this since it is not consistent.

There’s nothing wrong with wait() in this case, it will work as intended if implemented correctly.

1 Like

Use a global debounce for both for listing and un-listing method. Don’t define it within the method but rather within the global scope of the script.

This still uses wait(n) :frowning:

this is my preferred method as I don’t use wait in script

local debounceTable = {}

local function coolDown(plr, second)
	if debounceTable[plr.UserId] == nil then
		debounceTable[plr.UserId] = os.time()

		return true
	else
		if os.time() - debounceTable[plr.UserId] >= second then
			debounceTable[plr.UserId] = os.time()

			return true
		else
			return false
		end
	end
end

if coolDown(Player, 1) then
	-- do staff here
else
	print("please wait for cooldown")
end

I tried making a delay on a module script so each bus can share it is this consistent?

local COUNT_DOWN_TIME = 0.5

local busHandler = {}

function busHandler:Cooldown(Event)
	delay(COUNT_DOWN_TIME, function()
		Event:Fire()
	end)
end

But why os.time(). It works but wait() is more than sufficient for this. Over complicating things, somewhat

I don’t see why it would cause any issues.
delay is used for, as the name implies, to delay the call of the function provided given for the given amount of seconds, without interrupting the current thread.

I read something on another thread that sometimes when using delay or wait() too much on a script it can throttle and produce weird unwanted bugs.

If there is a code after the wait function and that code must run without waiting
How do you do this with the wait function ?

Specially, for me is I have multiple bus to put in the game.

The safest approach here would be wait(n) as it will yield the current thread instead of running anything below in the meantime (such as delay).

But that doesn’t happen. A new thread is created when the function is called. It’ll still pause for a certain amount of time before setting the player within the player array to nil.

local playerList = {}



-- Function goes here but can stil be called even when waiting
if (not playerList[player] == player) then
	playerList[player] = player
	
	-- Code
	wait(2) -- Will wait
	playerList[player] = nil
end

have you tried my method?

30

this will work fine
but the wait function will stop the entire work of the script

True, you could wrap that in a coroutine.

1 Like