Chrono
A scope-based task scheduler for Roblox. Schedule recurring tasks, fixed-rate
ticks, one-shot delays, and per-frame callbacks — all tied to a Scope's lifecycle.
All tasks created through a Scope are automatically cleaned up when the Scope is destroyed, making chrono safe to use in component-based or OOP architectures without manual cleanup bookkeeping.
local chrono = require(path.to.chrono)
local scope = chrono.scope()
scope:tick(60, function(dt)
player.position += player.velocity * dt
end)
scope:every(5, function()
print("every 5 seconds")
end)
scope:after(10, function()
scope:destroy() -- cleans up all tasks at once
end)
Functions
createScope
Chrono.createScope(config: {timeScale: number?,onError: ((err: string,name: string) → ())?}?--
Optional configuration. timeScale sets the initial time multiplier (default: 1.0). onError is called when a task callback throws, receiving the error message and the task name.
) → ScopeCreates a new independent Scope. Each Scope maintains its own pause state, time scale, and elapsed time. Scopes do not interfere with each other.
profile
Chrono.profile() → {[string]: {name: string,count: number,avgMs: number,maxMs: number,p99Ms: number,totalMs: number}}
Returns profiling data for all tasks that have executed at least once since the
last reset_profiler() call (or since the module was loaded).
Task names come from the name field in each task's config table. Tasks without
a name are grouped under <anonymous>.
Times are computed over a rolling window of the last 128 samples per task.
local prof = chrono.profile()
for name, data in pairs(prof) do
print(name, "avg:", data.avgMs, "p99:", data.p99Ms)
end
resetProfiler
Chrono.resetProfiler() → ()Clears all profiler data accumulated since the last reset or module load.
pauseAll
Chrono.pauseAll() → ()
Pauses all active Scopes at once. Equivalent to calling scope:pause() on
every Scope individually.
Useful for game-wide pause states such as cutscenes or menus.
resumeAll
Chrono.resumeAll() → ()
Resumes all active Scopes at once. Equivalent to calling scope:resume() on
every Scope individually.