Skip to content

How scripts run

Events, drawing, time limits and errors.

Every script runs in its own sandboxed Luau VM, so scripts can't see each other. The file runs once when it loads. After that, Nyx calls the functions you add to events. All of them run on the game thread.

events.paint:add(function()
-- every game tick: draw here
end)
events.createmove:add(function(cmd)
-- every user command: read or change cmd
end)
events.game_event:add(function(name, e)
if name == "player_death" and e.victim then
print(e.victim:name(), "died")
end
end)

All events are on the Events page. In the Reference, functions tagged paint only work in events.paint or a window's on_paint, and createmove ones only in events.createmove.

paint runs once per game tick, 64 times a second. Nyx shows what you drew on every rendered frame until the next tick. A counter in paint counts ticks, not frames.

The _3d functions (render.line_3d, render.text_3d, render.circle_3d, render.box_3d) take world positions. Nyx projects them every rendered frame, so they stay on the world while the camera moves.

Each callback has a time budget, listed on the Limits page. A callback that runs over is stopped. Three overruns in a row unload the script with "script too slow".

An error unloads the script. Its tab shows the error with the traceback.