---
slug: "pi-worlds"
source_type: "readme"
source_url: "https://cdn.jsdelivr.net/gh/minghinmatthewlam/pi-worlds@main/README.md"
repo: "https://github.com/minghinmatthewlam/pi-worlds"
source_file: "README.md"
branch: "main"
---
# pi-worlds

Generate navigable 3D worlds from text or images inside [pi](https://github.com/badlogic/pi-mono), powered by the [World Labs Marble API](https://docs.worldlabs.ai/).

<p align="center">
  <a href="https://marble.worldlabs.ai/world/e7f22b4f-7235-49ba-875a-4069a49b993e">
    <img src="assets/demo-world.webp" alt="Generated coffee shop world" width="700">
  </a>
  <br>
  <em>A cozy coffee shop generated from a text prompt — <a href="https://marble.worldlabs.ai/world/e7f22b4f-7235-49ba-875a-4069a49b993e">click to explore in 3D</a></em>
</p>

## Install

```bash
pi install npm:pi-worlds
```

Or from git:

```bash
pi install git:github.com/minghinmatthewlam/pi-worlds
```

## Setup

Get an API key at [platform.worldlabs.ai/api-keys](https://platform.worldlabs.ai/api-keys) (requires a $5 minimum credit purchase).

```bash
export WORLD_LABS_API_KEY=your-key-here
```

Add to your shell profile (`.zshrc`, `.bashrc`) to persist across sessions.

## Tools

| Tool | Description |
|------|-------------|
| `generate_world` | Generate a 3D world from text or an image URL. Returns a `world_marble_url` for viewing in any browser. Supports blocking mode with progress updates or async mode. |
| `get_world` | Retrieve details and assets for an existing world by ID. |
| `list_worlds` | List previously generated worlds with optional filters (status, model, tags). |
| `delete_world` | Permanently delete a world by ID. |

## Usage

### Generate from text

```
> generate a cozy coffee shop with warm lighting and exposed brick walls

generate_world "cozy coffee shop with warm lighting and exposed brick walls" (Marble 0.1-plus)
  Generating world... 45%
  Generating world... 80%
  World generated successfully.

  World ID: w_abc123
  Preview: https://marble.worldlabs.ai/world/w_abc123
  Model: Marble 0.1-plus
  Caption: A cozy coffee shop with warm ambient lighting...
```

Click the preview URL to explore the world in 3D directly in your browser.

### Generate from image

```
> generate a world from this image: https://example.com/warehouse.jpg

generate_world (Marble 0.1-plus)
  image: https://example.com/warehouse.jpg
  World generated successfully.

  Preview: https://marble.worldlabs.ai/world/w_def456
```

### Async mode

```
> generate a hospital corridor, don't wait for it

generate_world "hospital corridor" (Marble 0.1-plus, async)
  Generation started -> op_xyz789

> check on world w_ghi012

get_world w_ghi012
  World generated successfully.
  Preview: https://marble.worldlabs.ai/world/w_ghi012
```

### List and manage

```
> list my worlds

list_worlds
  Found 3 world(s):
  1. w_abc123 - Coffee Shop (Marble 0.1-plus, 3/27/2026)
     https://marble.worldlabs.ai/world/w_abc123
  2. w_def456 - Warehouse (Marble 0.1-plus, 3/27/2026)
     https://marble.worldlabs.ai/world/w_def456
  ...
```

## Models

| Model | Speed | Cost | Use When |
|-------|-------|------|----------|
| `Marble 0.1-mini` | ~1-2 min | ~230 credits ($0.18) | Iterating, testing prompts |
| `Marble 0.1-plus` | ~3-5 min | ~1580 credits ($1.26) | Final quality, production |

## Parameters

### generate_world

| Param | Type | Required | Default | Description |
|-------|------|----------|---------|-------------|
| `prompt` | string | no* | - | Text description (max 2000 chars) |
| `image_url` | string | no* | - | Publicly accessible image URL (jpg, png, webp) |
| `model` | string | no | Marble 0.1-plus | `"Marble 0.1-mini"` or `"Marble 0.1-plus"` |
| `wait` | boolean | no | true | Block with progress updates, or return immediately |
| `seed` | number | no | - | Random seed for reproducibility (0-4294967295) |
| `display_name` | string | no | - | Display name (max 64 chars) |
| `tags` | string[] | no | - | Tags for organizing worlds |

*At least one of `prompt` or `image_url` is required.

### list_worlds

| Param | Type | Required | Description |
|-------|------|----------|-------------|
| `status` | string | no | Filter: `SUCCEEDED`, `PENDING`, `FAILED`, `RUNNING` |
| `model` | string | no | Filter by model |
| `tags` | string[] | no | Filter by tags (matches any) |
| `page_size` | number | no | Results per page (1-100, default 20) |

### get_world / delete_world

| Param | Type | Required | Description |
|-------|------|----------|-------------|
| `world_id` | string | yes | World ID |

## Viewing Worlds

Every generated world gets a `world_marble_url` — a link to World Labs' hosted 3D viewer. Open it in any browser to orbit, zoom, and walk through the world. No installs needed.

For embedding in your own apps, download the `.spz` splat file and use [SparkJS](https://sparkjs.dev/) (THREE.js-based renderer).

## Rate Limits

World Labs allows ~6 generation requests per minute. The extension handles this — if you hit the limit, you'll get a clear error message asking you to wait.

## Development

### Release pipeline

Releases are automated via GitHub Actions. To publish a new version:

1. Bump version in `package.json`
2. Commit and tag: `git tag v0.2.0`
3. Push: `git push && git push --tags`
4. GitHub Actions publishes to npm automatically

**Setup (one-time):**

1. Generate an npm access token at [npmjs.com/settings/tokens](https://www.npmjs.com/settings/tokens)
   - Use "Granular Access Token" type
   - Scope to the `pi-worlds` package with read/write
   - If your npm account uses passkey/2FA, use `--auth-type=web` for manual publishes
2. Add the token as a repo secret: `gh secret set NPM_TOKEN`

### Local development

```bash
# Clone
git clone https://github.com/minghinmatthewlam/pi-worlds
cd pi-worlds

# Test with pi (loads extension from local directory)
pi -e .
```

### Extension structure

```
pi-worlds/
  package.json        # pi.extensions: ["./index.ts"], keywords: ["pi-package"]
  index.ts            # Extension entry — registers tools via pi.registerTool()
  client.ts           # Marble API HTTP client (fetch, polling, error handling)
  types.ts            # TypeBox schemas + TypeScript interfaces
  tools/
    generate-world.ts # Primary tool — text/image to 3D world
    get-world.ts      # Retrieve world details
    list-worlds.ts    # List worlds with filters
    delete-world.ts   # Delete a world
    shared.ts         # Client factory, formatters, error handling
```

### Key conventions for pi extensions

- `package.json` must have `"keywords": ["pi-package"]` and `"pi": { "extensions": ["./index.ts"] }`
- Entry point is a default export function receiving `ExtensionAPI`
- Tools use TypeBox schemas for parameters
- `renderCall` / `renderResult` return `Text` components from `@mariozechner/pi-tui`
- Peer deps: `@mariozechner/pi-coding-agent`, `@mariozechner/pi-tui`, `@sinclair/typebox`
- All source is TypeScript (`.ts`), shipped as-is (no build step)
- Environment variables for API keys, validated lazily on first tool call

## License

MIT
