Skip to main content

Pulse.Cooldown

Pulse.Cooldown prevents actions from happening too frequently. There are two variants: a single shared cooldown, and a per-entity cooldown where each entity tracks its own timer.


Single cooldown

local cd = Pulse.Cooldown.new(1.0) -- 1 second

cd:ready() -- → bool: has the cooldown expired?
cd:use() -- start the timer
cd:reset() -- mark as ready immediately
cd:set(dur) -- change duration

Pattern:

if cd:ready() then
cd:use()
-- do the action
end

Per-entity cooldown

One timer per entity. Use when each target needs independent rate limiting:

local pcd = Pulse.Cooldown.perEntity(0.5)

pcd:ready(entity) -- is this entity's cooldown expired?
pcd:use(entity) -- start this entity's timer
pcd:reset(entity) -- clear one entity's timer
pcd:purge(fn) -- remove entries where fn(entity) returns true

Pattern:

for _, titan in ipairs(func.GetCachedTitans()) do
if pcd:ready(titan) then
pcd:use(titan)
-- hit titan
end
end

-- Clean up dead titans so the table doesn't grow forever
pcd:purge(function(t) return not t or not t.Parent end)

Always call purge in a periodic loop. Without it, the cooldown table grows indefinitely as entities come and go.


When to use it

  • Firing a remote more than once per second per target
  • Applying an effect to each enemy at most once every N seconds
  • Preventing a keybind from spamming

The debounce N modifier on on InputBegan handlers covers the simple case. Use Pulse.Cooldown when you need programmatic control or per-entity tracking.