# Render previews

See blueprint frames and experience layouts as PNG images from the server.

Render an image, inspect it, edit, and render again. No open browser or Studio session is needed. Images use the same deterministic voxel bakers as the client.

## Blueprints

```sh
eggox blueprint render blueprint.json --frame 3 --rotation 90 --output frame-3.png
eggox blueprint render blueprint.json --frame 3 --layers 0,2 --view front --output parts.png
eggox blueprint render --id <owned-prototype-id> --output saved.png
eggox blueprint render blueprint.json --look flat-ink --output flat-ink.png
```

The file form sends your local source for a preview without buying, saving, publishing or minting anything. The `--id` form renders the exact saved iteration you name. Frames and layers are zero-based. Omit `--layers` for the visible composite; explicit layer indices include hidden layers and preserve their original stacking order. Views are `iso` (default), `top` (a plan), and `front`. Rotation is `0`, `90`, `180`, or `270` degrees.

`--look` previews an item filter in any view without changing the source. Choose `normal` (default), `outline`, `inked`, `soft`, `flat`, `sticker`, `flat-ink`, `color-ink`, `soft-ink`, or `chunky`. Flat ink preserves painted colors and adds black overlap lines; Color ink blends a little shading; Soft ink retains more sculpted shading. All three keep color patches crisp.

## Experiences

```sh
eggox push ./my-game
eggox render ./my-game --output overview.png
eggox render ./my-game --room Lobby --room Arena --output rooms.png
eggox render ./my-game --room Arena --bounds 8,10,12,8 --output section.png
eggox render ./my-game --room Arena --focus <placement-id> --margin 2 --output detail.png
eggox render --game "My Game" --state published --view top --output published.png
```

An experience render reads the server's layout. Push local changes first. `--state draft` is the default; `published` uses the most recently published room template. Each room appears in its own labelled panel, with up to 16 rooms per request. Select room ids when names are ambiguous.

`--bounds x,y,width,height` selects a tile rectangle in one room. Models whose footprints overlap the rectangle are included whole, so tall or overhanging items are not cut off. `--focus` selects a placement with a tile margin; it also requires exactly one room and cannot be combined with bounds. Placement ids, tile coordinates, image rectangles and camera transforms are included in the metadata for follow-up renders.

`--view auto` respects each room's view; `iso` and `top` override it. `--rotation` turns the scene. `--time-ms` samples voxel flipbook frames (default `0`). `--hidden` includes hidden stock, drawn ghosted. Placed items use their displayed iteration, position, height, rotation and supported image filters.

These are **layout snapshots**, not a running playtest. Scripts are not executed. Players, HUD, particles, script-painted floors, runtime costumes and live match effects are not included. Missing voxel artwork appears as a marker with a warning. Published layouts reference the displayed item art; this is not an archive of every historic asset byte.

## Output and limits

Both commands write a PNG plus `<output>.json` containing dimensions, selection metadata, warnings and quota. Default filenames are `blueprint.png` and `experience.png`. Existing files are protected; use a new `--output` or explicitly add `--force`.

Common options: `--width`, `--height`, and `--background '#RRGGBB'` or `transparent`. Default output is 1024×768 on a dark background. Each side must be 128–1536 pixels, with at most 1,572,864 pixels total. PNGs are compressed and capped at 2 MB. Heavy scenes may need fewer rooms or a smaller section: each request permits up to 128 distinct assets, 1,024 selected placements per room, and a bounded decoded-voxel workload.

```sh
eggox renders
```

The default allowance is **30 render attempts per account per UTC hour**, shared across blueprints, experiences, CLI installations and OAuth tokens. The server can configure this allowance. `eggox renders` reports the actual limit, remaining renders and reset time without consuming a render. Counters persist across server restarts. Admission consumes a render even if the worker later fails or times out. Authentication, initial option validation and busy-server refusals do not consume one.

An exhausted allowance returns HTTP 429 with `retry_after`, `quota.resets_at`, and `Retry-After`. A busy or unavailable worker returns 503; retry later. The server admits only a small number of concurrent jobs and terminates workers after 20 seconds.

## MCP tools

`eggox_blueprint_render` accepts `file` or `id`, plus `frame`, `layers`, `view`, `look`, `rotation`, `width`, `height`, `background`, `output`, and `force`.

`eggox_render` accepts `dir` or `game`, plus `rooms`, `bounds`, `focus`, `margin`, `state`, `time_ms`, `hidden` and the common image options.

Both return native MCP **image content** plus metadata text, so the agent can see the result immediately. `output` is optional in MCP; omit it to avoid writing files. `eggox_render_quota` checks the shared budget.

## HTTP contract

| Route | Body / result |
| --- | --- |
| `GET /api/dev/renders/quota` | `{quota: {limit, used, remaining, resets_at, retry_after}}` |
| `POST /api/dev/blueprints/render` | `source`: the blueprint upload payload, plus render options |
| `POST /api/dev/blueprints/:id/render` | Blueprint render options; exact owned iteration |
| `POST /api/dev/games/:id/render` | Experience render options; owned root room id |

Successful renders return `{image: {mime_type: "image/png", data: "<base64>", width, height, bytes}, metadata, quota}` with `Cache-Control: no-store`. Use JSON integers for dimensions, frame and rotation; arrays for `layers`, `rooms`, and `bounds`. Blueprint routes require creator scope; experience and quota routes accept games or creator scope. All requests require a bearer token.

