By @epicalyepik
This module was created to provide a simple, structured, and signal-based cooldown system with optional client replication.
This is my first open source resource, so if you have any suggestions, I’d love to hear them
Highlighted features
- Thread-safe implementation
- Automatic cooldown expiration
- Signals for cooldown Started / Updated / Ended
- Client-side replication support
- Easy cooldown checking
- Support for default cooldown durations
- Duration multiplier
- Automatic signal cleanup after cooldown ends
Cooldown Object (Server)
Key — unique string identifier for a cooldown (e.g. ability name).
CooldownObjectModule.new(Player : Player?)
Creates a new cooldown object. The player variable is completely optional, and it’s only used for client communication
Recommended usage: One CooldownObject per Player or NonPlayer entity.
CooldownObject.Defaults
You can set this to a custom table with this format:
CooldownObject.Defaults = {
[Key]: Duration(number)
}
Code Example
Object.Defaults = {
["Slap"] = 2
}
Object:set("Slap")
--Slap will be on cooldown for 2 seconds
CooldownObject(Key) / CooldownObject:get(Key)
Both do the same; they return True if there’s a cooldown active for Key
get(Key) avoids metatable call overhead and is slightly faster
CooldownObject:set(Key, Duration?)
Puts the key in cooldown for Duration or Default duration (if previously set)
You can also overwrite active cooldowns with this
Special values:
Duration = 0→ clears immediatelyDuration = -1→ infinite cooldown
CooldownObject:SignalGet(Key)
Returns cooldown Ended signal for key or nil if key isn’t in cooldown
CooldownObject:InfoGet(Key)
Returns the cooldown information:
{StartTime: number, Length: number, Ended: Signal}
or nil if key isn’t in cooldown
CooldownObject:SetMultiplier(number)
Sets the cooldown object’s Duration multiplier, and the next cooldowns will have their duration multiplied.
CooldownObject:GetMultiplier()
Returns the current duration multiplier
CooldownObject:Destroy()
Deletes all cooldowns without firing signals and disconnects all internal connections.
Client (Inside CooldownObject module)
Client.CooldownStarted
Signal fired when a cooldown starts
Argument given
{
Key: string,
Length: number,
StartTime: number,
Ended: Signal -- fired when cooldown ends
Updated: Signal -- fired when cooldown is overwritten, it also sends as an argument an updated version of this table.
}
Client.GetMultiplier()
Returns the current cooldown duration multiplier
Client(Key) | Client.get(Key)
Returns true if Key is in cooldown
Code examples
Server
local cooldowns = CooldownObject.new(player)
cooldowns:set("Dash", 3)
if cooldowns("Dash") then
print("Dash is on cooldown")
end
Client
CooldownObjectClient.CooldownStarted:Connect(function(Cooldown)
print("Cooldown started with key "..Cooldown.Key.." length "..Cooldown.Length.." at: "..Cooldown.StartTime)
Cooldown.Ended:Once(function()
print("Cooldown "..Cooldown.Key.." ended")
end)
Cooldown.Updated:Once(function()
print("Cooldown "..Cooldown.Key.." overwritten")
end)
end)
And that’s about it. Please let me know how you like the system. I’ll be updating it occasionally if I find the time.