Fixes the papercut: the generated frame loop called rt_poll() (feeding only Input.key) but never input_poll(), so Input.active/key_down/mouse/pad read empty unless the game called Input.poll() by hand. The loop now calls input_poll() when the game uses any Input runtime method — committing the held-key/mouse/gamepad state, and record/replay — and stores its return as the frame key so Input.key still works. A game using no Input runtime keeps the plain rt_poll path, byte-identical. Adds the Input-Manager API: Input.action(name,key) ships a default binding (kept if already bound, so a rebind/loaded map isn't clobbered), Input.bind_pad(name,button) makes an action device-agnostic (keyboard OR pad), and Input.active/just_pressed/just_released read the multi-key device layer with clean on-press/on-release edges (deterministic, dispatch-free — a handler polls the edge; a replay fires identically). Examples input_manager + input_auto, 5 docs pages. Full suite 107/0, goldens byte-identical, fixpoint holds. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
958 B
958 B
id: input-active name: Input.active category: input kind: namespace-method tokens: Input.active sig: Input.active(action: str) -> bool tip: Is a named action active right now (any bound key held, or pad button down)? order: 33 ns: Input member: active
Returns whether a named action is active this frame, reading the whole device layer: true if any of the action's bound keyboard keys is in the multi-key held-set or any bound gamepad button is down on pad 0. Unlike Input.down (which reads only the single per-frame key), this sees simultaneous holds (move and jump) and is device-agnostic. The frame loop commits the device layer automatically, so it reads live without a manual Input.poll.
program Active {
entry {
Input.action("left", 'a')
if Input.active("left") { print(1) }
}
}