Skip to content

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.

Devices map through named actions to per-frame queries
Raw devices → named actions → queries.
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 diffs

poll() 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.

  • 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 during poll().
  • registerAction(name, bindings) — define an action in code.
  • requestPointerLock(element) — request pointer lock (for FPS-style mouse look).
  • dispose() — remove listeners.

An input map is a versioned file of actions, each with a list of bindings (packages/engine/src/input/input-types.ts):

BindingFields
keycode (from KeyboardEvent.code, e.g. "KeyW")
mouse_buttonbutton (0 = left, 1 = middle, 2 = right)
mouse_move— (fires when the mouse moves)
gamepad_buttonbutton
gamepad_axisaxis, direction (positive / negative), deadzone?
gamepad_axis_pairxAxis, yAxis, deadzone? (a stick → 2D vector)