Add Hugo website and rewrite docs to match current engine

New Hugo site in website/ with prosperon.dev theme (blue/gold/castle
aesthetic), docs sidebar navigation, and content pages. Rewrote all
doc files to align with the actual codebase: compositor+film2d
rendering, use() modules (no global prosperon object), Pit language,
script+JSON entity model. Added entities.md, front matter to all
70+ API docs, and updated API index for current module architecture.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-23 18:09:55 -06:00
parent 1619122a58
commit 83b798e365
106 changed files with 2749 additions and 492 deletions

View File

@@ -1,54 +1,148 @@
# Program events and an example input system
---
title: "Input"
type: docs
---
Prosperon provides a handy `input` module. Input is done in a highly generic and customizable manner. *players* can take control of any object (actor or otherwise) in Prosperon, after which it is referred to as a *pawn* of a player. If the object has a defined *input* object, it is a valid pawn. One player can have many pawns, but each pawn may have only one player.
# Input
Pawns are added as a stack, with the newest ones getting priority, and handled first. It is possible for pawns to block input to lower pawns on the stack.
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.
```
*newest*
car <== When a key is pressed, this is the first pawn to handle input
player
ui <== /block/ is set to true here, so editor recieves no input!
editor
*oldest*
```
## Actions
The default player can be obtained with `Player.players[0]`. Players are all local, and the highest number is determined by platform.
An action is a named game event like `"jump"`, `"attack"`, or `"ui_up"`. Multiple physical inputs can trigger the same action:
The **input** object defines a number of keys or actions, with their values being functions.
## Editor input
The editor input style defines keystrokes. It is good for custom editors, or any sort of game that requires many hotkeys. Keystrokes are case sensitive and can be augmented with auxiliary keys.
| symbol | key |
|--------|-------|
| C | ctrl |
| M | alt |
| S | super |
```
```javascript
var input = use('input')
var orc = this.spawn('orc');
orc.inputs = {};
orc.inputs.a = function() { ... };
orc.inputs.A = function() { ... }; /* This is only called with a capital A! */
orc.inputs['C-a'] = function() { ... }; /* Control-a */
input.players[0].control(orc); /* player 0 is now in control of the orc */
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']
}
})
```
The input object can be modified to customize how it handles input.
Default actions are provided for common UI navigation (`ui_up`, `ui_down`, `ui_left`, `ui_right`, `confirm`, `cancel`, `menu`).
| property | type | effect |
|----------------|----------|--------------------------------------|
| post | function | called after any input is processed |
| =release_post= | function | called after any input is released |
| fallthru | bool | false if input should stop with this |
| block | bool | true if input should stop with this |
## Players and Users
The input can be modified by setting properties on the associated function.
The input system supports multiple players. Each **user** has:
| property | type | effect |
|----------|----------|--------------------------------------------------------|
| released | function | Called when the input is released |
| rep | bool | true if holding the input should repeatedly trigger it |
| down | function | called while the input is down |
- 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
}
})
```