Scheduler
Scheduler runs a callback every frame, every server tick, or once after a delay.
The scheduler does not draw or change anything by itself; the code inside the callback determines every visible or gameplay effect. Use OnFrame() for client rendering and smooth UI updates, OnTick() for server decisions, and Schedule() for a one-shot delay in the current context.
Where callbacks are processed
Section titled “Where callbacks are processed”OnFrame()stores a subscription in the client module runtime and invokes it from the render loop. Its rate follows FPS, not server tickrate.OnTick()stores a subscription in the Reflex server runtime and invokes it once per module server tick.Schedule()places a one-shot callback in the current runtime’s queue; after the delay, the queue invokes it in the same client/server context.EventSubscription:Cancel()removes a repeating callback from that queue. It does not undo changes that already ran.
Contexts
Section titled “Contexts”| Method | Regular module / Reflex main.lua |
Reflex server.lua |
|---|---|---|
OnFrame |
✅ | ❌ |
OnTick |
❌ | ✅ |
Schedule |
✅ | ✅ |
These restrictions are strict: an unavailable method is absent from the Lua object. Calling OnTick on the client or OnFrame on the server stops execution with a Lua access error.
OnFrame
Section titled “OnFrame”Scheduler:OnFrame(callback: function): EventSubscriptionCalls the callback once per rendered frame. This method is only available in client-side Lua.
local subscriptionlocal frames = 0
subscription = Scheduler:OnFrame(function() frames = frames + 1
if frames >= 60 then subscription:Cancel() endend)The OnFrame frequency follows the frame rate. Do not use a frame count as a timer in seconds. Compare Time.Seconds or use Schedule().
OnTick
Section titled “OnTick”Scheduler:OnTick(callback: function): EventSubscriptionCalls the callback every simulation tick. This method is only available in a Reflex module’s server.lua.
local subscriptionlocal ticks = 0
subscription = Scheduler:OnTick(function() ticks = ticks + 1
if ticks >= 30 then subscription:Cancel() endend)In testing, 30 consecutive callbacks corresponded to 30 ticks and 0.5 seconds of simulation.
EventSubscription
Section titled “EventSubscription”OnFrame() and OnTick() return a subscription object.
Cancel
Section titled “Cancel”subscription:Cancel()Cancels the subscription. Its callback is no longer called after cancellation.
Store the returned object when a callback will ever need to stop:
local subscription = Scheduler:OnFrame(Update)
-- Latersubscription:Cancel()Schedule
Section titled “Schedule”Scheduler:Schedule(duration: number, callback: function)Schedules one callback call after the specified number of seconds. It is available in both Lua contexts.
Scheduler:Schedule(1, function() print("One second has passed")end)The method returns nil, and the callback is called only once. It does not create an EventSubscription.
Delay precision
Section titled “Delay precision”Schedule() runs the callback on the next applicable update, so the actual delay can be slightly longer than requested.
For Schedule(0.1, callback), testing produced:
| Context | Actual delay |
|---|---|
| Client | approximately 0.1064 seconds |
| Reflex server | approximately 0.1167 seconds, or 7 ticks |
Use the method for gameplay and interface logic, but do not expect high-frequency timer precision.
Nil callback
Section titled “Nil callback”Scheduler:Schedule(0, nil)This call is accepted without an error and does nothing.
Common mistakes
Section titled “Common mistakes”Calling OnTick from main.lua
Section titled “Calling OnTick from main.lua”OnTick is not a client-side method. Move the logic into a Reflex module’s server.lua, or use OnFrame.
Calling OnFrame from server.lua
Section titled “Calling OnFrame from server.lua”The server does not render frames. Use OnTick.
Losing the subscription reference
Section titled “Losing the subscription reference”Without a stored EventSubscription, code cannot call Cancel(). Assign the result of OnFrame() or OnTick() to a variable.
Expecting a subscription from Schedule
Section titled “Expecting a subscription from Schedule”Schedule() returns nil. For a cancellable delay, check time from an OnFrame or OnTick callback, and cancel that subscription after it runs.