Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/sanchedev/tiny-engine/llms.txt

Use this file to discover all available pages before exploring further.

tiny-engine provides a unified Input system that handles both pointer (mouse/touch) and keyboard events through a single API. The system normalises pointer coordinates to game-space, clears per-frame key state automatically, and exposes typed event emitters so you never attach raw DOM listeners yourself.

Accessing input

Game.input is available after Game.setup() completes. Access it from any TinyScript or hook context:
import { Game } from 'tiny-engine'

const input = Game.input

Pointer properties

PropertyTypeDescription
input.pointerPositionReadonly<Vector2>Current pointer position in game coordinates. Updated on every pointer move.
input.isPointerPressedbooleantrue while a pointer button is held down.
// Read current pointer state synchronously
const pos = input.pointerPosition   // Vector2 in game coords
const held = input.isPointerPressed // boolean

Pointer events

Input exposes three typed Event properties. Call .on(callback) directly on the property. Every callback receives the current pointer position as a game-space Vector2.
PropertyFired when
input.pointerPressedA pointer button is pressed down.
input.pointerUnpressedA pointer button is released.
input.pointerMovedThe pointer moves (regardless of press state).
input.pointerPressed.on((position) => {
  console.log('Pressed at', position.x, position.y) // game coords
})

input.pointerUnpressed.on((position) => {
  console.log('Released at', position.x, position.y)
})

input.pointerMoved.on((position) => {
  console.log('Moved to', position.x, position.y)
})

Keyboard methods

The keyboard API distinguishes between currently held keys, keys pressed this frame, and keys released this frame. All methods accept an optional set of modifier flags.
MethodReturnsDescription
isKeyPressed(key, ctrl?, shift?, alt?)booleantrue while the key is currently held.
isJustKeyPressed(key, ctrl?, shift?, alt?)booleantrue only on the frame the key was first pressed.
isJustKeyUnpressed(key, ctrl?, shift?, alt?)booleantrue only on the frame the key was released.
getKeyAxis(positiveKey, negativeKey)-1 | 0 | 1Returns 1 if positive key is held, -1 if negative, 0 if neither or both.
// Directional movement axis (-1 left, 0 still, 1 right)
const xAxis = input.getKeyAxis('ArrowRight', 'ArrowLeft')

// One-shot action on key down
if (input.isJustKeyPressed('z')) {
  player.attack()
}

// Modifier combo
if (input.isKeyPressed('s', true)) {
  // Ctrl+S held
}
Key strings match the browser’s KeyboardEvent.key values (e.g. 'ArrowLeft', 'a', ' '). Matching is case-insensitive.

Input options

When tiny-engine constructs Input internally via Game.setup(), it passes the preventKeyDefaults option:
OptionTypeDefaultDescription
preventKeyDefaultsbooleantrueCalls preventDefault() on all keyboard events, blocking browser shortcuts (e.g. arrow-key scroll). Set to false to allow default browser behaviour.

Example: axis movement and pointer fire in a TinyScript

import { TinyScript } from 'tiny-engine/scripts'
import { PrimaryNode, Game } from 'tiny-engine'

class PlayerScript extends TinyScript<PrimaryNode.Transform> {
  setup() {
    this.connect('updated', (delta) => {
      const input = Game.input

      // Move left/right with arrow keys
      const xAxis = input.getKeyAxis('ArrowRight', 'ArrowLeft')
      this.me.position.x += xAxis * 120 * delta

      // Jump on the frame Space is pressed
      if (input.isJustKeyPressed(' ')) {
        this.jump()
      }

      // Fire toward the pointer while left button is held
      if (input.isPointerPressed) {
        this.fireAt(input.pointerPosition)
      }
    })
  }

  private jump() {
    // jump logic
  }

  private fireAt(target: Vector2) {
    // fire logic
  }
}

Cleaning up

input.destroy() removes all DOM event listeners attached by the Input instance.
Always call input.destroy() when the game or scene is torn down to prevent memory leaks from dangling window listeners. If you are using Game.destroy(), you do not need to call it manually — Game.destroy() calls input.destroy() automatically as part of its cleanup sequence.

Build docs developers (and LLMs) love