使用说明
SpawnForge
SpawnForge is a source-available, AI-native 2D/3D game engine that runs entirely in the browser. It combines a Bevy-based Rust/WebAssembly rendering engine with a React visual editor and a 383-command MCP manifest (measured 2026-10-05 — which of those commands work today through which entry point is recorded in the capability matrix), enabling game creation through natural language, visual scripting, or manual editing. Games are built, tested, and published without leaving the browser — no install, no compile step, no deployment pipeline.
Status
Why SpawnForge
- Browser-native — No download, no IDE setup. Open a URL and start building 2D or 3D games.
- AI-first — 25+ AI modules; the in-app AI is offered 299 of the 383 manifest commands (every
:write-scoped command plus thequerycategory) to drive the editor. External MCP agents can attach only in local builds, through an allowlist of 325 commands; permitted names can still return unavailable results, and that path is not yet verified end to end (production access is pending #9722). Describe a scene in plain text and watch it materialize. Which capabilities are proven, unverified or unavailable per entry point: capability matrix. - Real engine — Bevy ECS compiled to WebAssembly, WebGPU rendering (WebGL2 fallback), Rapier physics, spatial audio, GPU particles, skeletal animation. Not a toy.
- One command interface — The visual editor, AI chat, and external MCP agents all call the same
handle_command()JSON API. There is no separate "AI mode." - Publish instantly — One-click publish to a shareable URL. Export as a standalone ZIP with PWA support.
Key Statistics
| Metric | Value |
|---|---|
| MCP commands | 383 across 41 categories (305 public), measured 2026-10-05 with jq '.commands | length' mcp-server/manifest/commands.json — per-category status in the capability matrix |
| Visual scripting nodes | 73 across 10 categories |
| Material presets | 56 across 9 categories |
| AI modules | 25+ (chat, generation, asset creation) |
| Game components | 13 drag-and-drop behaviors |
| Test suite | 14,200+ tests |
| Rendering | WebGPU primary, WebGL2 fallback |
| Engine | Bevy 0.19, Rust/WASM |
A source-available, AI-native 2D/3D game engine for the browser. Editor operations are JSON commands through handle_command(), and 383 of them (305 public) are published in the MCP manifest for the Model Context Protocol. Registration is not the same as a working feature: which capabilities are proven, implemented but unverified, partial or unavailable through the editor UI, the in-app AI, game scripts and external MCP is recorded per capability in docs/capability-matrix.md. As of 2026-09-15, external MCP agents can attach only to local builds (#9722) and platform-key asset generation is unavailable in production (#9117). Build games by conversation, by code, or by hand — within those limits.
Powered by WebGPU (with WebGL2 fallback), Rust compiled to WebAssembly, and a React-based visual editor.
Project Sites
| Site | URL | Description |
|---|---|---|
| Editor | spawnforge.localhost:1355 (dev) |
Main SpawnForge editor and platform |
| MCP & API Docs | docs.spawnforge.ai | Public MCP command reference and API documentation |
| Design System | design.spawnforge.ai |
Storybook component library and design tokens |
Features
AI & Automation
- AI Chat Assistant — Built-in Claude-powered chat panel with agentic tool loop. Describe what you want in plain language and the AI executes compound actions to spawn entities, configure materials, write scripts, and iterate across multiple turns until the scene is complete. The upcoming Game Creation Orchestrator will decompose any game description into composable systems (movement, camera, challenge, feedback, etc.) and coordinate specialist agents to build them in parallel
- Compound AI Actions — 8 high-level tools (
create_scene_from_description,setup_character,arrange_entities, etc.) that batch dozens of operations into single AI calls - Extended Thinking — Toggle deep reasoning mode for complex multi-step requests like full game setup
- Visual Scripting — React Flow node graph editor with 73 node types across 10 categories. Non-programmers create game logic by connecting visual blocks; graphs compile to TypeScript
- AI Asset Generation — Generate 3D models, textures, sound effects, and voice lines via provider integrations (Meshy, ElevenLabs, DALL-E, Stable Diffusion). Music generation is not available yet — its move to ElevenLabs is tracked in #9522; platform provisioning status per capability is in docs/guides/platform-keys.md
- MCP Server — 383 commands across 41 categories (305 public). In a local build, an MCP-compatible agent can attach to the editor (after the in-tab consent prompt) with an allowlist that permits 325 of those command names — scene authoring, materials, physics, animation, inspection. Availability checks can still reject permitted names: linked prefab placement, nested placement, and source propagation are not implemented. Commands for script authoring, export, publishing, generation, security and economy are withheld over the bridge by design (
web/src/lib/mcp/bridgeAllowlist.ts). That local path is not yet verified end to end, and attaching to production is pending #9722. Per-category status for MCP and the other entry points: capability matrix. See the MCP command reference for the full public command listing. - Command-Driven Architecture — Every engine operation is a JSON command through
handle_command(). The visual editor and AI agents use the exact same API - Scene Context — Built-in context builder provides LLMs with full scene state for informed decision-making
- Documentation System — 28+ structured docs searchable via MCP tools (
search_docs,get_doc,list_doc_topics), enabling AI agents to learn features on demand
3D Engine
- WebGPU Rendering — Primary rendering via WebGPU (wgpu 29) with automatic WebGL2 fallback for older browsers
- PBR Materials — Physically-based rendering with metallic/roughness workflow, UV transforms, clearcoat, transmission/IOR, parallax mapping, texture support, alpha modes, and 56 material presets across 9 categories
- Shader Node Editor — Visual WGSL shader creation with 30+ node types, live material preview, and save/load
- Quality Presets — Low/Medium/High/Ultra rendering presets that batch-configure MSAA, shadows, bloom, sharpening, and particle density
- Dynamic Lighting — Point, directional, and spot lights with real-time shadows and ambient light controls
- Skybox & Environment Maps — 5 built-in procedural cubemap presets (Studio, Sunset, Overcast, Night, Bright Day) with adjustable brightness, IBL, and rotation
- Physics — Rigid body dynamics, colliders, forces, joints (fixed, revolute, spherical, prismatic, rope, spring), collision events, and raycasting powered by Rapier 3D
- Audio — Spatial 3D audio, bus mixer with effect chains (reverb, delay, EQ, compressor), adaptive music (vertical stem layering), reverb zones, crossfade, ducking
- GPU Particles — 9 built-in presets (fire, smoke, sparks, rain, snow, explosions, etc.) with full customization via WebGPU compute shaders
- Skeletal Animation — glTF animation playback with transport controls, crossfade, blend weights, per-clip speed, and script API
- Keyframe Animation — Custom animation clips with position/rotation/scale/color keyframes, easing modes, and timeline editor
- CSG Boolean Operations — Union, subtract, and intersect on mesh entities using BSP-based constructive solid geometry
- Procedural Terrain — Heightmap generation with Perlin/Simplex/Value noise, sculpting tools, and vertex coloring
- Procedural Mesh Generation — Extrude 2D shapes, lathe profiles, array entities, and combine meshes
- Polygon Modeling — Edit mode with vertex/edge/face selection, extrude, subdivide, and normal recalculation
- Custom Shader Effects — 6 built-in visual effects (Dissolve, Hologram, Force Field, Lava/Flow, Toon, Fresnel Glow)
- Custom WGSL Shaders — Write arbitrary WGSL fragment shader code directly in the editor. 8 built-in templates (Passthrough, Color Tint, Wave Distortion, Rim Light, Grayscale, Pulsing Glow, UV Scroll, Scanlines), real-time compile status, error display, Ctrl+Enter compile shortcut, and scene persistence
- Post-Processing — Bloom, chromatic aberration, color grading, CAS sharpening, SSAO (WebGPU), depth of field, and motion blur
- LOD System — Level-of-detail component with distance thresholds, performance budget tracking
2D Engine
- 2D Project Type — Dedicated 2D mode with orthographic camera, sorting layers, and sprite-specific tools
- Sprite System — Import PNG/WebP sprites, SpriteInspector, sorting layers (Background/Default/Foreground/UI), Bevy Sprite rendering
- Sprite Animation — Sprite sheet slicing via TextureAtlas, animation clips, state machines with parameter-driven transitions
- Tilemap System — Multi-layer tilemaps, paint/erase/fill/rectangle tools, tile palette, hash-based change detection
- 2D Physics — Rapier2D integration with 6 collider shapes, 4 joint types, one-way platforms, surface velocity
- Skeletal 2D Animation — Bone hierarchy, skins, IK constraints, blend trees, vertex skinning, keyframe animation
- AI Sprite Generation — Pixel art characters, tilesets, and sprite sheets via Replicate SDXL (pixel-art style) or DALL-E 3 (other styles). Not usable in production until the platform keys are provisioned (#9117) — neither provider accepts a user-supplied key; see
generation:spritein the capability matrix
Editor
- Dockable Workspace — Movable, resizable panels with preset layouts and persistent user customization
- 3D/2D Scene Editor — Transform gizmos, multi-select, snapping, scene hierarchy, and domain-specific inspector panels
- Starter System Bundles — 11 prepackaged system configurations (5 3D + 6 2D) with friendly names like Platformer, Runner, Shooter, Puzzle, and Explorer. Each bundle is a starting point, not a constraint — every system is independently editable, and you can describe any game type beyond these presets
- Game Cameras — 6 camera modes (ThirdPerson, FirstPerson, SideScroller, TopDown, Fixed, Orbital) with auto-activation in Play mode
- Dialogue System — Visual node editor with 5 node types (text, choice, condition, action, end), typewriter display, branching, and
forge.dialoguescript API - Scene Transitions — Fade, wipe, and instant transitions between scenes with
forge.scene.loadAPI - In-Game UI Builder — 10 widget types, WYSIWYG editor, 7 screen presets, data binding, play-mode renderer, and
forge.uiscript API - TypeScript Scripting — Sandboxed scripting with
forge.*API (14+ namespaces), starter templates, built-in editor with console - Script Library — Save and share standalone scripts, import/export, enhanced script explorer
- Material Library — Browse 56 built-in presets with CSS sphere previews, category filters, search, and custom saving
- Asset Pipeline — Import glTF models, textures, audio, and sprites via drag-and-drop
- Play Mode — Test games instantly with play/pause/stop and scene snapshot restore
- Input System — Configurable key bindings with presets (FPS, Platformer, Top-Down, Racing)
- Mobile Controls — Virtual joystick and action buttons overlay, 5 touch presets, auto quality reduction
- Prefab System — Reusable entity templates with 8+ built-in prefabs, import/export, search, and saved-link metadata inspection. Linked scene placement, nesting, and propagation remain unavailable (#9811).
- Multi-Scene Management — Multiple named scenes per project with scene switching, duplication, and import/export
- Cloud Publishing — Publish to shareable URLs with version management, tier-based limits, and analytics
- Game Export — ZIP export with texture compression, custom loading screens, PWA generation
- Guided Onboarding — Welcome wizard, interactive tutorials, context-sensitive tips
- In-Editor Documentation — Browsable docs panel with BM25 search, help buttons on inspectors, F1 shortcut
- Pre-Built Game Components — 13 drag-and-drop behaviors (CharacterController, Health, Collectible, Projectile, etc.)
- Responsive Layout — Adaptive UI with compact (mobile), condensed (laptop), and full desktop modes
Architecture
MCP Server (383 commands, 41 categories) AI agents + LLM tool use
| JSON commands
React Shell (Next.js 16, Zustand, Tailwind) Visual editor UI
| JSON events via wasm-bindgen
Bevy Engine (Rust -> WebAssembly) Scene editing + WebGPU rendering
|
Game Runtime + TypeScript Scripting In-browser game execution
The MCP server and the visual editor share the same command interface — there is no separate "AI mode." An agent calling set_material goes through the exact same code path as a user dragging a color picker.
Rendering: WebGPU primary (auto-detected), WebGL2 fallback. Four WASM binaries are built per release — an editor and a runtime variant for each of WebGPU and WebGL2 — and the frontend auto-selects the correct one at runtime.
Prerequisites
- Rust (stable) with the
wasm32-unknown-unknowntarget - wasm-bindgen-cli 0.2.127 exactly — it must match the
wasm-bindgencrate pin inengine/Cargo.toml, or the build fails on missing exports - Node.js 24
- Bash (macOS/Linux) or PowerShell (Windows) for build scripts
Install the WASM target
rustup target add wasm32-unknown-unknown
cargo install wasm-bindgen-cli --version 0.2.127
Getting Started
1. Clone the repository
git clone https://github.com/Tristan578/project-forge.git
cd project-forge
2. Build the WASM engine
# macOS / Linux
./build_wasm.sh
# Windows (PowerShell)
.\build_wasm.ps1
# This compiles both WebGL2 and WebGPU WASM binaries
# and copies them to web/public/
WASM build troubleshooting
| Error | Cause | Fix |
|---|---|---|
wasm-bindgen version mismatch |
CLI version differs from the wasm-bindgen crate in Cargo.lock (pinned to 0.2.127) |
cargo install wasm-bindgen-cli --version 0.2.127 |
error[E0433]: could not find crate |
Missing the WASM compile target | rustup target add wasm32-unknown-unknown |
doc-image-embed link errors (Windows) |
Native proc-macro needs Windows SDK LIB paths | The build script auto-detects; ensure Visual Studio Build Tools are installed |
| Pink/magenta materials in browser | Missing tonemapping_luts Bevy feature |
Verify Cargo.toml includes "tonemapping_luts" in default features |
wasm-opt not found warning |
Optional optimization step | cargo install wasm-opt (non-fatal — build still succeeds) |
| Engine loads but renders nothing | WebGPU not supported; fallback not triggered | Check browser console for WebGPU detection; try Chrome/Edge with chrome://flags/#enable-webgpu |
3. Install web dependencies
cd web
npm install
4. Set up environment variables
cp web/.env.example web/.env.local
# Edit web/.env.local with your API keys (Clerk, Stripe, database, etc.)
5. Start the development server
npm run dev
Open http://localhost:3000 in a WebGPU-capable browser (Chrome 113+, Edge 113+, or Firefox Nightly).
6. Install MCP server dependencies (optional)
cd ../mcp-server
npm install
Project Structure
project-forge/
├── engine/ # Bevy ECS engine (Rust -> WASM)
│ ├── src/
│ │ ├── bridge/ # JS interop — domain modules (wasm-bindgen, events)
│ │ └── core/ # Pure Rust: commands, ECS components, pending queues
│ ├── Cargo.toml
│ └── Cargo.lock
├── web/ # Next.js frontend
│ ├── src/
│ │ ├── components/ # React UI (editor panels, inspectors, dialogs)
│ │ ├── hooks/ # WASM loader, engine events, script runner
│ │ ├── stores/ # Zustand state (editor slices, chat, user, workspace)
│ │ └── lib/ # Audio, scripting, export, auth, billing, shaders
│ ├── public/ # Static assets + WASM binaries (generated)
│ └── package.json
├── mcp-server/ # MCP command manifest + tools
│ ├── manifest/commands.json # 383 commands across 41 categories (see docs/capability-matrix.md)
│ └── src/
├── docs/ # User-facing documentation (human + AI readable)
│ ├── getting-started/ # Installation, first scene, editor overview
│ ├── features/ # Per-feature guides
│ ├── guides/ # End-to-end tutorials
│ └── reference/ # Command reference, script API, entity types
├── specs/ # Feature specifications and sprint plans
├── build_wasm.sh # WASM build script — macOS / Linux
├── build_wasm.ps1 # WASM build script — Windows (PowerShell)
└── README.md
Development
Build commands
| Command | Description |
|---|---|
./build_wasm.sh |
Build all four editor/runtime WebGPU/WebGL2 WASM variants — macOS / Linux |
.\build_wasm.ps1 |
Build all four editor/runtime WebGPU/WebGL2 WASM variants — Windows (PowerShell) |
cd web && npm run dev |
Start the Next.js dev server |
cd web && npm run build |
Production build |
cd web && npm run lint |
Run ESLint |
cd web && npx tsc --noEmit |
TypeScript type checking |
cd web && npx vitest run |
Run web tests (~14,200+ tests) |
cd mcp-server && npx tsc --noEmit && npx vitest run |
Run MCP server tests |
Key conventions
- Bridge isolation: Only
engine/src/bridge/may importweb_sys/js_sys/wasm_bindgen. Thecore/module is pure Rust with no browser dependencies. - Command-driven: All engine operations are expressed as JSON commands through
handle_command(). This enables both the UI and programmatic integrations to drive the editor. - Event-driven updates: Bevy systems emit events via the bridge -> JS callback -> Zustand store -> React re-render. No direct DOM manipulation from Rust.
Agentic Development
SpawnForge is designed for AI-assisted development. Six AI coding tools are pre-configured with shared enforcement hooks, skills, and project context. Any contributor can open the repo in their preferred tool and start working immediately — ticket tracking, code quality, and GitHub sync are enforced consistently across all tools.
Supported Tools
| Tool | Config Dir | Hooks | Skills | Default Model |
|---|---|---|---|---|
| Claude Code | .claude/ |
Automatic | .claude/skills/ |
Opus 4.6 / Sonnet 4.6 |
| GitHub Copilot | .github/ |
Automatic | .github/skills/ |
GitHub-managed |
| Gemini CLI | .gemini/ |
Automatic | .agents/skills/ |
gemini-3.1-pro-preview |
| Windsurf | .windsurf/ |
Automatic | .windsurf/workflows/ |
App-managed |
| Google Antigravity | .agent/ + .gemini/ |
Manual | .agent/skills/ |
Gemini 3 |
| OpenAI Codex CLI | .codex/ |
Wired; run only after a one-time /hooks approval (not yet confirmed in a live session) |
.agents/skills/ |
gpt-5.3-codex |
First-time setup: Install the taskboard binary, then open the repo in your AI tool. Tools with automatic hooks will self-configure on first session. Codex needs a one-time approval of its hooks in /hooks first (see .codex/AGENTS.md); Antigravity has no hooks and carries manual workflow instructions in its rules.
Quick Start by Tool
Claude Code
cd project-forge
claude # hooks auto-start taskboard, pull GitHub, display backlog
Everything is automatic. Hooks enforce ticket-before-code on every prompt, validate tickets after every response, push changes to GitHub, and lint edited files. Skills are invoked via /kanban, /sync-push, /sync-pull, /planner, /builder, /cycle.
Claude Code also has three subagents (.claude/agents/):
- Planner (Opus) — Architect that creates specs in
specs/, never writes code - Builder (Sonnet) — Implementation specialist, reads specs and writes code
- Validator (Sonnet) — QA gatekeeper, runs tests and architecture checks
GitHub Copilot
cd project-forge
# Copilot reads .github/hooks/*.json and .github/copilot-instructions.md
# (Copilot CLI also runs the hooks in .claude/settings.json)
Hooks trigger on session start (pull), prompt submit (ticket gate), end of turn (on-stop.sh: worktree safety commit + GitHub sync), and post-tool-use (architecture check). Which file owns each event for Copilot CLI versus the cloud agent is in the Hooks section of .github/copilot-instructions.md. Skills available in .github/skills/ and .agents/skills/; manual sync is the sync-pull and sync-push skills.
Gemini CLI
cd project-forge
gemini # reads .gemini/settings.json, GEMINI.md, AGENTS.md
Hooks configured in .gemini/settings.json for SessionStart, BeforeAgent, AfterAgent, and AfterTool (file edits). Skills in .agents/skills/.
Windsurf
cd project-forge
# Windsurf reads .windsurf/hooks.json and .windsurf/rules/taskboard.md
Hooks trigger on post_write_code, post_run_command, post_cascade_response, and pre_user_prompt. Workflows for sync in .windsurf/workflows/.
Google Antigravity
cd project-forge
# Antigravity reads GEMINI.md (with AGENTS.md loading directive) and .agent/skills/
# No auto-hooks — run manually:
bash .claude/hooks/on-session-start.sh # start of session
bash .claude/hooks/on-stop.sh # after work
bash .claude/hooks/post-edit-lint.sh # after editing
Skills in .agent/skills/ (singular — Antigravity uses .agent/, not .agents/). Rules in .agent/rules/.
OpenAI Codex CLI
cd project-forge # start Codex at the repo root — on Windows the hook commands are relative to it
codex # reads AGENTS.md (root), .codex/config.toml, .codex/hooks.json, .codex/agents/ — NOT .codex/AGENTS.md; the root file points it there
Hooks run the shared .claude/hooks/ scripts, but only after a one-time approval: trust the project, then open /hooks and approve them (Codex re-asks whenever a hook's command changes). Config in .codex/config.toml. Subagents in .codex/agents/, skills in .agents/skills/ — both generated from .claude/ by node tools/agentic-sync/port.mjs --write, never hand-edited. What is wired, what Codex cannot express, and what was verified: docs/guides/codex-cli-support-matrix.md. Full enforcement rules in .codex/AGENTS.md.
Shared Hook System
All tools call the same bash scripts in .claude/hooks/. Tools with hook support wire them up automatically via their config files; tools without hooks require manual execution.
Tool Config (JSON/TOML)
│
▼
Shared Bash Scripts (.claude/hooks/)
│
├── taskboard-state.sh ← Library: API helpers, validation, consistency
├── github_project_sync.py ← Sync engine: push/pull with GitHub Projects v2
└── github-sync-config.json ← GitHub Project metadata
Hook Lifecycle
| Hook | Script | Trigger | What It Does |
|---|---|---|---|
| Session Start | on-session-start.sh |
Tool opens | Checks taskboard binary, auto-starts server, pulls from GitHub Project, displays backlog with prioritized work suggestions, warns about stale tickets |
| Prompt Submit | on-prompt-submit.sh |
Before each prompt | Detects development-intent keywords, blocks code work if no active ticket, injects active ticket context |
| Stop | on-stop.sh |
After each response | Validates active ticket (user story, AC, priority, team, subtasks), checks open ticket consistency, pushes changes to GitHub Project |
| Post-Edit Lint | post-edit-lint.sh |
After file edits | Runs ESLint on changed .ts/.tsx files under web/ (skips tests, node_modules, coverage) |
| Sync Push | sync-to-github.sh |
Called by Stop | Guards for gh CLI + auth, calls github_project_sync.py push |
| Sync Pull | sync-from-github.sh |
Called by Session Start | Guards for gh CLI + auth, calls github_project_sync.py pull |
Ticket Validation Rules
The tb_validate_ticket() function in taskboard-state.sh enforces:
- User Story — Must match regex
As an?\s+.+,\s+I want\s+.+\s+so that\s+.+ - Acceptance Criteria — Minimum 3 complete Given/When/Then scenarios (happy path, edge case, negative)
- Description Substance — At least 20 characters of technical context beyond user story and AC
- Priority — Must be
urgent,high,medium, orlow - Team — Must be assigned to Engineering or PM
- Subtasks — At least 3 implementation steps
Skills Reference
Skills are callable capabilities loaded on-demand. Each tool stores them in its own directory, but all reference the same shared hook scripts.
The project's own skills are authored once, under .claude/skills/, and mirrored byte-for-byte into .agents/skills/ by node tools/agentic-sync/port.mjs --write — the directory Codex, Gemini CLI and Copilot read. "Mirrored" below means the text is available there; it was written for Claude Code and names Claude's tools. There are no exceptions: game-engine, kanban and web-accessibility once existed on both sides and had drifted apart, and #10131 made .claude/skills/ canonical for them too (the .agents/ copies' extra content was merged into the .claude/ side first), so every tool now reads the same text. skills.independent in tools/agentic-sync/port.json is the escape hatch for a skill that must stay unmirrored; it is empty.
| Skill | Available In | Purpose |
|---|---|---|
| kanban | All 6 tools | View board, create/update/move tickets, validate fields, toggle subtasks. Claude Code uses MCP tools; other tools use REST API (curl to localhost:3010) |
| sync-push | All 6 tools | Push local ticket changes to GitHub Project. Syncs full body (description, priority, subtask checkboxes, metadata block). Detects changes via content hashing |
| sync-pull | All 6 tools | Pull GitHub Project changes to local taskboard. Reconstructs subtasks from checkboxes, re-links tickets by ULID from metadata, imports new tickets with parsed fields |
| planner | Claude Code; mirrored to .agents/skills/ |
Architect agent — analyzes requests, creates detailed specs in specs/, never writes code |
| builder | Claude Code; mirrored to .agents/skills/ |
Implementation agent — reads specs, writes Rust/TypeScript, runs lint/check after coding |
| cycle | Claude Code; mirrored to .agents/skills/ |
Orchestration — runs Plan → Build → Verify loop, updates project context after each cycle |
| arch-validator | Claude Code; mirrored to .agents/skills/ |
Runs check_arch.py — 7 structural rules (bridge isolation, file sizes, dispatch chain, store composition) |
GitHub Project Sync
The github_project_sync.py engine provides bidirectional sync between the local taskboard and GitHub Project "SpawnForge" (#2).
V2 body format: Each ticket on GitHub contains a structured body:
**Priority:** high
[ticket description — user story, AC, technical context]
## Subtasks
- [ ] Step 1
- [x] Step 2 (completed)
- [ ] Step 3
---
<!-- SPAWNFORGE_METADATA
{ "version": 2, "ticketId": "...", "bodyHash": "...", "subtaskHash": "..." }
SPAWNFORGE_METADATA -->
- [ ]/- [x]renders as interactive checkboxes on GitHub- The HTML comment is invisible but machine-parseable for re-linking
- Content hashes detect changes without full comparison
- Old v1 format (
**Taskboard:** PF-N (ULID)) is still parsed on pull and auto-upgraded to v2 on next push
Commands:
python3 .claude/hooks/github_project_sync.py push # incremental push
python3 .claude/hooks/github_project_sync.py push-all # full push (upgrades all to v2)
python3 .claude/hooks/github_project_sync.py pull # pull remote changes
python3 .claude/hooks/github_project_sync.py status # show sync state
Architecture Validator
The check_arch.py script enforces 7 structural rules:
| Rule | Limit | What It Checks |
|---|---|---|
| Bridge isolation | Hard fail | No web_sys/js_sys/wasm_bindgen imports outside engine/src/bridge/ |
| Rust file size | 800 lines | No Rust source file exceeds limit |
| TypeScript file size | 500 lines | No TS/TSX file exceeds limit (excludes tests, .d.ts, legacy) |
| Command dispatch | 50 match arms | commands/mod.rs delegates to domain modules, not monolithic match |
| Pending mod.rs | No request structs | Request types live in domain modules, not pending/mod.rs |
| Store composition | 200 lines | editorStore.ts composes slices, doesn't define inline state |
| Event delegation | 150 lines | useEngineEvents.ts delegates to hooks/events/ handlers |
python3 .claude/skills/arch-validator/check_arch.py # warnings
python3 .claude/skills/arch-validator/check_arch.py --strict # exit 1 on any violation
python3 .claude/skills/arch-validator/check_arch.py --json # machine-readable output
Taskboard
All work is tracked on a local taskboard that syncs to GitHub Projects.
Install (go install github.com/tcarac/taskboard@latest does not work: v0.6.0 has no main package at the module root, and cmd/taskboard embeds a web/dist the module does not ship):
brew tap tcarac/taskboard && brew install taskboard
# Or download a release binary from https://github.com/tcarac/taskboard/releases
# Or build from source: git clone https://github.com/tcarac/taskboard && cd taskboard && make build
# Not on PATH? Set TASKBOARD_BIN to the binary.
First run on a new machine (no taskboard database yet) — once, instead of start:
cd project-forge
node .claude/hooks/taskboard-launch.mjs init # the only command that creates the shared database
python3 .claude/hooks/github_project_sync.py pull
Start (every time after that):
cd project-forge
node .claude/hooks/taskboard-launch.mjs start # never start the binary by hand — see "Database" below
- Web UI: http://localhost:3010
- API: http://localhost:3010/api
- Project ID:
01KMM9ZA6SBZ7RKJZJTZS9VR4R(prefix: PF) - Database: resolved by the launcher —
TASKBOARD_DBif set, else the OS config directory (%APPDATA%\taskboard\taskboard.dbon Windows,~/Library/Application Support/taskboard/taskboard.dbon macOS,$XDG_CONFIG_HOME/taskboard/taskboard.dbon Linux (~/.config/taskboard/taskboard.dbwhenXDG_CONFIG_HOMEis unset;node .claude/hooks/taskboard-launch.mjs db-pathprints the resolved path)) — and passed to the binary explicitly, so the HTTP server, the MCP server and the GitHub sync all open the same file. Never start the binary by hand and never pass your own--db: a stray--dbpoints the board at an empty local copy instead of the shared store.
Tools with hook support auto-start the taskboard on session start. Ticket state is shared across contributors via the GitHub Projects sync (.claude/hooks/github_project_sync.py), not a committed database.
Config Directory Map
project-forge/
├── AGENTS.md # Cross-tool instructions (Copilot, Gemini, Antigravity, Codex)
├── GEMINI.md # Gemini CLI + Antigravity instructions
├── .claude/ # Claude Code (primary tool)
│ ├── CLAUDE.md # Full project constitution (280+ lines)
│ ├── settings.json # Tool settings
│ ├── agents/ # Subagent definitions
│ │ ├── planner.md # Architect (Opus model)
│ │ ├── builder.md # Implementer (Sonnet model)
│ │ └── validator.md # QA gatekeeper (Sonnet model)
│ ├── hooks/ # SHARED hook scripts (all tools call these)
│ │ ├── taskboard-state.sh # Library: API helpers, validation, staleness
│ │ ├── on-session-start.sh # Session start lifecycle
│ │ ├── on-prompt-submit.sh # Prompt submit gate
│ │ ├── on-stop.sh # Post-response validation
│ │ ├── post-edit-lint.sh # ESLint on changed files
│ │ ├── sync-to-github.sh # Push to GitHub Project
│ │ ├── sync-from-github.sh # Pull from GitHub Project
│ │ ├── github_project_sync.py # Sync engine (Python)
│ │ ├── github-sync-config.json # GitHub Project metadata
│ │ └── github-project-map.json # Ticket ↔ GitHub item mapping
│ ├── rules/ # Architecture & quality rules
│ │ ├── bevy-api.md # Bevy 0.19 API patterns
│ │ ├── entity-snapshot.md # ECS snapshot patterns
│ │ ├── web-quality.md # ESLint & React patterns
│ │ ├── library-apis.md # Third-party library APIs
│ │ └── file-map.md # Project file structure
│ ├── skills/ # Claude Code skills
│ │ ├── kanban/SKILL.md # Taskboard management
│ │ ├── sync-push/SKILL.md # Push to GitHub
│ │ ├── sync-pull/SKILL.md # Pull from GitHub
│ │ ├── planner/SKILL.md # Spec generation
│ │ ├── builder/SKILL.md # Code implementation
│ │ ├── cycle/SKILL.md # Plan→Build→Verify loop
│ │ └── arch-validator/ # Architecture validation
│ │ ├── SKILL.md
│ │ └── check_arch.py
│ └── taskboard.db # SQLite database (186+ tickets)
├── .github/ # GitHub Copilot
│ ├── hooks/ # hooks.json: cloud-agent-only (sessionStart, userPromptSubmitted, agentStop);
│ │ # session-setup.json, validation.json run on both (CLI uses .claude/settings.json)
│ ├── copilot-instructions.md # Copilot guidance (agentic-sync target)
│ ├── instructions/review.instructions.md # PR review criteria
│ └── skills/ # kanban, sync-push, sync-pull
├── .gemini/ # Gemini CLI (+ Antigravity model config)
│ └── settings.json # Hooks + model (gemini-3.1-pro-preview)
├── .agents/ # Shared skills (Codex CLI + Copilot + Gemini CLI); the project skills here are GENERATED mirrors of .claude/skills/ — never hand-edit them
│ ├── rules/taskboard-sync.md # Ticket enforcement rules
│ └── skills/ # kanban, sync-push, sync-pull
├── .agent/ # Google Antigravity (singular — NOT .agents/)
│ ├── rules/taskboard-sync.md # Ticket enforcement rules
│ └── skills/ # kanban, sync-push, sync-pull
├── .windsurf/ # Windsurf
│ ├── hooks.json # Hook wiring (post_write_code, pre_user_prompt, etc.)
│ ├── rules/taskboard.md # Ticket enforcement rules
│ └── workflows/ # sync-push.md, sync-pull.md
└── .codex/ # OpenAI Codex CLI
├── config.toml # Model (gpt-5.3-codex), approval policy, sandbox (hand-edited)
├── AGENTS.md # Full instructions
├── agents/ # Subagents — GENERATED from .claude/agents/
├── hooks.json # Hook wiring — GENERATED from .claude/settings.json
├── hook-conditions.json # `if` conditions of NON-blocking hooks only (a PreToolUse `if` is left out on purpose) — GENERATED
└── hooks/run-claude-hook.mjs # Adapter: Codex hook payload → shared .claude/hooks scripts
Contributing
Contributions are welcome! Here's how to get involved.
Forking the repository
- Click the Fork button at the top-right of the repository page
- Clone your fork locally:
git clone https://github.com/<your-github-handle>/project-forge.git cd project-forge - Add the upstream remote:
git remote add upstream https://github.com/Tristan578/project-forge.git
Creating a Pull Request
- Create a feature branch from
main:git checkout -b feature/your-feature-name - Make your changes and verify they work:
# Build WASM engine ./build_wasm.sh # macOS/Linux # .\build_wasm.ps1 # Windows # TypeScript check cd web && npx tsc --noEmit # Run tests cd web && npx vitest run cd ../mcp-server && npx tsc --noEmit && npx vitest run - Commit your changes with a clear message:
git add <files> git commit -m "feat: add your feature description" - Push to your fork:
git push origin feature/your-feature-name - Open a Pull Request on the upstream repository. Include:
- A summary of what changed and why
- Steps to test the changes
- Screenshots if the change is visual
Submitting an Issue
- Go to the Issues tab
- Click New Issue
- Choose the appropriate template (bug report or feature request), or open a blank issue
- Include:
- Bug reports: Steps to reproduce, expected vs. actual behavior, browser/OS info, console errors
- Feature requests: Description of the feature, use case, and any proposed implementation ideas
Code style
- Rust: Follow standard
rustfmtconventions. All code must compile forwasm32-unknown-unknown. - TypeScript/React: Follow the ESLint config in
web/eslint.config.mjs. Use functional components with hooks. - Commits: Use Conventional Commits format (
feat:,fix:,docs:,refactor:, etc.).
Tech Stack
| Layer | Technology |
|---|---|
| Engine | Bevy 0.19, wgpu 29, bevy_rapier3d/2d 0.35, bevy_hanabi 0.19, bevy_panorbit_camera 0.35, csgrs 0.20, noise 0.9 |
| Frontend | Next.js 16, React 19, Zustand 5, Tailwind CSS, React Flow |
| Auth | Clerk |
| Payments | Stripe |
| Database | Neon (PostgreSQL) + Drizzle ORM |
| Build | wasm-bindgen, wasm-pack |
License
This project is licensed under the Business Source License 1.1. You may fork, modify, and contribute, but commercial use is prohibited. The license converts to Apache 2.0 on February 11, 2030. See LICENSE for full terms.