Skip to main content
skill CX Codex

add-3d-assets — Claude Code skill: real GLB models in Three.js

Swaps primitives like BoxGeometry for actual GLB models: animated characters, houses, trees, barrels. Useful when your Three.js game still looks like a pile of boxes.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add PlayableIntelligence/game-creator --skill add-3d-assets -a claude-code
Open on GitHub

What add-3d-assets does

The skill reads your project, finds every BoxGeometry and SphereGeometry, and replaces them with models. Characters and enemies go through Meshy AI: a text prompt, then rigging, then Idle, Walk and Run clips. World objects — houses, trees, barrels, coins — are either generated the same way or pulled from free libraries such as Poly Haven and Sketchfab.

Meshy needs a MESHY_API_KEY. The skill checks .env first and only asks you to paste a key if it comes up empty, saving it back to .env. Type "skip" and it falls back to the bundled character library: Soldier, Xbot, RobotExpressive and Fox, each with its own animation set.

Integration runs in steps. It creates src/level/AssetLoader.js, adds CHARACTER, ASSET_PATHS and MODEL_CONFIG to Constants.js, wires an AnimationMixer with crossfade into Player.js, and adds OrbitControls in Game.js for a third-person camera. One detail bites people: animated models need SkeletonUtils.clone() from three/addons/utils/SkeletonUtils.js. A plain .clone() copies the mesh without the skeleton, so the character freezes in a T-pose. At the end it suggests running npm run dev and npm run build, plus generating ATTRIBUTION.md from the .meta.json files.

What it helps with

  • replace box primitives with real GLB models
  • generate a character from a text prompt and rig it
  • set up crossfade between Idle, Walk and Run
  • add a third-person camera with OrbitControls
  • fix a model stuck in T-pose

Example prompts for the agent

  • /add-3d-assets examples/space-explorer
  • /add-3d-assets
  • replace the primitives with GLB models in this project

How to install add-3d-assets

1Skills CLI (Vercel)

npx skills add PlayableIntelligence/game-creator --skill add-3d-assets -a claude-code

2Manually: put the files in place

~/.claude/skills/add-3d-assets/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/add-3d-assets/

Step by step, with commands for each platform: How to install skills in Claude Code: five ways

Questions about add-3d-assets

How do I install add-3d-assets in Claude?

Run npx skills add PlayableIntelligence/game-creator --skill add-3d-assets -a claude-code. The skill then lands in ~/.claude/skills/add-3d-assets/SKILL.md.

What does add-3d-assets do?

It finds Three.js primitives in your project and swaps them for GLB models: animated characters via Meshy AI, plus environment objects from libraries or the same generator. It also sets up the loader, animations and camera.

What do I need before running it?

A MESHY_API_KEY for model generation. Without one, the skill falls back to the free character library and asset search.

Source text

SKILL.md · MIT
---
name: add-3d-assets
description: Replace primitive 3D shapes with real GLB models — animated characters, world props, buildings, and scenery for Three.js games. Use when the user says "add 3D models", "replace the boxes with real models", "add GLB assets", or "make the 3D game look real". For 2D pixel art, use add-assets instead. Do NOT use for 2D pixel art (use add-assets) or gameplay changes (use add-feature).
argument-hint: "[path-to-game]"
license: MIT
metadata:
  author: OpusGameLabs
  version: 1.3.0
  tags: [game, 3d, assets, glb, models, threejs]
---

## Performance Notes

- Take your time to do this thoroughly
- Quality is more important than speed
- Do not skip validation steps

# Add 3D Assets

Replace basic geometric shapes (BoxGeometry, SphereGeometry) with real 3D models. Characters get custom Meshy AI-generated models with rigging and animation. World objects get generated or sourced from free libraries.

## Instructions

Analyze the game at `$ARGUMENTS` (or the current directory if no path given).

First, load the game-3d-assets skill and the meshyai skill for the full model pipeline, AssetLoader pattern, Meshy generation, and integration patterns.

### Step 1: Get Meshy API Key

Check if `MESHY_API_KEY` is set. First check `.env`:
`test -f .env && grep -q '^MESHY_API_KEY=.' .env && echo "found"`
If found, export it with `set -a; . .env; set +a` and skip the prompt.

If not set, ask the user:

> I'll generate custom 3D models with Meshy AI for the best results. You can get a free API key in 30 seconds:
> 1. Sign up at https://app.meshy.ai
> 2. Go to Settings → API Keys
> 3. Create a new API key
>
> Paste your key below like: `MESHY_API_KEY=your-key-here`
> (It will be saved to .env and redacted from this conversation automatically.)
>
> Or type "skip" to use free model libraries instead.

### Step 2: Audit

- Read `package.json` to confirm this is a Three.js game (not Phaser — use `/add-assets` for 2D games)
- Read `src/core/Constants.js` for entity types, sizes, colors
- Read entity files (`src/gameplay/*.js`, `src/entities/*.js`) — find `BoxGeometry`, `SphereGeometry`, etc.
- Read `src/level/LevelBuilder.js` for environment primitives
- List every entity using geometric shapes
- Identify which entity is the **player character** (needs animated model)

### Step 3: Plan

Split entities into two categories:

**Animated characters** (player, enemies with AI) — generate with Meshy AI:

| Entity | Meshy Prompt | Notes |
|--------|-------------|-------|
| Player | "a heroic knight, low poly game character, full body, t-pose" | Generate → rig → animate |
| Enemy | "a goblin warrior with a club, low poly game character" | Generate → rig → animate |

If Meshy unavailable, fall back to `assets/3d-characters/`:
- **Soldier** — realistic military (Idle, Walk, Run) — best default
- **Xbot** — stylized mannequin (idle, walk, run + additive poses)
- **RobotExpressive** — cartoon robot (Idle, Walking, Running, Dance, Jump + 8 more)
- **Fox** — low-poly animal (Survey, Walk, Run) — scale 0.02

**World objects** (buildings, props, scenery, collectibles) — generate with Meshy or search free libraries:

| Entity | Meshy Prompt | Fallback Source |
|--------|-------------|-----------------|
| Tree | "a low poly stylized tree, game asset" | Poly Haven |
| House | "a medieval house, low poly game asset" | Poly Haven |
| Barrel | "a wooden barrel, low poly game asset" | Poly Haven |
| Coin | "a gold coin, game collectible item" | Sketchfab |

### Step 4: Generate / Download

**With Meshy (preferred):**
```bash
# Generate characters
MESHY_API_KEY=<key> node <plugin-root>/scripts/meshy-generate.mjs \
  --mode text-to-3d \
  --prompt "a heroic knight, low poly game character, full body" \
  --polycount 15000 --pbr \
  --output public/assets/models/ --slug player

# Rig characters for animation
MESHY_API_KEY=<key> node <plugin-root>/scripts/meshy-generate.mjs \
  --mode rig --task-id <refine-task-id> --height 1.7 \
  --output public/assets/models/ --slug player-rigged

# Generate static props
MESHY_API_KEY=<key> node <plugin-root>/scripts/meshy-generate.mjs \
  --mode text-to-3d \
  --prompt "a wooden barrel, low poly game asset" \
  --polycount 5000 \
  --output public/assets/models/ --slug barrel
```

**Without Meshy (fallback):**
```bash
# Characters — copy from library
cp <plugin-root>/assets/3d-characters/models/Soldier.glb public/assets/models/

# World objects — search and download
node <plugin-root>/scripts/find-3d-asset.mjs --query "barrel" --source polyhaven \
  --output public/assets/models/ --slug barrel
```

### Step 5: Integrate

1. Create `src/level/AssetLoader.js` — **use `SkeletonUtils.clone()` for animated models** (import from `three/addons/utils/SkeletonUtils.js`). Regular `.clone()` breaks skeleton → T-pose.
2. Add `CHARACTER` to Constants.js with `path`, `scale`, `facingOffset`, `clipMap`
3. Add `ASSET_PATHS` and `MODEL_CONFIG` for static models
4. Update `Player.js`:
   - `THREE.Group` as position anchor
   - `loadAnimatedModel()` + `AnimationMixer`
   - `fadeToAction()` for idle/walk/run crossfade
   - Camera-relative WASD via `applyAxisAngle(_up, cameraAzimuth)`
   - Model facing: `atan2(v.x, v.z) + CHARACTER.facingOffset`
   - `model.quaternion.rotateTowards(targetQuat, turnSpeed * delta)`
5. Update `Game.js`:
   - Add `OrbitControls` — third-person camera orbiting player
   - Camera follows: move `orbitControls.target` + `camera.position` by player delta
   - Pass `orbitControls.getAzimuthalAngle()` to Player for camera-relative movement
6. Replace environment primitives with `loadModel()` calls + `.catch()` fallback
7. Add `THREE.GridHelper` for visible movement reference
8. Preload all models on startup with `preloadAll()` for instant loading

### Step 6: Tune & Verify

- Run `npm run dev` — walk around with WASD, orbit camera with mouse
- Confirm character animates (Idle when stopped, Walk when moving, Run with Shift)
- Adjust `MODEL_CONFIG` values (scale, rotationY, offsetY) per model
- Run `npm run build` to confirm no errors
- Generate `ATTRIBUTION.md` from `.meta.json` files

## Example Usage

### With Meshy AI
```
/add-3d-assets examples/space-explorer
```
Result: Generates custom knight model via Meshy → rigs and animates (Idle/Walk/Run) → replaces BoxGeometry player with animated GLB → adds OrbitControls camera → world props from free libraries.

### Without Meshy (fallback)
```
/add-3d-assets examples/3d-platformer
```
Result: Copies Soldier.glb from character library → configures SkeletonUtils.clone() → fadeToAction animation crossfade → replaces all primitives with library/downloaded models.

## Troubleshooting

### Model stuck in T-pose (not animating)
**Cause:** Using `.clone(true)` instead of `SkeletonUtils.clone()` breaks skeleton bindings on animated GLB models.
**Fix:** Always use `SkeletonUtils.clone()` from `three/addons/utils/SkeletonUtils.js` for any model with animations. Regular `.clone()` copies the mesh but not the skeleton bindings.

### Meshy AI generation fails or returns low quality
**Cause:** Vague prompts or wrong generation mode selected.
**Fix:** Use specific, descriptive prompts (e.g., "low-poly medieval wooden treasure chest, game asset" not "chest"). For characters, use image-to-3D mode with a reference image. Set art style to "game-asset" or "low-poly" for better game integration.

### Rigging fails on generated model
**Cause:** The model geometry is not suitable for auto-rigging (too complex, non-manifold, or not humanoid).
**Fix:** Simplify the prompt to produce cleaner geometry. Ensure the model is a single connected mesh in a humanoid pose. Non-humanoid models (props, vehicles) should not be rigged — use them as static assets instead.

### meshopt decoder error on load
**Cause:** Some GLB files use meshopt compression which requires a decoder not loaded by default.
**Fix:** Add the meshopt decoder before loading: `import { MeshoptDecoder } from 'three/addons/libs/meshopt_decoder.module.js'; loader.setMeshoptDecoder(MeshoptDecoder);`

### Model facing wrong direction
**Cause:** Different model sources use different forward directions. Mixamo models face -Z, some others face +Z.
**Fix:** Store a `facingOffset` per character model. Apply it as `model.rotation.y = facingOffset + movementAngle`. Common values: Soldier/Xbot need `+Math.PI`, Robot/Fox need `+0`.

## Next Step

Tell the user:

> Your 3D game now has custom models! Characters were generated with Meshy AI (or sourced from the model library), rigged, and animated. World objects are loaded from GLB files.
>
> **Files created:**
> - `src/level/AssetLoader.js` — model loader with SkeletonUtils
> - `public/assets/models/` — generated and downloaded GLB models
> - OrbitControls third-person camera
>
> **Controls:** WASD to move, Shift to run, mouse drag to orbit camera, scroll to zoom.
> Run the game to see everything in action. Adjust `MODEL_CONFIG` in Constants.js to fine-tune scale and orientation.

© OpusGameLabs · MIT · PlayableIntelligence/game-creator

Similar skills

Everything for Game dev and 3D: Unity, Unreal, Godot, Blender →

From the same set27

add-audio This skill adds background music and sound effects to a browser game using the Web Audio API. No audio files, no npm packages — everything is synthesized in the browser. CX Codex +1 1,000installs add-assets Swaps the circles and rectangles in a 2D game for pixel art sprites of characters, enemies and items. Useful once the prototype plays fine but looks like a wireframe. CX Codex +1 997installs add-feature Adds gameplay mechanics to Three.js or Phaser browser games. It helps implement power-ups, combo systems, or double jumps while keeping the core architecture intact. CX Codex +1 977installs review-game Audits an existing game project for architecture, performance, code quality and monetization readiness. Read-only, no edits. CX Codex +1 954installs qa-game Sets up Playwright automated tests for web games, covering boot sequences, scene transitions, visual regressions, and FPS. Useful for verifying game mechanics without manual runs. CX Codex +1 931installs meshyai Generates 3D models from text or images with Meshy AI, rigs humanoids, and pulls in walk and run animations for Three.js games. CX Codex +1 907installs quick-game Scaffolds and implements a playable game prototype using Phaser or Three.js. Built for rapid gameplay testing without assets, audio, or visual polish. CX Codex +1 866installs monetize-game Registers your web game on Play.fun, integrates the browser SDK for rewards and leaderboards, and generates a ready-to-share play.fun URL. CX Codex +1 862installs

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor