Builtin Library
README.md
state
Synchronous per-frame input state. Thin wrapper over the internal
__zero_input.snapshot() FFI; backs Zin.state. Pointer-lock mutations
live on Zin.pointer; the read-side pointerLocked() query lives here
with the rest of the snapshot accessors. Held-time and synthetic-repeat
state is owned by this module and updated via _observeEvent from the
Zin.tick coordinator.
Exports
M.get() -> Snapshot— full per-frame snapshot table; empty when the FFI is unavailable.M.keyDown(key: string) -> boolean— held this frame.M.keyPressed(key: string) -> boolean— edge-pressed this frame.M.keyReleased(key: string) -> boolean— edge-released this frame.M.mousePosition() -> (number, number)— current mouse(x, y).M.mouseDelta() -> (number, number)—(dx, dy)since last frame.M.scrollDelta() -> number— wheel delta this frame.M.mouseButtonDown(idx: number?) -> boolean— held; default idx = 0.M.mouseButtonPressed(idx: number?) -> boolean— edge-pressed.M.mouseButtonReleased(idx: number?) -> boolean— edge-released.M.pointerLocked() -> boolean— pointer-lock query (writes are onZin.pointer).M.uiWantsPointer() -> boolean—truewhen the UI layer claims pointer focus.M.uiTookPress() -> boolean?:truewhile a UI widget sensing a click or a drag holds the pointer press in progress;falsewith no press held and for a press on empty space;nilfrom the moment a press arrives until a UI pass has decided it.M.setRepeatDefaults(opts: RepeatOpts?)— set default delay / period for synthetic repeat.M.getRepeatDefaults() -> RepeatDefaults— read the active synthetic-repeat defaults.M.keyHeldTime(code: string) -> number?— seconds since the key was pressed (or nil).M.mouseButtonHeldTime(idx: number?) -> number?— seconds since a mouse button was pressed.M.keyRepeatFired(code: string, opts: RepeatOpts?) -> boolean— should a synthetic key-repeat fire this frame?M._observeEvent(ev: any)— internal: per-event observer, wired from the tick coordinator.M._reset()— test-only: clear held-time and synthetic-repeat state.
Types:
Snapshot = { [string]: any }RepeatOpts = { delay: number?, period: number? }RepeatDefaults = { delay: number, period: number }
Usage
local State = require("@builtin::modules.zinput.state")
-- Rebind-capture-style probe: how long has a key been held, and is a
-- synthetic repeat due this frame?
local heldFor = State.keyHeldTime("Space")
if heldFor and State.keyRepeatFired("Space", { delay = 0.4, period = 0.08 }) then
-- charge-attack tick, key-repeat menu navigation, etc.
end
Notes
- Mouse-button indices are 0-based and follow
InputResource.mouse_buttons[](0=left, 1=right, 2=middle). Winit's0=L, 1=M, 2=Ris converted in Rust before reaching Luau. mousePosition/mouseDeltareturn two numbers, not a table.- Held-time / repeat state is updated by the
Zin.tickcoordinator via_observeEvent— without a tick, those queries returnnil/false. keyRepeatFiredadvances state on every call — call once per frame per consumer.- All entry points are no-ops or return zero values when
__zero_inputis missing (off-host execution). - Gameplay subscribes to controls through an activated
.inputMap; this module is the raw snapshot layer those bindings evaluate against, used directly by rebind capture, the emulation floor, and dev tooling. Polling it from a world makes that world keyboard-only and draws theengine-raw-key-polldiagnostic at author time.