Skip to content

tvanhens/ourcade

Repository files navigation

Ourcade

Ourcade is a multiplayer 3D sandbox where players build the world by prompting it. Walk around a shared 3D space, "cast" a natural-language prompt (e.g. "a red rocket ship" or "a small wooden house"), and a large language model generates a 3D model that streams into the world in real time — visible to everyone connected.

Ourcade demo — prompting a cozy cabin into the world

▶️ Watch the full-quality video

It is two pieces working together:

  • A Godot 4.3 game client (compiled to WebAssembly and played in the browser).
  • A Bun + Hono WebSocket server that drives LLMs to turn prompts into 3D geometry and broadcasts the results to every connected player.

How it works

Player types a prompt in the Godot client
        │  (WebSocket / JSON-RPC)
        ▼
Bun server runs a content filter, then an LLM "agent"
        │  the model streams a list of editor actions:
        │  addBox, addSphere, setMaterial, addOmniLight, addParticles, …
        ▼
Server broadcasts each action as a game event to all players
        ▼
Every Godot client applies the actions incrementally,
building the model live in the shared world

Rather than asking the model for a mesh file, the server asks it for a sequence of editor actions — primitive operations like "add a box", "add a cone", "apply this material", "add a spotlight", "emit these particles". These are defined as strict Zod schemas in server/tools.ts and streamed token-by-token, so objects appear to assemble themselves piece by piece. The same world is kept in sync across clients by broadcasting and replaying these action events.

Key features

  • Prompt to create — manifest new 3D objects from text.
  • Re-prompt to modify — select an existing object and prompt a change ("make it bigger", "paint it blue").
  • Move, duplicate, and delete objects you've created.
  • Real-time multiplayer — see other players' avatars, names, positions, and a shared chat log.
  • Event replay — players who join late have the existing world rebuilt for them from stored events.
  • Content moderation — prompts are screened by a lightweight model before generation.
  • Materials, lighting, and particle effects — the model can apply PBR materials (glass, metal, car paint, skin, etc.), add lights, and create particle systems.
  • Mobile controls, fall respawn, animated avatars, and a casting "energy beam" effect.

Project structure

ourcade/
├── server/                 # Bun + Hono WebSocket backend
│   ├── index.ts            # HTTP/WS entrypoint, static serving, Supabase auth
│   ├── service.ts          # JSON-RPC methods called by the game client
│   ├── game-session.ts     # Authoritative session state, broadcast & replay
│   ├── events.ts           # Game event type definitions
│   ├── connections.ts      # WebSocket connection registry
│   ├── model.ts            # LLM model configuration (heavy / light)
│   ├── tools.ts            # Zod schemas for editor actions (the LLM's toolset)
│   └── agents/
│       ├── new-prompt.ts   # "Create" agent — generates a model from a prompt
│       ├── re-prompt.ts    # "Modify" agent — edits an existing model
│       └── content-filter.ts # Screens prompts for inappropriate content
│
├── game/                   # Godot 4.3 project (the playable client)
│   ├── game.tscn / game.gd # Main scene
│   ├── entities/           # player, avatar, prompt_spawner, energy_beam
│   ├── systems/            # event_bus, server_api, presence, prompt_handler
│   │   └── prompt_handler/ # Applies streamed editor actions to the scene
│   ├── ui/                 # hud, chat, prompt input
│   └── assets/ music/      # Art and audio
│
├── frontend/               # Login/landing web app (git submodule)
├── static/                 # Static assets served by the server
├── Dockerfile              # Bun production image
├── fly.toml                # Fly.io deployment config
└── Makefile                # Godot web export + frontend build + deploy

Note: frontend/ is a git submodule pointing at the separate 3d-prompt-playground repo (the React/Vite login & landing site). Run git submodule update --init --recursive to populate it.

Tech stack

Layer Technology
Game client Godot 4.3 (GL Compatibility renderer, exported to Web/WASM)
Server runtime Bun + Hono
Realtime WebSockets with JSON-RPC (typed-rpc)
LLM integration Vercel AI SDK (OpenRouter, Anthropic, Google, Bedrock)
Schema / parsing Zod, zod-to-json-schema, best-effort-json-parser
Auth Supabase (session cookie validation)
Frontend React + Vite (submodule)
Deployment Docker + Fly.io

The server uses two model roles, configured in server/model.ts:

  • Heavy model (default: Claude 3.7 Sonnet via OpenRouter) — generates and modifies models.
  • Light model (default: Claude 3.5 Haiku via OpenRouter) — fast content filtering.

Running locally

Prerequisites

  • Bun (server)
  • Godot 4.3 (game client)
  • API credentials for your chosen model provider (e.g. an OpenRouter API key)

1. Start the server

bun install
bun run dev        # watch mode (or `bun run start`)

The server listens on port 3000, serves WebSocket connections at /ws, and serves the game client and static assets over HTTP.

Set provider credentials via environment variables (e.g. OPENROUTER_API_KEY, ANTHROPIC_API_KEY, GOOGLE_GENERATIVE_AI_API_KEY). To bypass Supabase authentication during local development, set NOAUTH=true.

2. Run the game client

Open the game/ folder in Godot 4.3 and run the main scene (game.tscn). When running outside the browser, the client connects to ws://localhost:3000/ws.

To play the web build, export the Godot project to the build/ directory (see the Makefile) and open the app served by the Bun server.

Controls

Input Action
W / A / S / D Move
Mouse Look around
Space Jump
F Cast a prompt to create an object
Q Cancel a cast in progress
Enter Open / send chat
Escape Pause / toggle mouse capture

Selecting an existing object lets you re-prompt, move, duplicate, or delete it. Touch controls are available on mobile.

Deployment

The project deploys to Fly.io as a Bun Docker image (see Dockerfile and fly.toml). The Makefile automates the full build:

make deploy        # godot web export → build frontend → fly deploy

Individual targets:

  • make release — export the Godot project for web (release).
  • make debug — export the Godot project for web (debug).
  • make web — install and build the frontend submodule.
  • make deploy — run release, web, then fly deploy.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors