Input
The InputManager (packages/engine/src/input/input-manager.ts) maps raw device events to
named actions so your gameplay code asks βis jump pressed?β rather than βis Space
down?β. Itβs polled once per frame in the input phase.
The frame discipline
Section titled βThe frame disciplineβawait input.loadMap('inputmaps/default.inputmap.json');// each frame:input.poll(); // at the start (input phase)if (input.isPressed('jump')) { /* β¦ */ }if (input.isJustPressed('attack')) { /* β¦ */ }input.endFrame(); // at the end β clears per-frame diffspoll() reads gamepad state and computes the just-pressed / just-released edges for this
frame; endFrame() clears those per-frame diffs. The engine runtime wires this for you.
Queries
Section titled βQueriesβisPressed(action)β held this frame.isJustPressed(action)β became pressed this frame.isJustReleased(action)β became released this frame.getMouseDelta()β accumulated mouse movement this frame.setLookStick(x, y)β feed a virtual look stick (e.g. from on-screen touch controls); its value is injected as mouse delta duringpoll().registerAction(name, bindings)β define an action in code.requestPointerLock(element)β request pointer lock (for FPS-style mouse look).setEnabled(enabled)/isEnabled()β gate input delivery without removing listeners; disabling flushes held keys and buttons so nothing sticks on re-enable (the editor uses this to isolate play-mode input).dispose()β remove listeners.
Keydown events are also ignored while a text field (input, textarea, or a
contenteditable element) has focus, so typing a name into an editor panel or an
in-game chat box never triggers game actions.
Binding types (.inputmap.json)
Section titled βBinding types (.inputmap.json)βAn input map is a versioned file of actions, each with a list of bindings.
The Zod schema (packages/engine/src/input/schema.ts, T4.6) validates every
map at loadMap β a malformed file throws a SceneParseError naming the
file, instead of failing deep inside a query method:
| Binding | Fields |
|---|---|
key | code (from KeyboardEvent.code, e.g. "KeyW") |
mouse_button | button (0 = left, 1 = middle, 2 = right) |
gamepad_button | button |
gamepad_axis | axis, direction (positive / negative), deadzone? |
Two declared binding kinds β mouse_move and gamepad_axis_pair β have
no runtime reader (no query method ever handles them), so authoring
either one throws at parse (T4.1βs dead-field rule). Mouse look is read
out-of-band via getMouseDelta()/setLookStick(), not through a binding.
See also
Section titled βSee alsoβ- The game loop & phases β the
inputphase. - Capstone: FPS β pointer lock + actions in a build.
- Quick start: write your first component β reading input from a component.