Core guide

Input routing

Give the active scene first chance to handle raw keyboard, pointer, and gamepad input, then fall back to global handlers.

Try it: press Escape, click the button, move over the panel, or focus the text field and type.

Escape is consumed by the scene. The button and text field retain browser behavior.

checking browser support…
  1. waiting for input…

How it works

The core router is browser-independent. Attach create_browser_input_adapter to a host element to normalize DOM events. The adapter listens in capture phase, skips editable controls by default, and applies preventDefault() only when a handler returns consume_and_prevent_default.

Scene handlers are registered automatically with scene lifecycle. The newest active scene runs first; global handlers receive events only when scenes pass them. Gamepad state is sampled when the owner calls poll().

Public types

  • InputEvent, InputDisposition, and InputRouter
  • SceneDefinition.input and Game.input
  • BrowserInputAdapter and BrowserGamepadAdapter
  • GamepadState, GamepadSnapshot, and GamepadButtonSnapshot

Minimum viable example

const router = create_input_router();
router.on_global((event) => {
  console.log(event);
  return "pass";
});

const browser_input = create_browser_input_adapter({
  host: game_host,
  router: game.input,
});

const gamepads = create_browser_gamepad_adapter({ router: game.input });
gamepads.poll();
console.log(gamepads.state.all());

Scope and limitations

Phase 3B handles raw devices, ownership, and browser default-action policy. Action mapping, rebinding, text input/IME, gesture recognition, pointer hit testing, and haptics remain separate capabilities. A physical gamepad must be connected and exposed to the browser before its state can be observed.