local players = game:GetService('Players')
local cooldown = {} allCooldowns = {}
players.PlayerRemoving:Connect(function(player)
if not allCooldowns[player] then return end
for i, v in pairs(allCooldowns[player]) do
cooldown.Rem(player, i)
end
allCooldowns[player] = nil
end)
function cooldown.new(player: Player, move: string, duration: number)
allCooldowns[player] = allCooldowns[player] or {}
allCooldowns[player][move] = allCooldowns[player][move] or {}
local cd = allCooldowns[player][move]
cd._start = tick() cd._duration = duration
end
function cooldown.Has(player: Player, move: string)
if not allCooldowns[player] then
return false
end
for i, v in pairs(allCooldowns[player]) do
if tick() - v._start > v._duration then
cooldown.Rem(player, i)
end
end
return not not allCooldowns[player][move]
end
function cooldown.All(player: Player, move: string)
local returns = {}
if not allCooldowns[player] then
return returns
end
for i, v in pairs(allCooldowns[player]) do
if tick() - v._start > v._duration then
cooldown.Rem(player, i) continue
end
table.insert(returns, i)
end
return returns
end
function cooldown.Rem(player: Player, move: string)
if not allCooldowns[player] then return end
allCooldowns[player][move] = nil
end
return cooldown
Is there any way I can make this more perfromant/efficient? Is it well scripted? Is the system I’m using the best way to do it? If not, what is a better way of doing this? (Combat game with 30 max players)
Your code looks good and well-structured, and it should perform well under normal circumstances with up to 30 players.
However, because you asked for some improvements, here are some of my suggestions.
Localizing global functions: In Lua, localizing global functions can improve performance. It means storing a reference to a global function/variable in a local variable for faster access. For example, you’re using pairs() and tick() multiple times, it would be more efficient to localize them.
local pairs = pairs
local tick = tick
Avoid unnecessary table operations: In the Has and All functions, you’re iterating through all the cooldowns, even if the specific move you’re interested in isn’t on cooldown. Instead, you could directly access the specific move and check if it’s on cooldown.
Avoid creating tables unnecessarily: In your All function, you’re creating an empty table for returns even if there are no cooldowns for the player. You could instead return an empty table literal if there are no cooldowns for the player.
Use os.clock() instead of tick(): tick() is more accurate than os.clock() but it can be slower due to its precision. If you don’t need that level of precision, os.clock() can be a faster option.
Avoid unnecessary function calls: In the PlayerRemoving event, you’re calling cooldown.Rem() for each cooldown, which is unnecessary because you’re setting allCooldowns[player] to nil anyway. You could just set allCooldowns[player] to nil without calling cooldown.Rem().
Here’s a version of your script with these optimizations:
local players = game:GetService('Players')
local pairs = pairs
local os_clock = os.clock
local cooldown = {}
local allCooldowns = {}
players.PlayerRemoving:Connect(function(player)
allCooldowns[player] = nil
end)
function cooldown.new(player, move, duration)
local playerCooldowns = allCooldowns[player] or {}
playerCooldowns[move] = {_start = os_clock(), _duration = duration}
allCooldowns[player] = playerCooldowns
end
function cooldown.Has(player, move)
local playerCooldowns = allCooldowns[player]
if playerCooldowns then
local moveCooldown = playerCooldowns[move]
if moveCooldown and os_clock() - moveCooldown._start > moveCooldown._duration then
playerCooldowns[move] = nil
return false
end
return moveCooldown ~= nil
end
return false
end
function cooldown.All(player)
local playerCooldowns = allCooldowns[player]
if playerCooldowns then
local returns = {}
for move, cooldown in pairs(playerCooldowns) do
if os_clock() - cooldown._start > cooldown._duration then
playerCooldowns[move] = nil
else
table.insert(returns, move)
end
end
return returns
end
return {}
end
function cooldown.Rem(player, move)
if allCooldowns[player] then
allCooldowns[player][move] = nil
end
end
return cooldown
Thanks for at least replying but I’ve already asked ChatGPT and recognize the answers. I have already drastically improved the module and am thinking about adding a heap system to better expire cooldowns with great performance.