# Eden Live 5B Game

> Real-time games rendered using VAST's Eden Live 5B


## Overview

- **Endpoint**: `https://fal.run/vast/eden-live-5b-game`
- **Model ID**: `vast/eden-live-5b-game`
- **Category**: worlds
- **Kind**: inference


## Pricing

Sessions cost $0.0035 per second of video generated, with a minimum of 10 billable seconds ($0.035) per session.

For more details, see [fal.ai pricing](https://fal.ai/pricing).

## Realtime API (WMA/WebRTC)

This endpoint publishes a WMA WebRTC contract. Open it with `fal.realtime.open`; do **not** call the session endpoint with `fal.run`, `fal.subscribe`, or the Queue API.

The browser negotiates through fal and then exchanges media with the model over WebRTC.

Client contract for the WebRTC session created by the linked OpenAPI operation.


### Install the experimental client

```bash
npm install @fal-ai/client@alpha @fal-ai/server-proxy@alpha
```

### Authentication and server proxy

Keep `FAL_KEY` on your server. Expose an authenticated proxy route to the browser. In a Next.js App Router application, create `app/api/fal/proxy/route.ts`:

```typescript
import { route } from "@fal-ai/server-proxy/nextjs";

export const { GET, POST, PUT } = route;
```

Protect that route with your application's authentication before deploying it.

### Open a browser session

```typescript
import { createFalClient } from "@fal-ai/client";
import { wma } from "@fal-ai/client/realtime";

const fal = createFalClient({ proxyUrl: "/api/fal/proxy" });

const session = fal.realtime.open(wma("vast/eden-live-5b-game"), {
  receive: [
    "video"
  ],
  onMedia: (stream) => {
      const element = document.querySelector("video");
      if (element) element.srcObject = stream;
    },
  onData: (raw) => {
      const message = JSON.parse(raw);
      console.log(message);
    },
  onState: (state) => console.log("realtime:", state),
  onError: (error) => console.error(error),
});


// Consult the session flow and message reference before sending control messages.

// Later, release the peer connection and network resources:
// await session.close();
```

## Session flow

This world starts automatically. Wait for the first video frame before using the movement controls.

Send ` commands ` with held controls in ` active ` and newly pressed controls in ` activated `. Send empty arrays when controls are released or focus leaves the world.

- Send ` configure ` and wait for ` configured ` before sending another world update. Setup is optional and can be used once per session.
- Send ` reset ` and wait for ` reset_applied ` before sending another world update.
- Send ` prompt ` and wait for ` prompt_applied ` before sending another world update.

World updates run one at a time and must not be replayed automatically. A ` error ` event is diagnostic and does not identify a failed update; read ` /error ` for details. The session ends on ` stream_exhausted `.


## Media contract

Tracks are described from the browser's perspective.

### Browser sends to the model

None.

### Browser receives from the model

- `video` — optional
  - Settings: `{"frameRate":24,"height":704,"width":1280}`

## Client-to-model control messages

### Game action

- **Wire type**: `action`
- **Payload**: `object`

A game UI action, e.g. a "Play again" or "Pause" button.

- **`action`** (`string`, _required_)
  One of the game's actions from session_info (restart, pause).
  - Constraints: minLength=1, maxLength=32
- **`type`** (`string`, _required_)
  - Constant: `"action"`
- Additional properties: not allowed

**Example**

```json
{
  "action": "restart",
  "type": "action"
}
```

### Controls

- **Wire type**: `commands`
- **Payload**: `object`

Semantic command-state report.

``active`` contains commands currently held by the user and ``activated``
contains edge-triggered commands since the previous report. A browser may
map a keyboard, gamepad, touch control, or agent action to these names.

- **`active`** (`string[]`, _optional_)
  - Constraints: maxItems=14
  - Array items: `string`
    - Values: `"forward"`, `"backward"`, `"left"`, `"right"`, `"look_up"`, `"look_down"`, `"look_left"`, `"look_right"`, `"fire"`, `"jump"`, `"ability_1"`, `"ability_2"`, `"ability_3"`, `"ability_4"`
- **`activated`** (`string[]`, _optional_)
  - Constraints: maxItems=14
  - Array items: `string`
    - Values: `"forward"`, `"backward"`, `"left"`, `"right"`, `"look_up"`, `"look_down"`, `"look_left"`, `"look_right"`, `"fire"`, `"jump"`, `"ability_1"`, `"ability_2"`, `"ability_3"`, `"ability_4"`
- **`type`** (`string`, _required_)
  - Constant: `"commands"`

**Example**

```json
{
  "active": [
    "forward",
    "fire"
  ],
  "activated": [],
  "type": "commands"
}
```

### Choose game

- **Wire type**: `configure`
- **Payload**: `object`

Pick the game and how it is presented, once per connection; await ``configured``.

- **`game`** (`string | null`, _optional_)
  Game id from /game/info. Defaults to the first game.
  - Default: `null`
  - anyOf alternatives:
    1. `string`
      - Values: `"freeze"`, `"spiders"`, `"pulse"`, `"deepwater"`, `"kaiju"`, `"arcadeduel"`, `"desert"`, `"snowball"`, `"puppy"`, `"cat"`, `"drone"`, `"herding"`
    2. `null`
- **`hud`** (`string`, _optional_)
  'baked' draws the game's HUD into the video; 'client' only sends game_state messages so the client draws its own UI; 'none' sends neither.
  - Default: `"baked"`
  - Values: `"baked"`, `"client"`, `"none"`
- **`autopilot`** (`boolean`, _optional_)
  Let the game play itself; held player input overrides it.
  - Default: `false`
- **`prompt`** (`string | null`, _optional_)
  Override the game's built-in scene description.
  - Default: `null`
  - anyOf alternatives:
    1. `string`
      - Constraints: maxLength=2000
    2. `null`
- **`image_url`** (`string | null`, _optional_)
  Override the game's photoreal opening frame.
  - Default: `null`
  - anyOf alternatives:
    1. `string`
      - Constraints: maxLength=60000
    2. `null`
- **`seed`** (`integer | null`, _optional_)
  - Default: `null`
  - anyOf alternatives:
    1. `integer`
      - Constraints: minimum=0, maximum=2147483647
    2. `null`
- **`condition_capture`** (`string`, _optional_)
  Resolution the game frames the model conditions on are captured at: 'output', 'encoder' (the control encoder's input, which every capture is resized to) or 'encoder_half'. Smaller captures render faster; sizes are in /game/info.
  - Default: `"output"`
  - Values: `"output"`, `"encoder"`, `"encoder_half"`
- **`dynamic_prompt`** (`boolean`, _optional_)
  Before each chunk, re-encode the prompt as the scene description plus the game's description of what happened in that chunk (shots, hits, turns). Adds the text-encode time to input latency on chunks whose description changed.
  - Default: `true`
- **`type`** (`string`, _required_)
  - Constant: `"configure"`
- Additional properties: not allowed

**Example**

```json
{
  "condition_capture": "output",
  "game": "freeze",
  "autopilot": false,
  "dynamic_prompt": true,
  "type": "configure",
  "hud": "baked"
}
```

### Client input message

- **Wire type**: `input`
- **Payload**: `object`

Ordered raw input events for custom game clients.

Clicks on the baked HUD arrive as ``pointer`` presses (see ``MessageUI``).

- **`events`** (`object[]`, _required_)
  - Constraints: minItems=1, maxItems=64
  - Array items: `object`
    One raw input event; see ``GameController.push_input``.
    - **`x`** (`number | null`, _optional_)
      - Default: `null`
      - anyOf alternatives:
        1. `number`
          - Constraints: minimum=0, maximum=1
        2. `null`
    - **`kind`** (`string`, _optional_)
      - Default: `"key"`
      - Values: `"key"`, `"action"`, `"pointer"`
    - **`y`** (`number | null`, _optional_)
      - Default: `null`
      - anyOf alternatives:
        1. `number`
          - Constraints: minimum=0, maximum=1
        2. `null`
    - **`name`** (`string`, _required_)
      - Constraints: minLength=1, maxLength=32
    - **`phase`** (`string`, _optional_)
      - Default: `"press"`
      - Values: `"down"`, `"up"`, `"press"`
    - Additional properties: not allowed
- **`type`** (`string`, _required_)
  - Constant: `"input"`
- Additional properties: not allowed

**Example**

```json
{
  "events": [
    {
      "name": "string"
    }
  ],
  "type": "input"
}
```

### Client keys message

- **Wire type**: `keys`
- **Payload**: `object`

Legacy physical-key report retained for existing WMA clients.

- **`activated`** (`string[]`, _optional_)
  - Constraints: maxItems=16
  - Array items: `string`
    - Values: `"W"`, `"A"`, `"S"`, `"D"`, `"ARROWUP"`, `"ARROWDOWN"`, `"ARROWLEFT"`, `"ARROWRIGHT"`, `"F"`, `" "`, `"E"`, `"SHIFT"`, `"R"`, `"G"`, `"P"`, `"ESCAPE"`
- **`pressed`** (`string[]`, _optional_)
  - Constraints: maxItems=16
  - Array items: `string`
    - Values: `"W"`, `"A"`, `"S"`, `"D"`, `"ARROWUP"`, `"ARROWDOWN"`, `"ARROWLEFT"`, `"ARROWRIGHT"`, `"F"`, `" "`, `"E"`, `"SHIFT"`, `"R"`, `"G"`, `"P"`, `"ESCAPE"`
- **`type`** (`string`, _required_)
  - Constant: `"keys"`

**Example**

```json
{
  "type": "keys"
}
```

### Client ping message

- **Wire type**: `ping`
- **Payload**: `object`

Latency probe; the server echoes ``ts`` back in a ``pong`` payload.

- **`ts`** (`number | null`, _optional_)
  - Default: `null`
- **`type`** (`string`, _required_)
  - Constant: `"ping"`

**Example**

```json
{
  "type": "ping"
}
```

### Update prompt

- **Wire type**: `prompt`
- **Payload**: `object`

Change the scene description; applied at the next chunk boundary.

- **`prompt`** (`string`, _required_)
  Text the model renders the scene with. Keeps the current world.
  - Constraints: minLength=1, maxLength=2000
- **`type`** (`string`, _required_)
  - Constant: `"prompt"`
- Additional properties: not allowed

**Example**

```json
{
  "prompt": "string",
  "type": "prompt"
}
```

### Restart

- **Wire type**: `reset`
- **Payload**: `object`

Restart the round (and the model), optionally switching game or settings.

- **`game`** (`string | null`, _optional_)
  Game id from /game/info. Defaults to the first game.
  - Default: `null`
  - anyOf alternatives:
    1. `string`
      - Values: `"freeze"`, `"spiders"`, `"pulse"`, `"deepwater"`, `"kaiju"`, `"arcadeduel"`, `"desert"`, `"snowball"`, `"puppy"`, `"cat"`, `"drone"`, `"herding"`
    2. `null`
- **`prompt`** (`string | null`, _optional_)
  Override the game's built-in scene description.
  - Default: `null`
  - anyOf alternatives:
    1. `string`
      - Constraints: maxLength=2000
    2. `null`
- **`image_url`** (`string | null`, _optional_)
  Override the game's photoreal opening frame.
  - Default: `null`
  - anyOf alternatives:
    1. `string`
      - Constraints: maxLength=60000
    2. `null`
- **`seed`** (`integer | null`, _optional_)
  - Default: `null`
  - anyOf alternatives:
    1. `integer`
      - Constraints: minimum=0, maximum=2147483647
    2. `null`
- **`condition_capture`** (`string | null`, _optional_)
  - Default: `null`
  - anyOf alternatives:
    1. `string`
      - Values: `"output"`, `"encoder"`, `"encoder_half"`
    2. `null`
- **`type`** (`string`, _required_)
  - Constant: `"reset"`
- **`hud`** (`string | null`, _optional_)
  - Default: `null`
  - anyOf alternatives:
    1. `string`
      - Values: `"baked"`, `"client"`, `"none"`
    2. `null`
- **`autopilot`** (`boolean | null`, _optional_)
  - Default: `null`
- **`dynamic_prompt`** (`boolean | null`, _optional_)
  - Default: `null`
- Additional properties: not allowed

**Example**

```json
{
  "game": "freeze",
  "type": "reset"
}
```

### End session

- **Wire type**: `stop`
- **Payload**: `object`

End the session.

- **`type`** (`string`, _required_)
  - Constant: `"stop"`
- Additional properties: not allowed

**Example**

```json
{
  "type": "stop"
}
```

## Model-to-client control messages

### Server configured message

- **Wire type**: `configured`
- **Payload**: `object`

- **`game`** (`object | null`, _optional_)
  - Default: `null`
  - anyOf alternatives:
    1. `object`
      - **`prompt`** (`string`, _required_)
      - **`thumbnail_url`** (`string | null`, _optional_)
        - Default: `null`
      - **`description`** (`string`, _required_)
      - **`instructions`** (`string[]`, _required_)
        - Array items: `string`
      - **`title`** (`string`, _required_)
      - **`controls`** (`object[]`, _required_)
        - Array items: `object`
          - **`label`** (`string`, _required_)
          - **`command`** (`string | null`, _optional_)
            Semantic command name.
            - Default: `null`
          - **`key`** (`string`, _required_)
          - **`hold`** (`boolean`, _optional_)
            - Default: `true`
      - **`actions`** (`string[]`, _required_)
        - Array items: `string`
      - **`id`** (`string`, _required_)
    2. `null`
- **`type`** (`string`, _required_)
  - Constant: `"configured"`

**Example**

```json
{
  "type": "configured"
}
```

### Server controls_state message

- **Wire type**: `controls_state`
- **Payload**: `object`

The current game's complete control set, sent after ``configured`` and
``reset_applied`` and whenever the game changes its controls mid-round.

Only controls with a ``command`` can be pressed with ``commands``; clients
show and bind those, and drop the rest of the vocabulary.

- **`pointer`** (`string | null`, _optional_)
  Mouse input the client should offer: 'click' presses buttons the baked HUD draws; absent offers none.
  - Default: `null`
  - anyOf alternatives:
    1. `string`
      - Values: `"click"`, `"capture"`
    2. `null`
- **`controls`** (`object[]`, _required_)
  - Array items: `object`
    - **`label`** (`string`, _required_)
    - **`command`** (`string | null`, _optional_)
      Semantic command name.
      - Default: `null`
    - **`key`** (`string`, _required_)
    - **`hold`** (`boolean`, _optional_)
      - Default: `true`
- **`type`** (`string`, _required_)
  - Constant: `"controls_state"`

**Example**

```json
{
  "controls": [],
  "type": "controls_state"
}
```

### Server error message

- **Wire type**: `error`
- **Payload**: `object`

- **`retryable`** (`boolean | null`, _optional_)
  - Default: `null`
- **`type`** (`string`, _required_)
  - Constant: `"error"`
- **`error`** (`string`, _required_)

**Example**

```json
{
  "type": "error",
  "error": "string"
}
```

### Server game_state message

- **Wire type**: `game_state`
- **Payload**: `object`

Game state at an output frame; frames are numbered from session start.

- **`type`** (`string`, _required_)
  - Constant: `"game_state"`
- **`round`** (`integer`, _required_)
- **`frame`** (`integer`, _required_)
- **`state`** (`object | null`, _required_)

**Example**

```json
{
  "type": "game_state",
  "round": 0,
  "frame": 0,
  "state": {}
}
```

### Server pong message

- **Wire type**: `pong`
- **Payload**: `object`

Reply to a ``ping``, echoing the client's timestamp for RTT measurement.

The echoed timestamp has two wire spellings: apps that handle ``ping``
themselves echo ``ts``; the fallback handler in
:class:`registry.wma.sdk.Session` replies with ``client_ts``. Clients read
whichever is present. ``server_ts`` is the (unsynchronized) runner clock; it
only shows how the round trip divides once the client has an offset estimate.

- **`client_ts`** (`number | null`, _optional_)
  - Default: `null`
- **`server_ts`** (`number | null`, _optional_)
  - Default: `null`
- **`ts`** (`number | null`, _optional_)
  - Default: `null`
- **`type`** (`string`, _required_)
  - Constant: `"pong"`

**Example**

```json
{
  "type": "pong"
}
```

### Server prompt_applied message

- **Wire type**: `prompt_applied`
- **Payload**: `object`

- **`type`** (`string`, _required_)
  - Constant: `"prompt_applied"`

**Example**

```json
{
  "type": "prompt_applied"
}
```

### Server reset_applied message

- **Wire type**: `reset_applied`
- **Payload**: `object`

- **`game`** (`object | null`, _optional_)
  - Default: `null`
  - anyOf alternatives:
    1. `object`
      - **`prompt`** (`string`, _required_)
      - **`thumbnail_url`** (`string | null`, _optional_)
        - Default: `null`
      - **`description`** (`string`, _required_)
      - **`instructions`** (`string[]`, _required_)
        - Array items: `string`
      - **`title`** (`string`, _required_)
      - **`controls`** (`object[]`, _required_)
        - Array items: `object`
          - **`label`** (`string`, _required_)
          - **`command`** (`string | null`, _optional_)
            Semantic command name.
            - Default: `null`
          - **`key`** (`string`, _required_)
          - **`hold`** (`boolean`, _optional_)
            - Default: `true`
      - **`actions`** (`string[]`, _required_)
        - Array items: `string`
      - **`id`** (`string`, _required_)
    2. `null`
- **`type`** (`string`, _required_)
  - Constant: `"reset_applied"`

**Example**

```json
{
  "type": "reset_applied"
}
```

### Server session_info message

- **Wire type**: `session_info`
- **Payload**: `object`

- **`info`** (`object`, _required_)
- **`session`** (`string`, _required_)
  - Values: `"video"`, `"game"`
- **`type`** (`string`, _required_)
  - Constant: `"session_info"`

**Example**

```json
{
  "info": {},
  "session": "video",
  "type": "session_info"
}
```

### Server stats message

- **Wire type**: `stats`
- **Payload**: `object`

- **`prompt_ms`** (`number | null`, _optional_)
  Per-chunk prompt update time with dynamic_prompt, unchanged chunks included (moving average).
  - Default: `null`
- **`generate_ms`** (`number | null`, _optional_)
  Model time per chunk (moving average).
  - Default: `null`
- **`pipelined`** (`boolean | null`, _optional_)
  The next chunk renders while this one generates (throughput mode).
  - Default: `null`
- **`render_ms`** (`number | null`, _optional_)
  Game render time per chunk (moving average).
  - Default: `null`
- **`realtime_factor`** (`number`, _required_)
  Generated frames per second / target fps.
- **`billable_units`** (`number | null`, _optional_)
  Seconds of video billed so far this session (queued for playback); the final total settles when the session closes.
  - Default: `null`
- **`latency_ms`** (`number | null`, _optional_)
  Input or control capture to frame handoff, median.
  - Default: `null`
- **`chunk_ms`** (`number`, _required_)
- **`type`** (`string`, _required_)
  - Constant: `"stats"`
- **`input_latency_ms`** (`number | null`, _optional_)
  Game control message arrival to the handoff of the first frame it changes, median.
  - Default: `null`
- **`chunk`** (`integer`, _required_)
- **`loop_lag_ms`** (`number | null`, _optional_)
  Server event-loop lag, p95 over the stats window.
  - Default: `null`
- **`queue_frames`** (`integer`, _required_)
- **`generation_fps`** (`number`, _required_)

**Example**

```json
{
  "realtime_factor": 0,
  "chunk_ms": 0,
  "type": "stats",
  "chunk": 0,
  "queue_frames": 0,
  "generation_fps": 0
}
```

### Server stream_exhausted message

- **Wire type**: `stream_exhausted`
- **Payload**: `object`

The model has no more frames to send and the current peer is closing.
Clients must negotiate a new session to continue.

- **`type`** (`string`, _required_)
  - Constant: `"stream_exhausted"`

**Example**

```json
{
  "type": "stream_exhausted"
}
```

## Additional Resources

### Documentation

- [Model Playground](https://fal.ai/models/vast/eden-live-5b-game)
- [API Documentation](https://fal.ai/models/vast/eden-live-5b-game/api)
- [OpenAPI Schema](https://fal.ai/api/openapi/queue/openapi.json?endpoint_id=vast/eden-live-5b-game)
- [AsyncAPI Contract](https://fal.ai/api/apps/fal-ai/eden-live-5b-game/asyncapi.json)

### fal.ai Platform

- [Platform Documentation](https://fal.ai/docs/documentation)
- [Python Client](https://fal.ai/docs/api-reference/client-libraries/python)
- [JavaScript Client](https://fal.ai/docs/api-reference/client-libraries/javascript)

### Other agent-readable surfaces

This file covers one model. To find anything else:

- [Platform overview](https://fal.ai/llms.txt): Entry points and representative endpoint IDs
- [Documentation index](https://fal.ai/docs/llms.txt): Every documentation page
- [Full documentation text](https://fal.ai/docs/llms-full.txt): The whole documentation inlined
- Any other model: `https://fal.ai/models/<endpoint-id>/llms.txt`
