Better way of using debounce in server script?

Hi, I’ve been wondering the best way to handle debounces on server scripts. I tested if wait() affected everyone on a server, and as I expected, it did. I read in another post that wasn’t related to my situation to use an array debounce that still uses wait, so I modified to use the player instance and os.time(). Does anyone know how the more popular games go about it or best practice? thank you for any feedback. Also, I ahve no clue how to get a rbxl file, so Ill just post the code below.

DataStore = require(game.ReplicatedStorage.DataManager)

Players = game:GetService('Players')

local part = script.Parent
local debouceList = {}

...

function Debouce(touchedPart)
	local player = Players:GetPlayerFromCharacter(touchedPart.Parent)
	
	if player then
		local entry = debouceList[player]
		local currentTime = os.time()
		
		if entry then
			if currentTime - entry >= 1 then
				debouceList[player] = currentTime
				Work(player)
			end
		else
			debouceList[player] = currentTime
			Work(player)
		end
	end
end

part.Touched:Connect(Debouce)

Kinda confused on what you mean, but this would be my implementation of it

local Players = game:GetService("Players");

local debounceList = {};
local debounceTime = 2;

part.Touched:Connect(function(touchedPart)
    local player = Players:GetPlayerFromCharacter(touchedPart.Parent)
    
    if player and not debounceList[player] then -- check if it's a player and that they aren't in debounce
        debounceList[player] = true; -- create the debounce
        pcall(function() -- safe calling just in case
            Work(player);
        end)
        wait(debounceTime); -- wait delay
        debounceList[player] = false; -- no more debounce
    end
end

Pretty simple, no need to use os.time() which can get confusing.

I meant that having a wait() in a server script yields the script for everyone, unlike local scripts.

local Players = game:GetService("Players")

local debounceList = {}
local debounceTime = 2

part.Touched:Connect(function(touchedPart)
    local player = Players:GetPlayerFromCharacter(touchedPart.Parent)

    if player and not debounceList[player] then -- check if it's a player and that they aren't in debounce
        debounceList[player] = true -- create the debounce

        pcall(function() -- safe calling just in case
            Work(player)
        end)

        task.delay(debounceTime, function()
            debounceList[player] = false -- no more debounce
        end)
    end
end

create a new thread then

EDIT: I used task.delay instead

In certain instances yes, however since we are using part.Touched it spawns a new function each time

anyone know the point of the pcall? im missing something

A pcall is a error handling thing and prevents the rest of your code crashing

An example can be used for Roblox APIs (such as data storing using the SetAsync() as they could fail randomly) but for now ill just make you a example to get a userID from a string that could be a player

local Plrs = game:GetService("Players")
local usernameExample = "Emilisyaye" --// say I wanna get this userID from this string that could be a player

local success, result = pcall(function() --// success is a boolean value while result is well, the result.
	return Plrs:GetUserIdFromNameAsync(usernameExample)
end)

if success then
	print(`Got a user ID! its {result}`)
else
	warn("Issue! Continuing on as nil.")
end

This is way better rather than just doing Plrs:GetUserIdFromNameAsync("emilisyaye") because if that fails (like if the user is not even a Roblox user) then the rest of your code crashes along

1 Like