# GameLib API reference

All exports. Units: `px` screen pixels, `cell` grid units (one cell is always 16 px), time in seconds. Every dot on screen is the same size; assets are never scaled.

## Running

### `run(game, {canvas, seed?, onError?}) → Player`

Starts a game on a 256x256 canvas. `seed` defaults to 1. `onError` receives errors thrown by the game.

| Player method | Effect |
| --- | --- |
| `setInput(key, down, source?)` | Press or release a button. `source` separates inputs, e.g. `'pad'` and `'keyboard'`. |
| `release()` | Release all buttons. |
| `pause(paused = true)` | Stop or resume updates. Drawing continues; paused time is not caught up. |
| `inspect()` | Copy of the current state (or `game.inspect(state)`). |
| `restart()` | Re-run `init` with the same seed. |
| `stop()` | Stop updates and input. Call before removing the canvas. |

### `createSimulation(game, {seed?}) → Simulation`

Runs a game without a canvas. Methods: `step()` advances one tick and returns the state, `state()`, `world()`, `inspect()`, `restart()`, `setInput(key, down, source?)`, `release()`, `input`.

### `gameControls(game) → {directions, buttons}`

On-screen controls declared by `game.controls`, with defaults filled in.

### `version`

Engine version string.

## Game

```ts
const game = {
  view: 'front',                  // 'front' | 'side'
  controls: {directions: true, buttons: ['a', 'b']},
  init({seed}) { return state },
  step(state, input, world, dt) { return nextState },
  draw(state, g, world) {},
  inspect(state) { return debugObject },
}
```

### `input`

| Method | Returns |
| --- | --- |
| `down(key)` | `true` while held. |
| `pressed(key)` | `true` on the first tick of a press. Taps between ticks count once. |
| `repeat(key, delay = 0.3, interval = 0.1)` | `true` on press, then every `interval` after `delay`. |
| `vector()` | `{x, y}` from the direction buttons, diagonal normalized to length 1. |

Keys: `up down left right a b x y`.

### `world`

`time` (seconds), `tick`, `seed`. Always: `caps` all `false`, `me {id: null, peer: null}`, `peers []`, `events []`, `docs {}`, `isHost true`.

## Drawing

### `g` (Gfx, passed to `draw`)

| Member | Effect |
| --- | --- |
| `width`, `height` | `256` |
| `view` | The game view. |
| `clear(color = 'paper')` | Fill the screen. |
| `rect(x, y, w, h, color = 'ink')` | Filled rectangle, px. |
| `sprite(name, x, y, {flip?})` | Draw an asset at 1x with its top-left at `x, y`. There is no scaling: every dot on screen is the same size. |
| `hero(x, y, {pose?, direction?, time?, flip?})` | Draw the hero for the current view. `pose` `idle/walk/jump/happy/hurt`; `direction` `down-left/down-right/up-left/up-right` (side uses only left/right); `time` animates walking and idle breathing; pass `world.time` always. |
| `text(text, x, y, color = 'ink')` | 8x8 pixel font. |
| `measureText(text) → number` | Text width in px. |
| `project(x, y, height?)` | Legacy pixel projection. Prefer `worldToScreen`. |

### `createGraphics(context, {view?}) → Gfx`

Gfx for your own 2D canvas context.

### `palette`, `sprites`, `assetCatalog`

`palette`: color name to hex. `sprites`: asset name to rows of pixel characters. `assetCatalog`: `{id, label, group, size, height?, view?, alternate?}` for every asset.

## Worlds

### `defineWorld(options) → scene`

| Option | Default | Meaning |
| --- | --- | --- |
| `view` | `'front'` | Asset style: `'front'` or `'side'`. |
| `projection` | `view` | How grid coordinates map to the screen. |
| `columns`, `rows` | | World size in cells. |
| `origin` | `{x: 8, y: 8}` | Screen position of cell `(0, 0)`. |
| `floor` | `true` (`false` for side) | Draw floor tiles. |
| `objects` | `[]` | Static `PlacedObject`s. |

The scene is frozen plain data. Keep moving things in game state and pass them to `drawWorld`.

`PlacedObject`: `{sprite, x, y, z?, solid?, layer?, flip?, footLift?, pose?, direction?}`. `x, y` are cells at the object's feet. `sprite: 'hero'` draws the hero. `solid` blocks movement. `layer` orders drawing. `footLift` raises the drawing in px without changing physics.

### `drawWorld(g, scene, {objects?, time?, camera?})`

Draws floor, static objects and the given objects. Order: `layer`, then `y` (front); side draws in the given order. `camera {x, y}` is in px.

### `drawPlatforms(g, scene, platforms, {camera?})`

Draws platforms for side-scrolling worlds, using the same data as `movePlatformer`.

### Coordinates

| Function | Returns |
| --- | --- |
| `worldToScreen(scene, x, y, z = 0)` | Cell to px. |
| `screenToWorld(scene, x, y)` | px on the ground to cell. |
| `snapToGrid(x, y)` | Nearest integer cell. |
| `insideWorld(scene, x, y)` | Inside the world bounds. |
| `blockedAt(scene, x, y, radius = 0.25)` | Overlaps a `solid` object. |
| `worldMovement(scene, vector, speed)` | Screen direction to a world velocity in cells/s. |
| `spriteAnchor(name)` | The feet point of an asset in px. |

## Maps

### `defineMap(rows, {legend?, ...worldOptions}) → map`

Parses an ASCII map into a scene with `tiles` and `start`.

| Char | Kind | Asset |
| --- | --- | --- |
| `#` | solid wall | `block` |
| `@` | `start` | |
| `*` | `collectible` | `coin` |
| `>` | `exit` | `door` |
| `!` | `hazard` | `spikes` |
| `$` | `crate` | `crate` |
| `o` | `switch` | `switch` |
| `k` | `key` | `key` |
| `D` | `door` | `door-closed` |
| `~` | solid | `water` |
| `.` or space | empty | |

`legend: {T: {sprite: 'tree', solid: true}}` adds or overrides characters. Kinds are labels only; picking up keys or opening doors is game logic. Unknown characters and uneven rows throw.

### `mapTiles(map, charOrKind) → Tile[]`

Tiles by character or kind: `{symbol, kind, id, x, y, sprite, ...}`.

## Movement

### `moveOnGrid(scene, state, vector, dt, {speed = 4, space = 'screen'})`

Cell-to-cell movement. Pass `{x, y, target}`; returns `{x, y, target, moving}`. Releasing input finishes the current cell. Turns happen at cell centers. Blocked by edges and `solid` objects. Keep `target` in state.

### `moveInWorld(scene, state, vector, dt, {speed = 4, radius = 0.28, space = 'screen'})`

Free movement that slides along walls. Returns `{x, y, moving, blocked, direction}`. Large moves are split so walls are not skipped.

### `movePlatformer(state, {x, jump, hold}, platforms, dt, options)`

Platform physics, tuned by default. Pass `x: input.vector().x`, `jump: input.pressed('a')`, `hold: input.down('a')`. Releasing `hold` while rising cuts the jump short; omit `hold` for always-full jumps.

`state`: `{x, y}` at the feet center, plus the returned `vx, vy, grounded, coyote, buffer, direction`. Returns these and `moving, hitWall, hitCeiling, jumped, landed`. Keep all of them in state.

Platforms: `{x, y, w, h = 1, oneWay?}` in cells; `y` is the top surface. `oneWay` platforms can be passed from below.

Defaults need no tuning: max jump about 3 cells high and 5 cells across.

| Option | Default | Meaning |
| --- | --- | --- |
| `width` | `0.5` | body width, cells |
| `height` | `1.25` | body height, cells |
| `speed` | `7` | max run speed, cells/s |
| `acceleration` | `70` | ground acceleration |
| `airAcceleration` | `45` | air control |
| `friction` | `90` | stopping and turning on ground |
| `jump` | `14.5` | jump velocity |
| `gravity` | `34` | gravity while rising |
| `fallGravity` | `52` | gravity while falling |
| `jumpCut` | `2.5` | gravity multiplier after releasing `hold` |
| `maxFall` | `18` | max fall speed |
| `coyote` | `0.1` | seconds a jump is allowed after leaving a ledge |
| `buffer` | `0.12` | seconds a jump press is remembered before landing |
| `stopOnLand` | `false` | zero horizontal speed on landing |

### `hopPatrol(time, {from, to, period = 1.1, hop = 0.9, offset = 0, view = 'side'})`

Slime that hops back and forth between `from` and `to` (cells). It moves only while airborne. Returns `{x, sprite, flip, airborne, direction}`; draw `{sprite, flip, x, y}` with `drawWorld`. The hop height is in the sprite, so keep `y` on the ground. Use different `offset`s so slimes do not hop in sync.

## Camera and effects

### `followCamera(previous, target, dt, {width = 256, height = 256, worldWidth?, worldHeight?, smoothing = 12})`

Moves the camera toward `target` (px) and clamps it to the world. Keep the result in state.

### `burst(x, y, {count = 8, seed = 1, speed = 28, life = 0.4, size = 2, color = 'ink'})`

Creates up to 64 particles at px `x, y`.

### `stepParticles(particles, dt, gravity = 24)`

Moves particles and removes expired ones.

### `drawParticles(g, particles, camera?)`

Draws particles, shrinking with age.

### `effect(name, since, time, {fps = 15})`

Sprite for a one-shot effect started at `since` (s), or `null` once it has finished. `name`: `hit` (attack lands), `slash` (sword swing), `poof` (enemy defeated), `dust` (jump or landing), `explode`. Keep `{n, x, y, t}` items in state, drop them when this returns `null`, and draw `{sprite, x, y}` with `drawWorld`.

### `animate(name, motion, time, {fps = 8})`

Sprite name for a creature's 4-frame motion at `time`: `animate('bat', 'move', t)` → `bat-move1..4`. `motion`: `idle / move / attack / hurt`. Works for every creature, `slime`, `side-slime` and `big-slime`.

### `blink(time, since, {duration = 1, rate = 15})`

Invincibility flicker after damage at `since`. Returns `false` on hidden frames; draw the character only when it is `true`. Use the same `duration` to ignore further damage.

### `shake(time, since, {power = 3, duration = 0.25})`

Screen shake started at `since`. Returns a px `{x, y}` that fades to 0; add it to the camera when drawing, not in state.

### `drawHud(g, {score?, total?, hearts?, title?, hint?, status?})`

Draws score, hearts and a hint in the top 40 px. A non-empty `status` shows a centered result panel.

## Math

| Function | Returns |
| --- | --- |
| `random(seed, index = 0)` | Deterministic number in `[0, 1)`. |
| `clamp(value, min, max)` | `value` limited to the range. |
| `approach(value, target, amount)` | `value` moved toward `target` by at most `amount`. |
| `distance(a, b)` | Distance between points. |
| `overlaps(a, b)` | Whether `{x, y, w, h}` rectangles overlap. Touching edges do not count. |
| `facing(dx, dy, previous?)` | Hero direction for a movement. |

## Legacy

`createWorld`, `project(view, x, y, height?)` and `views` remain for old shared games. Use `defineWorld` and `worldToScreen`.
