feat(input): action maps + deterministic record/replay (#7)
The two ideas the input revamp leads with, built in Ludic over the single-key poll every target already provides: - Action maps: gameplay reads named actions, not physical keys, so keys are rebindable and a scheme is data. Input.bind(action, key), Input.down/pressed(action), Input.rebind(action, from, to). - Deterministic record/replay: Input.poll() is the one per-frame input read; Input.record() captures the key each frame and Input.replay() feeds the tape back, so a run reproduces exactly — the seed of lockstep netcode. "Read input" and "read a recorded snapshot" are the same call. runtime/native/input.ludic (spliced when the new Input.* methods are used; pulls in core.ludic for rt_poll). emit_ns_call routes the methods to the @fn_input_* runtime; parse.ludic gates the splice. Seven docs/language pages; worked example + regression examples/library/input_actions.ludic (1 0 1 1 0 1 0). Full suite 75 passed, self-host fixpoint intact, no golden drift. The device layer (multi-key held, gamepads, touch, analog) needs a platform key-state backend and is tracked separately. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
3679ce1797
commit
377b6d1186
15 changed files with 19159 additions and 18515 deletions
24
docs/language/input/input-poll.md
Normal file
24
docs/language/input/input-poll.md
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
id: input-poll
|
||||
name: Input.poll
|
||||
category: input
|
||||
kind: namespace-method
|
||||
tokens: Input.poll
|
||||
sig: Input.poll() -> int
|
||||
tip: Advance one frame of input; the single per-frame read behind actions and replay.
|
||||
order: 3
|
||||
ns: Input
|
||||
member: poll
|
||||
---
|
||||
|
||||
Advances the input by one frame and returns the frame's key. Call it once at the top of a frame; the action reads (<a href="input-down.html"><code>Input.down</code></a>, <a href="input-pressed.html"><code>Input.pressed</code></a>) then report on the key it captured. It is the single place input crosses into the frame, which is what makes recording and replay possible: in record mode it saves the live key, and in replay mode it takes the next key from the tape instead of the device — so "read input" and "read a recorded snapshot" are the same call.
|
||||
|
||||
```ludic
|
||||
program Poll {
|
||||
entry {
|
||||
Input.bind("up", 'w')
|
||||
Input.poll()
|
||||
if Input.down("up") { print(1) }
|
||||
}
|
||||
}
|
||||
```
|
||||
Loading…
Add table
Add a link
Reference in a new issue