Reading Input
Call input methods directly on this.world inside onUpdate() to query keyboard and mouse state each frame. There is no world.input accessor — all methods are on the World instance itself.
import { Behaviour, KeyboardKeys } from "@relu-interactives/spatial-ecs";
export default class Example extends Behaviour {
onUpdate() {
// held this frame
if (this.world.getKey(KeyboardKeys.Space)) { /* … */ }
// only true on the first frame the key goes down
if (this.world.getKeyDown(KeyboardKeys.E)) { /* … */ }
// only true on the frame the key is released
if (this.world.getKeyUp(KeyboardKeys.E)) { /* … */ }
}
}API
All methods are called directly on this.world:
| Method | Description |
|---|---|
this.world.getKey(key) | true while the key is held. |
this.world.getKeyDown(key) | true only on the first frame the key is pressed. |
this.world.getKeyUp(key) | true only on the frame the key is released. |
this.world.getMouse(button) | true while the mouse button is held. "left" / "middle" / "right". |
this.world.getMouseDown(button) | true only on the first frame the button is pressed. |
this.world.getMouseUp(button) | true only on the frame the button is released. |
this.world.getMousePosition() | { x, y } in viewport pixels. |
this.world.getMouseDelta() | { x, y } pointer movement since the last frame. |
this.world.consumeMouseDelta() | { x, y } movement since last frame; zeroes the delta after reading. |
this.world.getScrollDelta() | { x, y } scroll wheel delta since the last frame. |
KeyboardKeys reference
All constants are available from the KeyboardKeys import. Pass any of them to getKey / getKeyDown / getKeyUp.
import { KeyboardKeys } from "@relu-interactives/spatial-ecs";Letters
KeyboardKeys.A through KeyboardKeys.Z
Digits
KeyboardKeys.Digit0 through KeyboardKeys.Digit9
Navigation & editing
| Constant | Key |
|---|---|
KeyboardKeys.ArrowUp | ↑ Arrow |
KeyboardKeys.ArrowDown | ↓ Arrow |
KeyboardKeys.ArrowLeft | ← Arrow |
KeyboardKeys.ArrowRight | → Arrow |
KeyboardKeys.Space | Space |
KeyboardKeys.Enter | Enter / Return |
KeyboardKeys.Escape | Escape |
KeyboardKeys.Tab | Tab |
KeyboardKeys.Backspace | Backspace |
KeyboardKeys.Delete | Delete |
KeyboardKeys.Insert | Insert |
KeyboardKeys.Home | Home |
KeyboardKeys.End | End |
KeyboardKeys.PageUp | Page Up |
KeyboardKeys.PageDown | Page Down |
Modifier keys
Generic variants match either the left or right physical key. Use the specific variant when the side matters.
| Constant | Physical key |
|---|---|
KeyboardKeys.Shift | Either Shift key |
KeyboardKeys.ShiftLeft | Left Shift |
KeyboardKeys.ShiftRight | Right Shift |
KeyboardKeys.Control | Either Ctrl key |
KeyboardKeys.ControlLeft | Left Ctrl |
KeyboardKeys.ControlRight | Right Ctrl |
KeyboardKeys.Alt | Alt / Option |
KeyboardKeys.Meta | Cmd (macOS) / Win key |
KeyboardKeys.CapsLock | Caps Lock |
Function keys
KeyboardKeys.F1 through KeyboardKeys.F12
Punctuation & symbols
| Constant | Key |
|---|---|
KeyboardKeys.Minus | - |
KeyboardKeys.Equal | = |
KeyboardKeys.BracketLeft | [ |
KeyboardKeys.BracketRight | ] |
KeyboardKeys.Backslash | \ |
KeyboardKeys.Semicolon | ; |
KeyboardKeys.Quote | ' |
KeyboardKeys.Backquote | ` |
KeyboardKeys.Comma | , |
KeyboardKeys.Period | . |
KeyboardKeys.Slash | / |
Other
| Constant | Key |
|---|---|
KeyboardKeys.NumLock | Num Lock |
KeyboardKeys.ScrollLock | Scroll Lock |
KeyboardKeys.Pause | Pause / Break |
KeyboardKeys.PrintScreen | Print Screen |
KeyboardKeys.ContextMenu | Context Menu |
Examples
WASD movement with sprint
import { Behaviour, KeyboardKeys } from "@relu-interactives/spatial-ecs";
export default class Movement extends Behaviour {
speed = 5;
sprintMultiplier = 2;
onUpdate() {
const step = this.speed * (this.world.getKey(KeyboardKeys.Shift) ? this.sprintMultiplier : 1) * this.deltaTime;
if (this.world.getKey(KeyboardKeys.W)) this.transform.position.z -= step;
if (this.world.getKey(KeyboardKeys.S)) this.transform.position.z += step;
if (this.world.getKey(KeyboardKeys.A)) this.transform.position.x -= step;
if (this.world.getKey(KeyboardKeys.D)) this.transform.position.x += step;
}
}One-shot action on key press and mouse click
getKeyDown fires only on the frame the key transitions from up to down, so it is safe to use for one-shot actions.
import { Behaviour, KeyboardKeys } from "@relu-interactives/spatial-ecs";
export default class ActionHandler extends Behaviour {
onUpdate() {
if (this.world.getKeyDown(KeyboardKeys.Space)) {
console.log("Jump!");
}
if (this.world.getMouseDown("left")) {
const pos = this.world.getMousePosition();
console.log("Fired at", pos.x, pos.y);
}
}
}Distinguishing left vs right modifier
import { Behaviour, KeyboardKeys } from "@relu-interactives/spatial-ecs";
export default class ModifierDemo extends Behaviour {
onUpdate() {
if (this.world.getKeyDown(KeyboardKeys.ControlLeft)) {
console.log("Left Ctrl");
}
if (this.world.getKeyDown(KeyboardKeys.ControlRight)) {
console.log("Right Ctrl");
}
// Matches either Shift key
if (this.world.getKey(KeyboardKeys.Shift)) {
console.log("Shift held");
}
}
}Mouse-delta camera look
import { Behaviour } from "@relu-interactives/spatial-ecs";
export default class CameraLook extends Behaviour {
sensitivity = 0.002;
onUpdate() {
const { x, y } = this.world.consumeMouseDelta();
this.transform.rotation.y -= x * this.sensitivity;
this.transform.rotation.x -= y * this.sensitivity;
}
}For InputSystem internals and pointer-lock details, see the InputSystem guide.

