Wulai: A React + Three.js Browser Action Game with Procedural Art and a Mobile Performance Budget
A full 3D action game can ship in the browser without a game engine, as long as performance is budgeted numerically; the same discipline makes AI coding agents stop repeating mistakes by encoding every fix into enforceable project rules.
Wulai is a full 3D action game that runs in the browser, built with React 18, React Three Fiber v8, and three.js r168. No game engine, no external art assets: the character, terrain, trees, rocks, monsters, and skill effects are all procedural geometry from code. The only imported model is the SU7. The map is 260m × 260m with a winding path, 165 monsters, six weapons, two bosses, and a drivable car with a nitrous system.
Performance is treated as a numeric budget. A permanent pool of four point lights prevents shader recompilation stalls; shaders pre-warm during browser idle; repeated objects go through InstancedMesh; and terrain is a single pure function queried by the ground, vegetation, spawns, and vehicle. A built-in probe at ?perf=auto runs the full move set and reports metrics, with acceptance criteria of zero new shaders, four lights, max ~20ms frame time, and draw calls capped at 660.
Five production-only pitfalls are documented: Vite circular chunks that break initialization, a Suspense fallback that duplicates the canvas build, stale visualViewport reads on iOS rotation, Xiaomi long-press spawning system UI, and gltf-transform optimize flattening wheel nodes. Each fix is encoded into project rules and skills that guide Cursor's coding agent, so recurring mistakes fade. The combination of numeric performance gates and AI-rule enforcement is what makes the game playable on phones.
Keeping per-frame state in module singletons outside React is a clean pattern for any animation-heavy React app; it avoids re-render storms without extra libraries.
The light pool and shader pre-warm are specific to three.js but the underlying principle (prevent runtime shader compilation) applies broadly to WebGL/GPU apps.
Turning each bug fix into a rule for the AI coding agent works because it turns tribal knowledge into executable constraints; that's a transferable practice for any AI-assisted development.
Building art via code, with anchor tables and loft profiles, makes "changing art" as fast as changing code, but it requires an unusual tolerance for debugging geometry.