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
12
LANGUAGE.md
12
LANGUAGE.md
|
|
@ -288,6 +288,18 @@ fields — so "Position + Light2D" and a self-positioned light both work. With
|
|||
`Light2D` present the engine owns the frame flip: a draw handler renders the
|
||||
scene and does **not** call `Screen.show`.
|
||||
|
||||
### Input actions & deterministic replay
|
||||
|
||||
Beyond the raw `Input.key()` (this frame's key code), gameplay can read **named
|
||||
actions** instead of physical keys, so a key is rebindable and a control scheme
|
||||
is data. `Input.bind(action, key)` binds a key; `Input.down(action)` /
|
||||
`Input.pressed(action)` read it (held vs one-shot edge); `Input.rebind(action,
|
||||
from, to)` remaps it at runtime. `Input.poll()` is the single per-frame input
|
||||
read the actions sit on — which is what makes **deterministic replay** fall out:
|
||||
`Input.record()` captures the polled key each frame and `Input.replay()` feeds
|
||||
the tape back, so a run reproduces exactly (the seed of lockstep netcode). All
|
||||
integer and deterministic. See `examples/library/input_actions.ludic`.
|
||||
|
||||
Everything is integer and deterministic (the frame clock ticks at a fixed 60/s),
|
||||
so animation, motion and lighting reproduce exactly under replay and lockstep
|
||||
netcode. See `examples/library/anim_ecs.ludic` and `examples/library/light_ecs.ludic`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue