Input — the Input phase
inputfills the stage's Input phase: it samples keyboard, gamepad, and pointer once per tick, latches the state for that whole tick, and exposes it — buttons, axes, pointer, and logical actions — for everything downstream to read. Sampling once, deterministically, is what finally gives "same inputs → same frame" an actual source; it is also what makes input recordable and replayable.
Status: design. Not built yet.
What it is
The phase order opens with Input — but so far nothing filled it. input is that phase: at the very start of each tick it reads the physical devices, latches a snapshot, and holds it steady for the rest of the frame. Every system and script that asks "is jump held?" during that tick sees the same answer, no matter when in the frame it asks.
This is distinct from BASIC's console input (INKEY / GET): those are typed, line-oriented interaction; input is real-time game input, polled per tick, for things that move.
Sample once, latch — the determinism
The one rule that makes input a deterministic source: the devices are read exactly once per tick, at the start of Input, and the snapshot is immutable for that tick. So:
- no reader sees input change mid-frame — motion, a collision response, and a script all act on one consistent snapshot;
- edges are exact — "pressed this tick" is "down now, up in the previous snapshot," a clean per-tick transition rather than a race;
- and because a tick's input is a small fixed snapshot, the stream of snapshots can be recorded — the whole basis of demos and deterministic replay: replay the input stream over the same seed and ticks and the run is identical.
State — buttons, axes, pointer
- buttons —
down(held),pressed(went down this tick),released(went up this tick), for keys and gamepad buttons; - axes — sticks and triggers as −1…1, and named axes that fold digital keys into one (WASD →
moveX/moveY), so a game reads one axis whether the player uses a stick or the keyboard; - pointer — position and buttons, for mouse / touch.
Actions — bindings, not keys
Games should read what the player meant, not which key they hit. input maps physical inputs to logical actions — bind("jump", { "space", "gamepad:A" }) — and code queries the action (action("jump").pressed). Bindings are data: rebindable at runtime, savable, and the layer that lets one game support keyboard and gamepad with no branching.
On the stage
input runs in Input, first, before Advance — so motion, tween, and everything after read a snapshot already settled for the tick. It writes no target state; it is the frame's input, read by everyone downstream. Record / replay hook the snapshot stream, and because it is captured at a fixed point in a fixed phase order, a replay is exact.
Clients
- Luau —
require("input"):down/pressed/axis/pointer,bind/action,record/replay. - AntBASIC — friendly queries for a first game:
KEYDOWN("space"), anON KEYhandler, and the named axes sox = AXIS("moveX")drives a sprite. (ConsoleINKEY/GETstay as they are, for typed input.)
Related
- stage — the Input phase it fills, and the tick it samples on · collision — reacts to what input drives · motion — moved by it
- luau_input — the Luau API