---
title: "Input"
type: docs
---

# Input

Prosperon's input system normalizes keyboard, mouse, gamepad, and touch into **named actions**. You define what actions your game uses, bind them to physical inputs, and the engine routes events to the right place.

## Actions

An action is a named game event like `"jump"`, `"attack"`, or `"ui_up"`. Multiple physical inputs can trigger the same action:

```javascript
var input = use('input')

input.configure({
  action_map: {
    jump: ['space', 'gamepad_a'],
    attack: ['mouse_button_left', 'gamepad_x'],
    move_left: ['a', 'left', 'gamepad_dpleft'],
    move_right: ['d', 'right', 'gamepad_dpright']
  }
})
```

Default actions are provided for common UI navigation (`ui_up`, `ui_down`, `ui_left`, `ui_right`, `confirm`, `cancel`, `menu`).

## Players and Users

The input system supports multiple players. Each **user** has:

- Paired devices (keyboard, specific gamepad, etc.)
- An action map (bindings can differ per player)
- A **control stack** of possessed entities

```javascript
var p1 = input.player1()
```

### Device Pairing

By default, pairing is `'last_used'` — all input goes to player 1, and the active device switches when a button is pressed. For local multiplayer, use `'explicit'` pairing where each player is assigned specific devices.

```javascript
input.configure({
  max_users: 2,
  pairing: 'explicit'
})
```

## Control Stack (Possession)

Players **possess** entities to route input to them. The control stack is ordered — the topmost entity gets input first.

```javascript
var p1 = input.player1()

// Take control of the player character
p1.possess(player_entity)

// Push a menu on top — it gets input priority
p1.push(pause_menu)

// Pop the menu — player character gets input again
p1.pop()
```

The possessed entity must have an `on_input` method:

```javascript
var player = {
  on_input: function(action, data) {
    if (action == 'jump' && data.pressed) {
      // jump logic
    }
    if (action == 'move_right') {
      // data.pressed, data.released, data.time
    }
  }
}
```

## Device Detection

The input system tracks what kind of device is active, so you can show appropriate button prompts:

```javascript
var p1 = input.player1()
var kind = p1.device_kind()  // 'keyboard', 'mouse', 'gamepad'
var type = p1.gamepad_type() // 'xbox', 'playstation', etc.
```

Get the display name or icon for an action based on the current device:

```javascript
var icon = p1.get_icon_for_action('jump')
var binding = p1.get_primary_binding('jump')
```

## Emacs-Style Keybindings

For editors or complex hotkey systems, Prosperon supports modifier notation:

| Prefix | Key |
|--------|-----|
| `C-` | Ctrl |
| `M-` | Alt |
| `S-` | Super |

So `C-a` means Ctrl+A, `C-M-s` means Ctrl+Alt+S. Case is preserved — `a` and `A` are different bindings.

The emacs module is enabled by default but can be disabled:

```javascript
input.configure({ emacs: false })
```

## Gestures

Touch gesture recognition is built in:

- Swipe detection (with configurable distance and time thresholds)
- Pinch detection

```javascript
input.configure({
  gestures: true,
  swipe_min_dist: 50,
  swipe_max_time: 0.5
})
```

## Saved Bindings

Player bindings are automatically saved and loaded, so remapped controls persist across sessions.

## Raw Events

For debugging or special cases, the raw SDL event can be accessed via the config callback:

```javascript
core.start({
  input: function(raw_event) {
    // raw SDL event object
  }
})
```
