autoTick
Opt-in per-frame tick loop for zinput. Spawns a `task.spawnSystem` worker that invokes a registered tick function (`Zin.tick`) once per frame, so code-mode snippets and tests without a host script component still drive the stateful subsystems — live binding dispatch, the touch ov…
autoTick
Opt-in per-frame tick loop for zinput. Spawns a task.spawnSystem worker
that invokes a registered tick function (Zin.tick) once per frame, so
code-mode snippets and tests without a host script component still drive
the stateful subsystems — live binding dispatch, the touch overlay, the
emulation floor, axes, chords, rebind, action handlers, event subscribers.
task.spawnSystem (not task.spawn) makes the loop system-owned, so it
keeps ticking while the editor pauses gameplay.
The first real input read arms this worker on its own. A host script
component can also call Zin.tick(dt) from its update(dt) hook, and
autoTick.start can be called directly; all three are idempotent
alongside each other.
Exports
M.start() -> boolean— spawn the worker if not already running. Returns true when a new loop was started.M.stop()— flag the loop to exit on its next yield. No-op if not running.M.isRunning() -> boolean— current status.M._setTickFn(fn: (number?) -> ())— internal hook. Called once byzinput/init.luauto registerZin.tick.M._setLastTickFrameIdFn(fn: () -> number)— internal hook. Wires the frame-id accessor so the worker can dedup itself against explicit ticks within the same engine frame.
Usage
local Zin = require("@builtin::modules.zinput")
-- One-shot test / code-mode setup:
Zin.autoTick.start()
-- ... later ...
Zin.autoTick.stop()
Notes
- Single-flight: calling
start()twice is a no-op — there is at most one worker per VM. - Cross-coroutine dedup: when an explicit
Zin.tickran in the same engine frame, the worker skips that frame soonHeldhandlers and event subscribers don't double-fire. - Module-local
_runningsurvives Luau require-cache reload, so a re-requiredautoTick.modulestill reports the loop is live.restart_instanceresets the VM and clears everything. start()raises if_setTickFnhasn't been wired yet — alwaysrequire("@builtin::modules.zinput")first.
Scoped to this part · feeds back into the world's score.