Builtin Library
README.md
emulation
Map-driven input-emulation floor. Reads Zin.virtual (the store on-screen
touch controls write) each tick and emulates the equivalent kbm keys / mouse
delta, so raw-key-polling worlds (Zin.state.keyDown) move from touch input
without themselves reading Zin.virtual or Zin.bindings. Backs
Zin.emulation.
What it derives, per tick, from the active effective map
Only entries whose context matches the current input context
(Zin.context.current()) participate — the same activity rule
Zin.actions applies, so a vehicle-context Brake button emulates nothing
while the default context is on top.
- touchButton actions — the OR of every touchButton binding in an
action's touch class drives its first kbm
keybinding's code, emulated on the held state's transitions. Actions with no kbm key binding are skipped. - touchStick axes whose kbm class is a
vectorof fourkeyarms (theB.wasd()/B.arrowKeys()shape) — each stick component thresholded at+-0.5drives the matching direction key. The stick's y is screen-down positive (Virtual.setStick's convention), so negative y (stick pushed up) drives the vector'suparm and positive y itsdownarm. - touchDrag axes whose kbm class is
mouseDelta— the drag delta, scaled byM.setSensitivity, emulated viainput.emulateMouseDeltawhenever it's non-zero.
A control that is already a live binding (Zin.scheme.has(name)) is
skipped: its touch class drives it directly, and synthesising a key for it
as well drives it twice, from opposite conventions. The judgement is per
control, because a world can subscribe to some things and poll raw keys for
others.
Emitted keys are tracked locally and diffed each tick — a held key is emulated once, on the press transition, never re-emitted every tick a control stays held. Switching the active map (name change between ticks) or the input context (top-of-stack change) releases everything emitted under the previous map/context.
Exports
M.setSensitivity(n: number)/M.getSensitivity() -> number— the touchDrag -> mouse-delta multiplier (default1.0).M._advance()— internal: one tick of the floor, called byZin.tick.M._reset()— test-only: release everything emitted, clear state.
Usage
local Zin = require("@builtin::modules.zinput")
Zin.map.ensureActive()
Zin.emulation.setSensitivity(1.5)
-- Zin.tick(dt) advances the floor; a virtual Jump press then reads as
-- Zin.state.keyDown("Space") for any world that only polls kbm state.