LIVE DEMO: https://ev2090.com/
A 3D space simulation game built with React and Three.js, deployed on Cloudflare.
Read-only repository. This is the first public release of EV Β· 2090. I'm still figuring out the best workflow for collaborating with other developers without spending all my time managing PRs and maintaining two parallel codebases (the MMO branch I actively build on vs. a contributor-friendly fork). For now, treat this repo as read-only β explore it, learn from it, and use it as a starting point for your own multiplayer engine, single-player variant, or backend experiments. When I've sorted out a contribution workflow that doesn't slow down development, I'll open things up. Stay tuned.
EV Β· 2090 is a 3D space simulation built with React 19 for UI, Three.js for the 3D world, and Cloudflare Workers for the backend. You fly a ship around a solar system, scan NPC vessels, dock at planet stations to trade commodities, swap between ship models and colors, and chat with other players in real time.
Behind the scenes, a living economy simulates production, consumption, and NPC trade routes 24/7 -- whether players are online or not. An AI-powered ship forge lets the community design new vessels. An MCP server lets you manage the whole economy by talking to Claude. And an admin dashboard gives you a 3D visualization of every trade route and market in the system.
The codebase spans four workspaces with a regular structure. Every engine system follows the same pattern. Every Durable Object follows the same pattern. Once you understand one, you understand them all.
You do not need to read everything. Pick the guide that matches what you are working on.
- Architecture -- big picture, key diagrams, data flow
- AI Guide -- using AI coding assistants with this codebase
- Engine Guide -- 3D layer: systems, entities, game loop, shaders
- UI Guide -- React components: sidebar, station, hangar, responsive design
- Backend Guide -- Backend Worker, Durable Objects, routing
- Economy Engine -- tick engine, SQLite schema, price curves, warmup
- NPC Economy -- NPC hauler brain, trade routes, sawtooth patterns
- Ship Forge -- Ship Creation pipeline
- Admin Guide -- admin dashboard (economy monitoring)
- MCP Guide -- MCP server, AI-assisted economy management
- Cloudflare Setup -- deploying your own instance from scratch
- Self-Hosting -- running without Cloudflare (workerd, Docker, VPS)
- Dev Tools -- config panel, debug commands, authoring tools
- Recipes -- how to add systems, entities, components, routes (Warning; untested)
- Security -- security model, keys, CORS, rate limiting
| Layer | Technology | Version |
|---|---|---|
| UI | React | 19 |
| 3D Engine | Three.js | 0.172 |
| Language | TypeScript | 5.7 |
| Bundler | Vite | 6 |
| Backend | Cloudflare Workers + Durable Objects | - |
| Hosting | Cloudflare Pages | - |
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Frontend (React 19 + Three.js) β you fly ships here β
β Vite 6 Β· TypeScript 5.7 Β· port 5180 β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Admin Dashboard (React 19 + Three.js) β economy ops β
β Vite 6 Β· port 5181 β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Game Worker (Cloudflare Workers) β the brain β
β 4 Durable Objects Β· 2 R2 buckets Β· 1 queue β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β MCP Worker (Cloudflare Workers) β AI interface β
β 37 tools Β· OAuth 2.0 Β· Claude integration β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Two commands. That's it.
npm install
npm run devnpm install sets up all four workspaces. npm run dev starts the frontend, the local worker, and the admin dashboard β and automatically seeds the NPC economy after 8 seconds so you have live trade data from the moment the page loads. No API keys, no .env files, no Cloudflare account required.
| URL | What's there |
|---|---|
http://localhost:5180 |
The game β fly ships, dock, trade |
http://localhost:5181 |
Admin dashboard β 3D trade route viewer, economy overview |
http://localhost:8787 |
Local worker API |
The game runs in no-auth mode by default: all admin routes are open and the economy is fully functional with locally seeded data. You can explore the entire game engine without touching any configuration.
Advanced configuration (AI ship forge, custom API keys, deploying your own Cloudflare infrastructure) is covered in CLAUDE.md and docs/cloudflare-setup.md when you're ready for it.
- Node.js 18+
npm run dev:frontend # frontend only β API proxied to production ws.ev2090.com
npm run dev:api # local worker only
npm run dev:admin # admin dashboard onlynpm run deploy # builds + deploys frontend to Cloudflare Pages
npm run deploy:api # deploys worker to Cloudflare Workers| Key | Action |
|---|---|
| W / Arrow Up | Thrust |
| A / Arrow Left | Rotate left |
| D / Arrow Right | Rotate right |
| S / Arrow Down | Brake |
| B | Toggle debug beam |
Console tricks -- open your browser dev tools and try:
| Command | Action |
|---|---|
config() |
Toggle light/camera debug panel |
testship() |
Spawn a frozen NPC near your ship |
heroshot() |
Toggle hero shot authoring tool |
hardpoints() |
Toggle hardpoint editor |
forge() |
Toggle ship forge overlay |
ship("bob") |
Switch ship by catalog ID |
zoom(0.3) |
Zoom camera (lower = closer) |
zoomreset() |
Reset zoom to default |
reset() |
Clear localStorage and reload |
URL shortcuts (dev only):
?scene=gameplay Β· ?scene=docked Β· ?scene=heroshot Β· ?scene=hardpoint Β· ?scene=config Β· ?scene=intro
graph LR
subgraph Frontend ["Frontend Β· React 19 + Three.js"]
direction TB
Game["Game.tsx<br/>orchestrator"]
Canvas["GameCanvas.tsx<br/>React β Engine bridge"]
Engine["Engine.ts<br/>game loop + scene"]
Systems["systems/<br/>subsystems"]
Entities["entities/<br/>Ship Β· Planet Β· NpcShip"]
Components["UI Components<br/>Sidebar Β· Station Β· Hangar Β· Chat"]
Game --> Canvas
Game --> Components
Canvas -->|"GameCanvasHandle"| Engine
Engine -->|"subscribe ~20fps"| Canvas
Engine --> Systems
Engine --> Entities
end
subgraph Worker ["Game Worker Β· Cloudflare"]
direction TB
Index["index.ts<br/>HTTP routing"]
ChatDO["ChatRoom DO<br/>SSE chat"]
BoardDO["BoardRoom DO<br/>community notes"]
ForgeDO["ShipForge DO<br/>AI ship pipeline"]
EconDO["EconomyRegion DO<br/>NPC economy"]
Index --> ChatDO
Index --> BoardDO
Index --> ForgeDO
Index --> EconDO
end
Components -->|"HTTP / SSE"| Index
The frontend is a single-page app. The Three.js engine runs the 3D scene independently of React. React handles the HUD, sidebar panels, station UI, hangar, and chat. The engine pushes state updates to React at ~20fps via a subscribe callback.
The worker is a Cloudflare Worker with four Durable Objects: ChatRoom (real-time SSE chat), BoardRoom (community notes), ShipForge (AI-powered ship generation), and EconomyRegionDO (NPC economy simulation with SQLite). Two R2 buckets store ship models and economy snapshots.
The engine has zero React dependencies. React talks to the engine through an imperative ref handle (
GameCanvasHandle). The engine pushes state back to React at ~20 fps via a subscribe callback. This boundary is the single most important thing to understand.
The flow looks like this:
graph LR
React["React (Game.tsx)"] -->|"imperative ref"| Bridge["GameCanvasHandle"] -->|"method calls"| Engine["Engine.ts"]
Engine -->|"subscribe callback ~20fps"| React
React never reaches into Three.js objects directly. The engine never imports React. GameCanvasHandle is the contract between the two worlds. If you remember nothing else from these docs, remember this.
The backend follows the same principle -- a small number of repeating patterns:
- Every Durable Object follows: constructor loads state β
fetch()handles routes βalarm()for periodic work. - Every MCP tool follows: validate scope β extract params β call DO or R2 β format response.
- Every admin endpoint follows: validate Bearer token β call DO β return JSON.
- All state is dual: in-memory (fast) + SQLite/R2 (durable). Always update both.
Use an AI coding assistant? I've prepared project context files:
- CLAUDE.md β for Claude Code. Loaded automatically when you open this project.
- .cursorrules β for Cursor. Loaded automatically as project rules.
- docs/ai.md β explains what these files contain and why every rule exists.
These files contain architecture rules, conventions, common tasks, and gotchas so your AI assistant understands the codebase from the first prompt.
escape_velocity/
βββ frontend/ # React + Three.js SPA
β βββ src/
β β βββ components/ # React UI components
β β β βββ config/ # CollapsibleSection building blocks
β β β βββ sidebar/ # Right sidebar panels (Radar, Diagnostic, Selector, Cargo, Status, Nav, Target)
β β β βββ station/ # Station facility sub-panels (Summary, Trading, Locked)
β β β βββ hangar/ # Ship management overlay (HangarOverlay, ShipCard, ShipDetail, ForgeCreatePanel)
β β β βββ Game.tsx # Main layout orchestrator
β β β βββ GameCanvas.tsx # Three.js canvas + React bridge
β β β βββ IntroScreen.tsx # First-time ship selection
β β β βββ StationPanel.tsx # Desktop docking interface
β β β βββ StationOverlay.tsx # Mobile docking interface (CRT terminal)
β β β βββ ChatPanel.tsx # Multiplayer SSE chat
β β β βββ ... # DockFlash, TouchControls, hangar/, etc.
β β βββ engine/ # Three.js game engine (no React deps)
β β β βββ Engine.ts # Core: game loop, scene, renderer
β β β βββ ShipCatalog.ts # Ship definitions (11 built-in + community)
β β β βββ entities/ # Ship, Planet, NpcShip, Bridge
β β β βββ systems/ # CameraController, NpcManager, PostProcessing, etc.
β β β βββ shaders/ # GLSL shaders (shield, vignette, color correction)
β β βββ data/ # Static game data (stations, missions)
β β βββ hooks/ # useBreakpoint, useConfigSlider, usePlayerEconomy, useMarketPrices
β β βββ types/ # Shared TypeScript interfaces
β βββ vite.config.ts
βββ worker/ # Cloudflare Worker (game backend)
β βββ src/
β β βββ index.ts # HTTP routing + CORS + queue consumer
β β βββ admin.ts # Admin API handlers (Bearer auth)
β β βββ chat-room.ts # ChatRoom DO (SSE chat)
β β βββ board-room.ts # BoardRoom DO (community notes)
β β βββ ship-forge.ts # ShipForge DO (AI ship pipeline)
β β βββ economy-region.ts # EconomyRegionDO (NPC economy, SQLite)
β β βββ economy/ # Pricing, trade routes, disruptions
β β βββ data/ # Commodity + planet definitions
β βββ wrangler.toml
βββ worker-mcp/ # MCP server (AI economy management)
β βββ src/tools/ # 37 tools across 10 categories
βββ admin/ # Admin dashboard (local dev only)
β βββ src/ # Economy monitoring + 3D trade viewer
βββ docs/ # Project documentation
βββ package.json # Monorepo root (workspaces)
| Variable | Description |
|---|---|
VITE_API_PROXY_TARGET |
Override API proxy target in dev. Defaults to https://ws.ev2090.com. |
VITE_FORGE_API_KEY |
Ship Forge admin key for local dev. |
The project ships with hardcoded URLs pointing to cdn.ev2090.com (assets) and ws.ev2090.com (API backend). These are provided temporarily so you can clone the repo and play immediately without deploying your own infrastructure. They will likely be shut down in the future β don't depend on them for a fork. To deploy your own instance, see docs/cloudflare-setup.md.
The ship models in this project are by @Quaternius, released under CC0 1.0 Universal (Public Domain). These models are incredible and free β if you use them in your own projects, consider supporting Quaternius on Patreon. Even $1 helps.
EV Β· 2090 is built on React and TypeScript β which means it can ship everywhere. I'm working toward releasing the framework with native builds for:
- Web (current) β runs in any modern browser
- Desktop β Windows and macOS executables via Electron or Tauri
- Mobile β iOS and Android via Capacitor or React Native
One codebase, every platform. Stay tuned.
This project is licensed under the MIT License.