neversight/learn-skills.dev/threejs-game
Claude Code and agent skill by neversight/learn-skills.dev
- community
- ext:[{"type":"plugin","description":"Custom plugin integration"}]
Checking that the SKILL.md file is still in the repository.
Build 3D browser games with Three.js using event-driven modular architecture. Use when creating a new 3D game, adding 3D game features, setting up Three.js scenes, or working on any Three.js game project.
Install
npx vskill@latest install neversight/learn-skills.dev/threejs-gameSemi-extensibleMentions customization, but needs skill-specific knowledge. Read the extensible skills standard
SKILL.md
Three.js Game Development
You are an expert Three.js game developer. Follow these opinionated patterns when building 3D browser games.
Reference: Seereference/llms.txt(quick guide) andreference/llms-full.txt(full API + TSL) for official Three.js LLM documentation. Prefer patterns from those files when they conflict with this skill.
Performance Notes
- Take your time with each step. Quality is more important than speed.
- Do not skip validation steps — they catch issues early.
- Read the full context of each file before making changes.
- Profile before optimizing. The bottleneck is rarely where you think.
Reference Files
For detailed reference, see companion files in this directory:
core-patterns.md— Full EventBus, GameState, Constants, and Game.js orchestrator codetsl-guide.md— Three.js Shading Language reference (NodeMaterial classes, when to use TSL)input-patterns.md— Gyroscope input, virtual joystick, unified analog InputSystem, input priority system
For performance optimization patterns with measured before/after evidence, see the threejs-perf skill (skills/threejs-perf/SKILL.md).
Tech Stack
- Renderer: Three.js (
three@0.183.0+, ESM imports) - Build Tool: Vite
- Language: JavaScript (not TypeScript) for game templates — TypeScript optional
- Package Manager: npm
Project Setup
When scaffolding a new Three.js game:
Create vite.config.js:
Add to package.json scripts:
Modern Import Patterns
Vite / npm (default — used in our templates)
Import Maps / CDN (standalone HTML games, no build step)
Use import maps when shipping a single HTML file with no build tooling. Pin the version in the import map URL.
Required Architecture
Every Three.js game MUST use this directory structure:
Core Principles
- Core loop first — Implement one camera, one scene, one gameplay loop. Add player input and a terminal condition (win/lose) before adding visual polish. Keep initial scope small: 1 mechanic, 1 fail condition, 1 scoring system.
- Gameplay clarity > visual complexity — Treat 3D as a style choice, not a complexity mandate. A readable game with simple materials beats a visually complex but confusing one.
- Restart-safe — Gameplay must be fully restart-safe.
GameState.reset()must restore a clean slate. Dispose geometries/materials/textures on cleanup. No stale references or leaked listeners across restarts.
Core Patterns (Non-Negotiable)
Every Three.js game requires these four core modules. Full implementation code is in core-patterns.md.
1. EventBus Singleton
ALL inter-module communication goes through an EventBus (core/EventBus.js). Modules never import each other directly for communication. Provides on, once, off, emit, and clear methods. Events use domain:action naming (e.g., player:hit, game:over). See core-patterns.md for the full implementation.
2. Centralized GameState
One singleton (core/GameState.js) holds ALL game state. Systems read from it, events update it. Must include a reset() method that restores a clean slate for restarts. See core-patterns.md for the full implementation.
3. Constants File
Every magic number, balance value, asset path, and configuration goes in core/Constants.js. Never hardcode values in game logic. Organize by domain: PLAYER_CONFIG, ENEMY_CONFIG, WORLD, CAMERA, COLORS, ASSET_PATHS. See core-patterns.md for the full implementation.
4. Game.js Orchestrator
The Game class (core/Game.js) initializes everything and runs the render loop. Uses renderer.setAnimationLoop() -- the official Three.js pattern (handles WebGPU async correctly and pauses when the tab is hidden). Sets up renderer, scene, camera, systems, UI, and event listeners in init(). See core-patterns.md for the full implementation.
Renderer Selection
WebGLRenderer (default — use for all game templates)
Maximum browser compatibility. Well-established, most examples and tutorials use this. Our templates default to WebGLRenderer.
WebGPURenderer (when you need TSL or compute shaders)
Required for custom node-based materials (TSL), compute shaders, and advanced rendering. Note: import path changes to 'three/webgpu' and init is async.
When to pick WebGPU: You need TSL custom shaders, compute shaders, or node-based materials. Otherwise, stick with WebGL. See tsl-guide.md for TSL details.
Play.fun Safe Zone
When games run inside the Play.fun dashboard on mobile Safari, the SDK sets CSS custom properties on the game iframe's document.documentElement:
--ogp-safe-top-inset— space below the Play.fun header bubbles (~68px on mobile)--ogp-safe-bottom-inset— space above Safari bottom controls (~148px on mobile)
Both default to 0px when not running inside the dashboard (desktop, standalone).
Constants
CSS Rule
All .overlay elements (game-over, pause, menus) must use the CSS variables for padding:
Bottom-positioned UI (joysticks, action buttons) must also respect the bottom inset:
What to Check
- No text, buttons, or interactive elements in the top or bottom inset areas
- Game-over overlays center content in the usable area (between both insets), not the full viewport
- Score displays, titles, and restart buttons are all visible and not hidden behind browser chrome
- Bottom-positioned controls (joysticks, action buttons) are not clipped by Safari bottom bar
Note: The 3D canvas itself renders behind the chrome, which is fine — the game should bleed to fill the full viewport. Only HTML overlay UI needs the safe zone offset. In-world 3D elements (HUD textures, floating text) should avoid the top 8% and bottom inset of screen space.
Performance Rules
- Use `renderer.setAnimationLoop()` instead of manual
requestAnimationFrame. It pauses when the tab is hidden and handles WebGPU async correctly. - Cap delta time:
Math.min(clock.getDelta(), 0.1)to prevent death spirals - Cap pixel ratio:
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))— avoids GPU overload on high-DPI screens - Object pooling: Reuse
Vector3,Box3, temp objects in hot loops to minimize GC. Avoid per-frame allocations — preallocate and reuse. - Disable shadows on first pass — Only enable shadow maps when specifically needed and tested on mobile. Dynamic shadows are the single most expensive rendering feature.
- Keep draw calls low — Fewer unique materials and geometries = fewer draw calls. Merge static geometry where possible. Use instanced meshes for repeated objects. See
skills/threejs-perf/for InstancedMesh patterns (~9,000× fewer draw calls, ~57× faster render CPU). - Prefer simple materials — Use
MeshBasicMaterialorMeshStandardMaterial. AvoidMeshPhysicalMaterial, custom shaders, or complex material setups unless specifically needed. - No postprocessing by default — Skip bloom, SSAO, motion blur, and other postprocessing passes on first implementation. These tank mobile performance. Add only after gameplay is solid and perf budget allows.
- Keep geometry/material count small — A game with 10 unique materials renders faster than one with 100. Reuse materials across objects with the same appearance.
- Use `powerPreference: 'high-performance'` on the renderer
- Dispose properly: Call
.dispose()on geometries, materials, textures when removing objects - Frustum culling: Let Three.js handle it (enabled by default) but set bounding spheres on custom geometry
Asset Loading
- Place static assets in
/public/for Vite - Use GLB format for 3D models (smaller, single file)
- Use
THREE.TextureLoader,GLTFLoaderfromthree/addons - Show loading progress via callbacks to UI
Input Handling (Mobile-First)
All games MUST work on desktop AND mobile unless explicitly specified otherwise. Allocate 60% effort to mobile / 40% desktop when making tradeoffs. Choose the best mobile input for each game concept:
| Game Type | Primary Mobile Input | Fallback | |
|---|---|---|---|
| Marble/tilt/balance | Gyroscope (DeviceOrientation) | Virtual joystick | |
| Runner/endless | Tap zones (left/right half) | Swipe gestures | |
| Puzzle/turn-based | Tap targets (44px min) | Drag & drop | |
| Shooter/aim | Virtual joystick + tap-to-fire | Dual joysticks | |
| Platformer | Virtual D-pad + jump button | Tilt for movement |
Unified Analog InputSystem
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 90 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingdata/skills-md/playableintelligence/game-creator/threejs-game/SKILL.md
Popularity
- 7-day trend score
- 0
Not refreshed yet.
Extension points
pluginCustom plugin integration
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/neversight/learn-skills.dev/threejs-game)