so if I have a remote called print and if you execute it from the localscript it prints out whatever the argument is, how would I make the remote usable only once every second using the server script?
Keep track of the last moment the remote was fired on the server. Compare the last time a specific client fired the server event, and if it's past or equal to some cooldown, allow the code to execute.
local PlayerService = game:GetService("Players") local REMOTE_COOLDOWN = 1 local ClientEventHistory = {} remote.OnServerEvent:Connect(function(client, ...) local lastFiredFromClient = ClientEventHistory[client] local now = tick() if now - lastFiredFromClient >= eventCooldown then print(...) -- print args or do code ClientEventHistory[client] = now end end) Players.PlayerAdded:Connect(function(player) ClientEventHistory[player] = 0 end) Players.PlayerRemoving(function(player) ClientEventHistory[player] = nil end)
You can handle this procedure on the client as well. In fact, depending on your circumstance, I may recommend doing this on the client instead. Handling this on the server is more of a safety net than anything else. The con of explicitly handling this on the client, is of course, the client can be exploited to bypass the cooldown by just firing the remote event.
Do this on the client if you expect this remote to be fired rapidly so that you're not using bandwidth by sending so many requests (although, if you're firing a remote so rapidly that you need to set a cooldown in place, there is probably a bigger design flaw at hand). Do this on the server if you're worried that an exploiter may be firing a remote within an interval that it's not supposed to be fired.
For this, you need a server-side debounce
.
There are two approaches to this:
Global Debounce
Server:
local rep = game:GetService("ReplicatedStorage") local printRE = rep:WaitForChild("PrintRE") local debounce printRE.OnServerEvent:Connect(function(player, msg) if not debounce then debounce = true print("SERVER: "..msg) wait(1) debounce = false else print("SERVER DEBOUNCE") end end)
Player Debounce
local rep = game:GetService("ReplicatedStorage") local printRE = rep:WaitForChild("PrintRE") local debounce = {} printRE.OnServerEvent:Connect(function(player, msg) local name = player.Name if not debounce[name] then debounce[name] = true print(name..": "..msg) wait(1) debounce[name] = false else print(name.." has been debounced, please wait a second and try again.") end end) game:GetService("Players").PlayerRemoving:Connect(function(player) debounce[player.Name] = nil end)