code
SourceA binding to a physical key by its KeyboardEvent.code.
const bindings = {
up: [Keyboard.code("KeyW")],
jump: [Keyboard.code("Space")]
} as const
Browser
Keyboard input as caller-named actions.
Games bind actions to keys once and read one snapshot per update. The module owns the browser plumbing every game rewrites: key normalization, preventDefault for bound keys, press/release edges that survive taps shorter than one frame, clearing on window blur, and listener cleanup. It does not know about the ECS; InputCapture.system(...) copies snapshots from a service into a resource.
Bind by character ("w") or by physical key (Keyboard.code("KeyW")); see KeyBinding. A key released while a modifier changed its character (W pressed, then Option, then W released as "∑") still releases its action.
Some combinations never reach the page: browsers reserve shortcuts such as Ctrl+W / Cmd+W (close tab), Ctrl+T / Cmd+T, and Cmd+Q, and pages cannot prevent them. Avoid Ctrl and Cmd as held modifiers in games.
const input = Keyboard.actions(window, {
left: ["ArrowLeft", "a"],
right: ["ArrowRight", "d"],
jump: [" ", "ArrowUp", "w"]
})
// Once per update:
const snapshot = input.snapshot()
if (snapshot.jump.pressed) jump()
// On teardown:
input.dispose()
For tests, replays, and headless runs, scripted(...) plays a timeline of presses and releases instead of listening to a host, and recording(...) wraps live actions to capture the timeline a session produced. parseTimeline(...) validates a timeline loaded from JSON.
// Browser: record a session, then save `recorder.timeline()` as JSON.
const recorder = Keyboard.recording(Keyboard.actions(window, bindings))
// Node: replay it frame by frame.
const parsed = Keyboard.parseTimeline(bindings, JSON.parse(saved))
if (parsed.ok) {
const replay = Keyboard.scripted(bindings, parsed.value)
}
A binding to a physical key by its KeyboardEvent.code.
idleA snapshot with every action idle, for initializing an input resource before the first capture.
actionsStarts tracking bound keys on host.
scriptedPlays timeline: before the snapshot at index frame, every entry for that frame is applied. Actions stay held from their press until their release, like keys.
recordingWraps actions and records, for every snapshot, the actions pressed and released since the previous one.
parseTimelineValidates untrusted data, such as a parsed JSON file, as a timeline for bindings: an array of entries with a non-negative integer frame and optional press/release arrays of bound action names.
A binding to a physical key by its KeyboardEvent.code.
const bindings = {
up: [Keyboard.code("KeyW")],
jump: [Keyboard.code("Space")]
} as const
A snapshot with every action idle, for initializing an input resource before the first capture.
Starts tracking bound keys on host.
Plays timeline: before the snapshot at index frame, every entry for that frame is applied. Actions stay held from their press until their release, like keys.
Wraps actions and records, for every snapshot, the actions pressed and released since the previous one.
Validates untrusted data, such as a parsed JSON file, as a timeline for bindings: an array of entries with a non-negative integer frame and optional press/release arrays of bound action names.