Builtin Library
README.md
axes
A name-registered axis registry over Zin.bindings. Any axis or vector
binding becomes a Zin.axes entry with optional deadzone, exponential
smoothing, curve shaping, invert, context gating, and a per-frame gate
function. Stateful — Zin.tick calls advance(dt) each frame to evolve
the smoothed reading.
A control asset replaced this. An axis1 / axis2 <name>.inputBinding/
inside an .inputMap/ carries a binding for keyboard-and-mouse, gamepad
and touch, so one control reads a stick and a dragging thumb as well as a
key, and the binding's own as / unitsPerSecond / scale bring every
class into one unit. It declares the same deadzone, smoothing, curve
and invert, applied by Zin.scheme through the same Zin.utils maths
this reads:
public = {
inputMap = Field.assetRef("inputMap", "@builtin::inputMaps.default", NoSync, "The controls this component reads."),
speed = Field.number(5, NoSync, "World units per second at full deflection."),
jumps = Field.number(0, NoSync, "How many times the jump control was pressed."),
}
local controls
function awake()
controls = public.inputMap:activate()
controls.move:onInput(function(v, dt, active)
if not active then return end
local p = public.entity.position
local step = public.speed * dt
public.entity.position = { p.x + v.x * step, p.y, p.z - v.y * step }
end)
controls.jump:onPressed(function() public.jumps += 1 end)
end
function onDestroy()
public.inputMap:deactivate(controls)
end
Zin.map.bake(name) writes the currently active map out as an .inputMap
asset. man topics/input covers the control model.
Exports
Lifecycle:
M.define(spec: AxisSpec)— define / replace axes.M.remove(name: string)/M.clear()— drop one / all axes.M.has(name) -> boolean/M.names() -> { string }/M.get(name) -> AxisDef?
Reads:
M.value(name: string) -> any— smoothed value (numberfor scalar,{ x, y }for vector).M.raw(name: string) -> any— raw unsmoothed binding value.
Tick hook:
M.advance(dt: number)— internal; called byZin.tick.M._setEnsureBindingsFn(fn)/M._setEnsureLiveFn(fn)— internal cold-read hooks.M._resetGateWarnings()— test helper.
Types:
Curve = string | (number) -> number—"linear"/"quadratic"/"cubic"/ custom.AxisDef = { binding, deadzone, smoothing, curve, invert, context, gate, kind }AxisSpec = { [string]: any }— define-spec.
Notes
smoothingis the exponential time constant in seconds.0means "snap to target instantly". Higher = laggier.deadzoneis radial for vector bindings — magnitude under the threshold zeros both axes — and scalar for scalar bindings.- Context gating is strict: the axis's declared context must equal
Zin.context.current(). Mismatch snaps target to 0, andadvancesmooths current down toward 0. - A throwing
gatefalls through to "ungated" for that frame and logs one warning per axis per session (state cleared via_resetGateWarnings()). - Without a tick host (or
Zin.autoTick.start()),value()returns the last computed snapshot;raw()always reads live.