1.9 KiB
1.9 KiB
lib-core.input
P.0 action-mapping lib. Decouples physical keys from logical actions.
Polling-based (is_action_down) + edge-based (was_action_pressed).
Direction-vector helper composes 4 actions into {x, y} ∈ {-1, 0, +1}².
- Lib-ID:
lib-core.input - Version:
0.1.0 - Spec:
meta/docs/superpowers/specs/2026-05-09-p0-lib-input-design.md
Forward-compat stubs (DEPRECATED-MVP) for mouse-button actions, gamepad bindings, action-context-stack, key-rebinding-config, modifier-combos, analog-axis, was_action_released edge.
API
input.bind(action_name, {key1, key2, ...})— bind multi-key arrayinput.unbind(action_name)— remove bindinginput.is_action_down(action) → bool— any bound key currently downinput.was_action_pressed(action) → bool— any bound key just-pressedinput.direction(left, right, up, down) → {x, y}— vec in {-1,0,+1}², Y-down-positiveinput.action_count() → number— bound-actions count
Conventions
- Y-down-positive per Sporel pixel-convention (ADR-0031).
- Multi-key per action (e.g.,
{KEY_A, KEY_LEFT}for both A and Left-Arrow). - Silent-false for undefined actions (debug-friendly; lookup-misuse won't drown the game-loop in errors).
- Lua
error(...)forbind()misuse (caller-bug fast-fail).
Consumer pattern
local input = require("lib-core.input")
input.bind("quit", { engine.input.KEY_ESCAPE })
input.bind("pan_left", { engine.input.KEY_A, engine.input.KEY_LEFT })
input.bind("pan_right", { engine.input.KEY_D, engine.input.KEY_RIGHT })
input.bind("pan_up", { engine.input.KEY_W, engine.input.KEY_UP })
input.bind("pan_down", { engine.input.KEY_S, engine.input.KEY_DOWN })
function update(ctx, dt)
if input.was_action_pressed("quit") then engine.exit(0) end
local d = input.direction("pan_left", "pan_right", "pan_up", "pan_down")
-- d.x, d.y ∈ {-1, 0, +1}
end