Hey Robloxians!
I’ve just finished rewriting my old cooldown module from scratch, and I’m excited to share Cooldowns, a massive upgrade over my previous system. The old module is now officially deprecated (but still stable) as this new version is faster, scalable, more reliable, and packed with features that modern games need. Four years have passed, and my development skills have grown significantly since then, so this was a bit of a personal challenge!
What’s New?
-
Frame Accuracy - Heartbeat-driven updates
-
Precision Timing - No large inaccuracies (>0.01s, after initial load)
-
Time Scaling - Perfect for slow-mo/fast-forward abilities or engagement tricks
-
Thread Safe Callbacks - No more random errors breaking your game
-
Bulk Adjustments - Modify hundreds of cooldowns at once
-
Automatic Cleanup - Maid compatible
What Is This For?
-
MMO/RPG games - Handle thousands of player cooldowns smoothly
-
Competitive games - Frame accuracy for ability timings
-
Server systems - Prevent exploits with server-side debounces
What This Isn’t For
- Client-side UI - Use simple checks instead
Documentation on v1.0.1
Installation:
local Cooldowns = require(game.ReplicatedStorage.Cooldowns) --Provide the path or require(102608563980648)
local cooldown = Cooldowns.new()
API Reference:
Cooldowns Module Constants
| Constant | Default | Description |
|---|---|---|
MAX_UPDATES_PER_FRAME |
10000 | Caps how many cooldowns to process per frame to avoid lag spikes |
PRECISION_FACTOR |
0.01 | Switches to high-precision mode at 1% of the remaining duration |
MIN_PRECISION_TIME |
0.25 | Minimum seconds left before os.clock() precision kicks in (overrides PRECISION_FACTOR if longer) |
DEFAULT_TIME_SCALE |
1 | Baseline speed multiplier (1 = real time) |
MIN_TIME_SCALE |
0.01 | Hard limit for slow-mo (1% speed) to prevent unwanted behavior |
Cooldowns Methods
| Method | Description |
|---|---|
Cooldowns.new(name?) → CooldownInstance |
Creates new instance (or returns existing ones) |
Cooldowns.get(name) → CooldownInstance? |
Retrieves existing instance (else nil) |
Cooldown Instance Properties
| Property | Description |
|---|---|
useScaledTime (bool) |
When true, durations are auto-scaled by timeScale (defaults to true) |
timeScale (number) |
Current time scaling factor (write via SetTimeScale method) |
cooldownData (table) |
Contains keyNames with their respective cooldown entry |
Cooldown Instance Core Methods
| Method | Effect |
|---|---|
:Set(key, duration, callback?, ...) → bool |
Forces new cooldown (overwrites) |
:Add(key, duration, callback?, ...) → bool |
Only sets if key doesn’t exist |
:Check(key, scaled?) → (ready, timeLeft) |
Checks status, if exists returns false (scaled returns adjusted time) |
:Remove(key) → bool |
Removes specific cooldown |
:Reset() → bool |
Removes ALL cooldowns from cooldown instance |
Cooldown Instance Advanced Methods
| Method | Effect |
|---|---|
:Pause(key) → bool |
Freezes cooldown |
:Resume(key) → bool |
Unfreezes cooldown |
:SetTimeScale(scale) → bool |
Cooldown instance speed modifier (0.5 = 50% speed |
:AdjustDuration(key, amount) → bool |
Modifies single cooldown |
:AdjustAllDurations(amount, predicate?) → bool |
Bulk-modify cooldowns |
Note that most bool return values tell whether the method effect was successful or not unless stated otherwise.
Usage Examples:
1. Basic Ability Cooldown
local Cooldowns = require(game.ReplicatedStorage.Cooldowns)
local abilities = Cooldowns.new(player.Name)
--Check if the ability is available
local ready, remaining = abilities:Check("Fireball")
if ready then
--Add a fireball ability with 5 second cooldown
abilities:Add("Fireball", 5, function()
print("Fireball ready to cast again!")
end)
castFireball()
else
warn(string.format("Wait %.1f more seconds", remaining))
end
2. Weapon Reload System
local weapons = Cooldowns.new("Weapons")
function reloadWeapon(player)
if weapons:Add(player.UserId.."_Reload", 2.5) then
--Reload starts
playReloadAnimation()
else
--Already reloading
local _, timeLeft = weapons:Check(player.UserId.."_Reload", true)
player:SetAttribute("ReloadPct", (2.5 - timeLeft) / 2.5)
end
end
3. Slow-Mo Game Mode
local gameCooldowns = Cooldowns.new("GameEvents")
--Enable slow-mo (50% speed) for ALL cooldowns
gameCooldowns.useScaledTime = true
gameCooldowns:SetTimeScale(0.5)
--Boss attack that should run at normal speed
local bossAttacks = Cooldowns.new("BossAttacks")
bossAttacks.useScaledTime = false --Critical line!
bossAttacks:Set("Ultimate", 10, launchAttack)
4. Economy Throttling
local economy = Cooldowns.new("Economy")
function sellItem(player)
if not economy:Add(player.UserId.."_Sell", 1.0) then
return
end
--Process sale
end
5. Pause All Cooldowns
local function togglePauseAll(state)
for _, cooldown in pairs(Cooldowns.instances) do
if not cooldown.cooldownData then return end
for key in pairs(cooldown.cooldownData) do
if state then
cooldown:Pause(key)
else
cooldown:Resume(key)
end
end
end
end
6. Haste Potion Cooldown Reduction System
local Cooldowns = require(game.ReplicatedStorage.Cooldowns)
local abilities = Cooldowns.new("PlayerAbilities")
--Setup ability cooldowns
abilities:Set("Fireball", 10, nil, {tags = {"basic"}})
abilities:Set("Dash", 6, nil, {tags = {"basic"}})
abilities:Set("MeteorStrike", 20, nil, {tags = {"ultimate"}}) --Excluded from reduction
--Predicate: Identifies abilities affected by Haste Potion
local function isHasteEligible(entry)
local args = entry.arguments or {}
local tags = args[1] and args[1].tags or {}
return not table.find(tags, "ultimate") --Only reduce non-ultimate abilities
end
--Applies Haste Potion effect
local function applyHastePotion()
--Reduce eligible cooldowns by 3 seconds
local success = abilities:AdjustAllDurations(-3, isHasteEligible)
if success then
print("Haste applied! Basic abilities cooldowns reduced.")
--Verify Fireball's new cooldown
local _, remaining = abilities:Check("Fireball")
print("Fireball now has", remaining, "seconds remaining")
end
end
applyHastePotion()
GET MODULE HERE (v1.0.1) and say goodbye to cooldown headaches.
v1.0.0 Feedback
- Me likey

- Me no likey

Feedback Welcome! (v1.0.1)
Found a bug or got a suggestion? lmk! (I haven’t tested it much yet)
Drop a comment if you have found use for it in your game ![]()
- Me likey

- Me no likey


