# Game object

```ts
type Game<S> = {
  view?: 'front' | 'side' // 'iso' and 'depth' are in development
  controls?: Controls | false
  init(context: {seed: number; me: {id: null; peer: null}}): S
  step(state: S, input: Input, world: World, dt: number): S
  draw(state: S, graphics: Gfx, world: World): void
  inspect?(state: S): object
}
```

## State

JSON-compatible data only: no functions, canvases or connections. `init` and `step` have no side effects and never mutate the previous state.

## Time

`step` runs at 60Hz, `dt = 1/60`.

| Value | Meaning |
| --- | --- |
| `world.time` | seconds from completed ticks |
| `world.tick` | completed ticks |
| `world.seed` | seed, default 1 |
| `world.caps` | `save / shared / room / ai`, all `false` |

## Player (standalone HTML only)

```js
const player = GameLib.run(game, {canvas, seed: 42})
player.inspect()      // state copy
player.restart()      // same seed
player.pause()        // pause(false) resumes
player.stop()         // stop updates and input
```

One player per canvas. Call `stop()` before removing the canvas.

## Headless

```js
const simulation = GameLib.createSimulation(game, {seed: 42})
simulation.setInput('right', true)
for (let tick = 0; tick < 60; tick++) simulation.step()
simulation.inspect()
```

Same seed and inputs give the same result.
