add-3d-assets
Replace primitive 3D shapes with real GLB models — animated characters, world props, buildings, and scenery for Three.js games.…
Three.js performance optimization patterns for draw calls, scene traversal, and instancing. Use when optimizing 3D scenes with 100+ repeated objects, thousands of moving entities, or draw calls above 500. Loaded by threejs-game, viral-game, and make-game for performance guidance.
$ npx -y skills add playableintelligence/game-creator --skill threejs-perf --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/threejs-perfContext preview
The summary Claude sees to decide when to auto-load this skill.
Three.js performance optimization patterns for draw calls, scene traversal, and instancing. Use when optimizing 3D scenes with 100+ repeated objects, thousands of moving entities, or draw calls above 500. Loaded by threejs-game, viral-game, and make-game for performance guidance.
name: threejs-perf description: Three.js performance optimization patterns for draw calls, scene traversal, and instancing. Use when optimizing 3D scenes with 100+ repeated objects, thousands of moving entities, or draw calls above 500. Loaded by threejs-game, viral-game, and make-game for performance guidance. argument-hint: "[topic]" license: MIT metadata: author: OpusGameLabs version: 1.3.0 tags: [threejs, performance, instancing, draw-calls, optimization]
Performance patterns for Three.js games, backed by measured before/after numbers on Three.js r183 (headless Chromium via Playwright, Apple M1 Pro, software WebGL).
**Problem**: Forests, debris, decorations as individual Meshes = unnecessary draw calls.
**Solution**: One `InstancedMesh` per shared geometry+material combo.
**Evidence**: ~19,365 → 2 draw calls. Render CPU p95: 28.5ms → 0.5ms (~57× faster). Build: 39.4ms → 3.9ms. See `instancing-static.md`.
// Anti-pattern: one Mesh per prop
for (let i = 0; i < 19600; i++) {
const mesh = new THREE.Mesh(geometry, material);
mesh.position.set(x, 0, z);
scene.add(mesh); // 19,600 draw calls
}
// Correct: one InstancedMesh
const im = new THREE.InstancedMesh(geometry, material, 19600);
const mat = new THREE.Matrix4();
for (let i = 0; i < 19600; i++) {
mat.makeTranslation(x, 0, z);
im.setMatrixAt(i, mat);
}
im.instanceMatrix.needsUpdate = true;
scene.add(im); // 1 draw call**Problem**: Thousands of moving actors as individual Meshes = scene-graph churn + transform propagation.
**Solution**: Flat entity state buffer + batched `InstancedMesh.setMatrixAt()` writes.
**Evidence**: 8,000 → 1 draw calls. Render CPU p95: 9.9ms → 0.5ms (~20× faster). Update loop p95: 1.4ms → 0.3ms. See `instancing-moving.md`.
// Anti-pattern: per-entity Mesh position writes
meshes.forEach((mesh, i) => {
mesh.position.x = computeX(i, tick);
mesh.position.y = computeY(i, tick);
});
// Correct: batched instance matrix writes
const mat = new THREE.Matrix4();
for (let i = 0; i < count; i++) {
mat.makeTranslation(computeX(i, tick), computeY(i, tick), computeZ(i, tick));
instancedMesh.setMatrixAt(i, mat);
}
instancedMesh.instanceMatrix.needsUpdate = true;Is the object repeated 50+ times with same geometry+material? ├── YES → Is it static (no per-frame movement)? │ ├── YES → Pattern 1: Static InstancedMesh (instancing-static.md) │ └── NO → Pattern 2: Moving InstancedMesh with batched writes (instancing-moving.md) └── NO → Standard Mesh is fine. Focus on material/geometry reuse.
Headless Chromium 147 via Playwright, Three.js r183, Apple M1 Pro, 30 warmup + 180 sample frames, median of 3 runs.
| Scenario | Metric | Baseline | Optimized | Improvement | |----------|--------|----------|-----------|-------------| | Static World (19.6k cubes) | Draw calls | ~19,365 | 2 | ~9,682× | | Static World (19.6k cubes) | Render CPU p95 | 28.5ms | 0.5ms | ~57× | | Static World (19.6k cubes) | Build | 39.4ms | 3.9ms | ~10× | | Moving Entities (8k wave-field) | Draw calls | 8,000 | 1 | 8,000× | | Moving Entities (8k wave-field) | Render CPU p95 | 9.9ms | 0.5ms | ~20× | | Moving Entities (8k wave-field) | Update loop p95 | 1.4ms | 0.3ms | ~4.7× |
Go from game idea to deployed, monetized browser game in minutes — not hours. Tell your AI coding agent "make a space invaders game" and get a fully playable 2D or 3D browser game with pixel art, procedural audio, and automated QA. Deploy instantly to the web.
Replace primitive 3D shapes with real GLB models — animated characters, world props, buildings, and scenery for Three.js games.…
Replace geometric shapes with pixel art sprites — recognizable characters, enemies, and items with optional animation. Use when…
Add music and sound effects to a game using the Web Audio API — background music, gameplay themes, and SFX. Zero dependencies.…
Add a new gameplay feature to an existing browser game following its architecture patterns. Use when the user says "add a…
Add real-time or turn-based multiplayer to an existing browser game using PartyKit (Cloudflare Durable Objects). Scaffolds a…
Audit and improve the visual design, polish, and player experience of an existing game. Use when the user says "make my game look…