Restructured per spec section 3.2: Abstract + Badges-Table + Topology-Block + 7 H3-API-Subsections + Conventions + Consumer pattern + Migration + CHANGELOG + References. Topology-Block auto-populated via Sporel.exe --lint --fix. Pre-commit hook installed via --install-hooks. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
164 lines
5.2 KiB
Markdown
164 lines
5.2 KiB
Markdown
# lib-core.input
|
|
|
|
P.0 action-mapping lib. Decouples physical keys from logical actions.
|
|
Polling-based (`is_action_down`) + edge-based (`was_action_pressed`, `was_action_released`).
|
|
Direction-vector helper composes 4 actions into `{x, y}` in {-1, 0, +1}^2.
|
|
|
|
| Field | Value |
|
|
|---|---|
|
|
| Version | 0.4.0 |
|
|
| Lib-ID | lib-core.input |
|
|
| Requires | (none) |
|
|
| Tags | input, action-mapping |
|
|
|
|
<!-- topology:start (auto-generated; do not edit) -->
|
|
```mermaid
|
|
graph LR
|
|
this["lib-core.input"]
|
|
engine["engine.*"]
|
|
this --> engine
|
|
```
|
|
<!-- topology:end -->
|
|
|
|
## API
|
|
|
|
### `input.bind(action_name, keys)`
|
|
**Syntax:** `input.bind(action_name: string, keys: string[]) -> void`
|
|
|
|
**Example:**
|
|
```lua
|
|
input.bind("move_left", { "a", "left" })
|
|
```
|
|
|
|
**Description:** Bindet einen logischen Action-Namen an ein Array von Key-Names. Atomic: wenn ein Key invalid ist, fehlt der gesamte Bind ohne partial state. Lua `error(...)` für `bind()` misuse (caller-bug fast-fail).
|
|
|
|
### `input.unbind(action_name)`
|
|
**Syntax:** `input.unbind(action_name: string) -> void`
|
|
|
|
**Example:**
|
|
```lua
|
|
input.unbind("move_left")
|
|
```
|
|
|
|
**Description:** Entfernt eine Action-Binding. No-op wenn Action nicht gebunden.
|
|
|
|
### `input.is_action_down(action) -> bool`
|
|
**Syntax:** `input.is_action_down(action: string) -> bool`
|
|
|
|
**Example:**
|
|
```lua
|
|
if input.is_action_down("move_left") then ... end
|
|
```
|
|
|
|
**Description:** Returns true wenn irgendein gebundener Key der Action gerade gedrückt ist. Silent-false für undefined actions.
|
|
|
|
### `input.was_action_pressed(action) -> bool`
|
|
**Syntax:** `input.was_action_pressed(action: string) -> bool`
|
|
|
|
**Example:**
|
|
```lua
|
|
if input.was_action_pressed("quit") then engine.exit(0) end
|
|
```
|
|
|
|
**Description:** Press-Edge — true für genau einen Frame pro Key-Down-Event. Triggers einmal pro Press-Release-Cycle.
|
|
|
|
### `input.was_action_released(action) -> bool`
|
|
**Syntax:** `input.was_action_released(action: string) -> bool`
|
|
|
|
**Example:**
|
|
```lua
|
|
if input.was_action_released("attack") then finish_swing() end
|
|
```
|
|
|
|
**Description:** Release-Edge — true für genau einen Frame pro Key-Up-Event. v0.4.0+. Triggers einmal pro Press-Release-Cycle.
|
|
|
|
### `input.direction(left, right, up, down)`
|
|
**Syntax:** `input.direction(left: string, right: string, up: string, down: string) -> {x: int, y: int}`
|
|
|
|
**Example:**
|
|
```lua
|
|
local d = input.direction("move_left", "move_right", "move_up", "move_down")
|
|
-- d.x, d.y in {-1, 0, +1}
|
|
```
|
|
|
|
**Description:** Komponiert 4 Actions in einen Direction-Vector. Y-down-positive per ADR-0031.
|
|
|
|
### `input.action_count() -> number`
|
|
**Syntax:** `input.action_count() -> number`
|
|
|
|
**Description:** Returns Anzahl der gebundenen Actions. Debug-friendly.
|
|
|
|
## Key-Names
|
|
|
|
Strict-lowercase. Engine-internal `engine.input.KEY_*` integer-args are rejected.
|
|
|
|
| Category | Names |
|
|
|---|---|
|
|
| Letters | `a`, `b`, ..., `z` |
|
|
| Numbers | `0`, `1`, ..., `9` |
|
|
| Arrows | `left`, `right`, `up`, `down` |
|
|
| Whitespace + control | `space`, `tab`, `enter`, `backspace`, `escape` |
|
|
| Modifiers (left-side) | `shift` (= `lshift`), `ctrl` (= `lctrl`), `alt` (= `lalt`) |
|
|
| Console-toggle | `^` (DE: Zirkumflex / US: backtick) |
|
|
| Mouse | `mouse_left`, `mouse_right`, `mouse_middle` (v0.3.0+) |
|
|
|
|
Right-modifier-aliases (`rshift`, `rctrl`, `ralt`) + function-keys (`f1`..`f12`) + special-keys (`delete`, `insert`, ...) are **forthcoming**.
|
|
|
|
Unknown key-names raise a Lua-error with hint to this README.
|
|
|
|
## Conventions
|
|
|
|
- Y-down-positive per Sporel pixel-convention (ADR-0031).
|
|
- Multi-key per action (e.g., `{"a", "left"}` for both A and Left-Arrow).
|
|
- Silent-false for undefined actions (debug-friendly).
|
|
- Lua `error(...)` for `bind()` misuse (caller-bug fast-fail). Atomic.
|
|
|
|
## Consumer pattern
|
|
|
|
```lua
|
|
local input = require("lib-core.input")
|
|
input.bind("quit", { "escape" })
|
|
input.bind("move_left", { "a", "left" })
|
|
input.bind("move_right", { "d", "right" })
|
|
input.bind("move_up", { "w", "up" })
|
|
input.bind("move_down", { "s", "down" })
|
|
|
|
function update(ctx, dt)
|
|
if input.was_action_pressed("quit") then engine.exit(0) end
|
|
local d = input.direction("move_left", "move_right", "move_up", "move_down")
|
|
-- d.x, d.y in {-1, 0, +1}
|
|
end
|
|
```
|
|
|
|
## Migration v0.1.0 -> v0.2.0
|
|
|
|
`bind()` switched from integer `engine.input.KEY_*` arguments to lowercase string-keys (per P.2.6). Reason: stop leaking engine-internal namespace into modules.
|
|
|
|
| v0.1.0 | v0.2.0 |
|
|
|---|---|
|
|
| `bind("quit", { engine.input.KEY_ESCAPE })` | `bind("quit", { "escape" })` |
|
|
|
|
## CHANGELOG
|
|
|
|
### v0.4.0 (P.3.10, 2026-05-15)
|
|
- Added `was_action_released(action_name)` — release-edge detection per action.
|
|
|
|
### v0.3.0 (P.3.3, 2026-05-12)
|
|
- `bind()` now accepts unified key+mouse strings via BIND_MAP with kind-tagged entries.
|
|
|
|
### v0.2.0 (P.2.6, 2026-05-11)
|
|
- `bind()` accepts string-key-names only.
|
|
|
|
### v0.1.0 (P.0)
|
|
- Initial release.
|
|
|
|
## References
|
|
|
|
- Spec v0.4.0 (P.3.10): `meta/docs/superpowers/specs/2026-05-15-p3-housekeeping-design.md`
|
|
- Spec v0.3.0 (P.3.3): `meta/docs/superpowers/specs/2026-05-12-p3-3-mouse-input-design.md`
|
|
- Spec v0.2.0 (P.2.6): `meta/docs/superpowers/specs/2026-05-11-engine-input-symbolic-keys-design.md`
|
|
- Spec v0.1.0 (P.0): `meta/docs/superpowers/specs/2026-05-09-p0-lib-input-design.md`
|
|
- ADR-0001 (engine knows verbs, libs bring nouns)
|
|
- ADR-0031 (pixel-convention: Y-down-positive)
|
|
- ADR-0038 (API-Doc-Convention)
|