Scope
A container for scheduled work. All tasks within a Scope share the same lifecycle: pausing, resuming, or destroying the Scope affects every task registered to it.
Created via chrono.scope().
local scope = chrono.scope({ timeScale = 0.5 })
scope:tick(60, function(dt)
player.position += player.velocity * dt
end)
scope:after(10, function()
scope:destroy() -- cleans up all tasks at once
end)
Properties
timeScale
This item is read only and cannot be modified. Read OnlyScope.timeScale: number
The current time multiplier for this Scope. Affects how fast after, every,
and tick tasks advance. Defaults to 1.0. Modify via setTimeScale().
isPaused
This item is read only and cannot be modified. Read OnlyScope.isPaused: booleanWhether this Scope is currently paused.
isDestroyed
This item is read only and cannot be modified. Read OnlyScope.isDestroyed: booleanWhether this Scope has been permanently destroyed. A destroyed Scope cannot be used and all its child Handles are invalid.
elapsedTime
This item is read only and cannot be modified. Read OnlyScope.elapsedTime: number
Total time elapsed in this Scope in seconds, scaled by timeScale. Does not
advance while the Scope is paused.
Functions
after
Scope.after(self: ScopeInternal,delay: number,--
Delay in seconds. Values ≤ 0 execute on the next frame.
fn: () → (),--
The function to execute.
config: {name: string?,maxCatchup: number?,fireImmediately: boolean?}?--
Optional configuration. name labels this task in the profiler.
) → Handle
Schedules a function to execute once after delay seconds. The Handle is
automatically cancelled after the function runs.
every
Scope.every(self: ScopeInternal,interval: number,--
Time between executions in seconds.
fn: () → (),--
The function to execute.
config: {name: string?,maxCatchup: number?,fireImmediately: boolean?}?--
Optional configuration. fireImmediately controls whether the task fires on registration (default: true).
) → Handle
Schedules a function to execute repeatedly every interval seconds. By default,
fires immediately on registration, then repeats. Set fireImmediately = false in
the config to skip the first execution. Respects the Scope's timeScale.
frame
Scope.frame(self: ScopeInternal,fn: (dt: number) → (),--
Called each frame. dt is the frame delta in seconds, or 0 when the Scope is paused.
config: {name: string?,maxCatchup: number?,fireImmediately: boolean?}?--
Optional configuration. name labels this task in the profiler.
) → Handle
Schedules a function to execute every frame via RunService.Heartbeat. Unlike
other task types, frame tasks always fire even when the Scope is paused —
they receive dt = 0 instead of the real frame delta.
Tasks run in order of creation, after all tick tasks for the frame.
tick
Scope.tick(self: ScopeInternal,hz: number,--
Target executions per second (e.g. 60 for 60 hz).
fn: (dt: number) → (),--
Called with a fixed delta of 1/hz on each tick.
config: {name: string?,maxCatchup: number?,fireImmediately: boolean?}?--
Optional configuration. maxCatchup caps how many times the task can fire in a single frame, preventing hitches after freezes (default: unlimited).
) → Handle
Schedules a function to execute at a fixed frequency, independent of frame rate.
If the frame rate drops below hz, the function fires multiple times per frame
to compensate. Respects the Scope's timeScale.
Tasks run in order of creation, before all frame tasks for the frame.
pause
Scope.pause(self: ScopeInternal) → ()
Pauses all tasks in this Scope. Timers do not advance while paused. frame
tasks still fire each frame but receive dt = 0.
Calling pause() on an already-paused Scope is a no-op.
resume
Scope.resume(self: ScopeInternal) → ()Resumes all tasks in this Scope after a pause. No time is backfilled — timers continue from where they were when the Scope was paused.
Errors
| Type | Description |
|---|---|
| "Scope is destroyed" | Thrown if the Scope was destroyed. |
setTimeScale
Scope.setTimeScale(self: ScopeInternal,scale: number--
Time multiplier. Negative values are clamped to 0 (a warning is emitted).
) → ()
Sets the time multiplier for this Scope. Affects how fast after, every, and
tick tasks advance. frame tasks always receive wall-clock dt regardless.
scale |
Effect |
|---|---|
1.0 |
Normal speed (default) |
0.5 |
Half speed — slow motion |
2.0 |
Double speed — fast-forward |
0 |
Freezes time (distinct from pause()) |
destroy
Scope.destroy(self: ScopeInternal) → ()Permanently destroys this Scope and cancels all its tasks. All child Handles become invalid. This operation cannot be undone.
NOTE
Also available as scope:Destroy() for compatibility with Trove
and similar cleanup utilities.