Agent skill

Game 3D Assets

by corosolto in corosolto/client

3D asset engineer that finds, downloads, and integrates GLB/GLTF models into Three.js browser games.

MITAuto-check: notesGame Development

Install Game 3D Assets

skills CLI
$ npx skills add corosolto/client --skill game-3d-assets -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install corosolto/client game-3d-assets --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/corosolto/client.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/game-3d-assets .claude/skills/game-3d-assets && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
game-3d-assets
GitHub stars
257
Token cost
~5.4k tokens
SKILL.md length
1,900 words
Files
1
Skills in repo
21
Repo updated
First seen
Licence
MIT

At a glance

3D asset engineer that finds, downloads, and integrates GLB/GLTF models into Three.js browser games.

  • Works in 6 steps: Check Meshy API Key → Audit → Plan → …
  • A 3D game needs real models instead of primitive BoxGeometry/SphereGeometry shapes
  • SKILL.md covers Philosophy, Character Selection — Tiered…, Sketchfab Token (Tier 3… and Search & Download Script, plus 6 more sections
  • Calls node, npm and curl; reaches raw.githubusercontent.com; needs MESHY_API_KEY and SKETCHFAB_TOKEN

What it does

Game 3D Assets is an agent skill from corosolto/client. 3D asset engineer that finds, downloads, and integrates GLB/GLTF models into Three.js browser games. Use when a 3D game needs real models instead of primitive BoxGeometry/SphereGeometry shapes.

Its SKILL.md is about 5.4k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Game Development, covering Game assets and audio and 3D graphics and WebGL. It works with Three.js. The repository describes itself as: FPS satírico de navegador: 5 facções brasileiras caricatas, 44 personagens, 5 mapas e 26 armas — rounds e Capture the Flag contra bots, direto na aba, sem instalar nada. Three.js… The licence is MIT.

When your agent uses it

  • A 3D game needs real models instead of primitive BoxGeometry/SphereGeometry shapes
  • Tasks that involve Game assets and audio
  • Tasks that involve 3D graphics and WebGL

Example prompts

  • “/game-3d-assets”

Requirements

  • A credential in MESHY_API_KEY
  • A credential in SKETCHFAB_TOKEN

Workflow steps

6 steps, taken from the step headings in SKILL.md.

  1. Check Meshy API Key
  2. Audit
  3. Plan
  4. Generate / Download
  5. Integrate
  6. Verify

What it can do on your machine

Read from SKILL.md and the folder at commit 23c16f5. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • node
    • npm
    • curl

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Hosts in commands or code, which the agent is likely to contact:

    • raw.githubusercontent.com

    Also links to:

    • sketchfab.com

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names these keys or tokens, usually read from environment variables:

    • MESHY_API_KEY
    • SKETCHFAB_TOKEN
    • POLY_PIZZA_API_KEY

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Game 3D Assets loads about 5.4k tokens when it runs. Until then it costs about 52 tokens; SKILL.md has 1,900 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~52
When it runs · the whole SKILL.md, loaded when a task matches
~5.4k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check: notes

The automated check noted patterns worth knowing about, such as sudo or a known installer.

  • NoteMentions a .env fileSKILL.md:34
    `test -f .env && grep -q '^MESHY_API_KEY=.' .env && echo "found"`
  • NoteMentions a .env fileSKILL.md:35
    If found, export it with `set -a; . .env; set +a` and skip the prompt.
  • NoteMentions a .env fileSKILL.md:45
    > (It will be saved to .env and redacted from this conversation automatically.)
  • NoteMentions a .env fileSKILL.md:150
    `test -f .env && grep -q '^SKETCHFAB_TOKEN=.' .env && echo "found"`
  • NoteMentions a .env fileSKILL.md:151
    If found, export it with `set -a; . .env; set +a` and skip the prompt.
  • NoteMentions a .env fileSKILL.md:161
    > (It will be saved to .env and redacted from this conversation automatically.)
  • NoteMentions a .env fileSKILL.md:163
    Then use it via: `set -a; . .env; set +a && node scripts/find-3d-asset.mjs ...`
  • NoteMentions a .env fileSKILL.md:442
    ompts. The API key is stored in a local `.env` file and passed only to the Meshy API. Generated models are downloaded as
  • NoteMentions a .env fileSKILL.md:443
    FAB_TOKEN`) are stored in the project's `.env` file (which should be gitignored) and loaded via environment variables. K

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from corosolto/client at commit 23c16f5, republished under its MIT licence (© corosolto). 1,900 words, ~5,421 tokens.

Download SKILL.mdSave it as .claude/skills/game-3d-assets/SKILL.md (or your agent's skills folder).
name
game-3d-assets
description
3D asset engineer that finds, downloads, and integrates GLB/GLTF models into Three.js browser games. Use when a 3D game needs real models instead of primitive BoxGeometry/SphereGeometry shapes.
argument-hint
[topic]
license
MIT
metadata.author
OpusGameLabs
metadata.version
1.3.0
metadata.tags
game, 3d, assets, glb, gltf, threejs, animation, sketchfab

Game 3D Asset Engineer (Model Pipeline)

You are an expert 3D game artist and integrator. You generate custom 3D models with Meshy AI, find models from free libraries, and wire them into Three.js games — replacing primitive geometry with recognizable 3D models.

Philosophy

Primitive cubes and spheres are fast to scaffold, but players can't tell a house from a tree. Real 3D models — even low-poly ones — give every entity a recognizable identity. Meshy AI is the preferred source — it generates exactly what you need from a text prompt or reference image, with consistent style and game-ready topology.

Asset Tiers
TierSourceAuthBest for
1. Meshy AI (preferred)meshy.aiMESHY_API_KEYCustom characters, props, and scenery from text/image — exact match to game theme
2. Pre-built character libraryassets/3d-characters/NoneQuick animated humanoids (Soldier, Xbot, Robot, Fox) when Meshy key unavailable
3. Sketchfabsketchfab.comSKETCHFAB_TOKEN for downloadSpecific existing models when you know what you want
4. Poly Havenpolyhaven.comNoneCC0 environment props
5. Poly.pizzapoly.pizzaPOLY_PIZZA_API_KEY10K+ low-poly CC-BY models
6. Procedural geometry (last resort)CodeN/ABoxGeometry/SphereGeometry
Meshy API Key

Meshy AI is the preferred source for all 3D assets. Before prompting the user, check if the key already exists: 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 MESHY_API_KEY is not set, ask the user before falling back to other tiers:

I'd like to generate custom 3D models with Meshy AI for the best results. You can get a free API key:

  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.

If the user provides a key, use it for all meshy-generate.mjs calls. If they skip, fall through to Tier 2+.

Pre-built Animated Characters (No Auth, Direct Download)

These GLB files from the Three.js repo have Idle + Walk + Run animations and work immediately:

ModelURLAnimationsSizeLicense
Soldierhttps://raw.githubusercontent.com/mrdoob/three.js/dev/examples/models/gltf/Soldier.glbIdle, Walk, Run, TPose2.2 MBMIT
Xbothttps://raw.githubusercontent.com/mrdoob/three.js/dev/examples/models/gltf/Xbot.glbidle, walk, run + additive poses2.9 MBMIT
RobotExpressivehttps://raw.githubusercontent.com/mrdoob/three.js/dev/examples/models/gltf/RobotExpressive/RobotExpressive.glbIdle, Walking, Running, Dance, Jump + 8 more464 KBMIT
Foxhttps://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/Fox/glTF-Binary/Fox.glbSurvey (idle), Walk, Run163 KBCC0/CC-BY 4.0
Gesture Characters (from assets/3d-characters/)

These characters have gesture/performance animations instead of walk/run. Best for standing-position games (debate, dance-off, boxing, rhythm):

ModelAnimationsFacesSizeLicense
TrumpStillLook (idle), Clap, Dance, Point, Talk, Twist1,2661.2 MBCC-BY (Sketchfab)
Biden1 Mixamo idle/sway50,0003.3 MBCC-BY (Sketchfab)

Copy from the character library (no auth needed):

bash
cp <plugin>/assets/3d-characters/models/trump.glb public/assets/models/
cp <plugin>/assets/3d-characters/models/biden.glb public/assets/models/

Trump clipMap:

js
{
  idle: 'root|TrumpStillLook_BipTrump',
  clap: 'root|TrumpClap1_BipTrump',
  dance: 'root|Trumpdance1_BipTrump',
  point: 'root|TrumpPoint_BipTrump',
  talk: 'root|TrumpTalk1_BipTrump',
  twist: 'root|TrumpTwist_BipTrump'
}

Biden clipMap:

js
{ idle: 'mixamo.com' }

Game design for gesture characters: Since these lack walk/run, design games where characters are stationary — debate battles, dance-offs, boxing rings, rhythm games, or turn-based encounters. Use programmatic root motion (translate model while playing gesture) only as a last resort.

Download with curl — no auth needed:

bash
curl -L -o public/assets/models/Soldier.glb "https://raw.githubusercontent.com/mrdoob/three.js/dev/examples/models/gltf/Soldier.glb"

Clip name mapping varies per model. Always log clip names on load and define a clipMap per character:

js
// Soldier: { idle: 'Idle', walk: 'Walk', run: 'Run' }
// Xbot:    { idle: 'idle', walk: 'walk', run: 'run' }  (lowercase)
// Robot:   { idle: 'Idle', walk: 'Walking', run: 'Running' }
// Fox:     { idle: 'Survey', walk: 'Walk', run: 'Run' }

Character Selection — Tiered Fallback

For EACH character in the game, try these tiers in order:

Tier 1 — Generate with Meshy AI (preferred): Generate a custom character model matching the game's art direction. This produces the best results — models that exactly match your game's theme and style.

bash
# Generate character from text description
MESHY_API_KEY=<key> node scripts/meshy-generate.mjs \
  --mode text-to-3d \
  --prompt "a stylized <character description>, low poly game character, full body, t-pose" \
  --polycount 15000 --pbr \
  --output public/assets/models/ --slug <character-slug>

# Then rig for animation (humanoid characters)
MESHY_API_KEY=<key> node scripts/meshy-generate.mjs \
  --mode rig --task-id <refine-task-id> \
  --height 1.7 \
  --output public/assets/models/ --slug <character-slug>-rigged

After rigging, the model comes with basic walk/run animations. Log clip names to build the clipMap.

For named personalities, be descriptive: "a cartoon caricature of <Name>, <hair/glasses/suit details>, low poly game character".

Tier 2 — Pre-built in assets/3d-characters/: If Meshy is unavailable, check manifest.json for a name/theme match. Copy the GLB. Done.

Tier 3 — Search Sketchfab for character-specific model: Use find-3d-asset.mjs:

bash
node scripts/find-3d-asset.mjs --query "<character name> animated character" --max-faces 10000 --list-only

Tier 4 — Generic library fallback: Use the best thematic match from assets/3d-characters/:

  • Soldier — action/military/generic human (default)
  • Xbot — sci-fi/tech/futuristic
  • RobotExpressive — cartoon/casual (most animations, 13 clips)
  • Fox — nature/animal

Multi-character games: When using Meshy, generate each character with distinct descriptions for visual variety. When falling back to library models, assign different models to each character (e.g., Soldier for one, Xbot for another).

Sketchfab Token (Tier 3 fallback)

Only needed if falling back to Sketchfab. Search is free but download requires SKETCHFAB_TOKEN. Before prompting, check if the key already exists: test -f .env && grep -q '^SKETCHFAB_TOKEN=.' .env && echo "found" If found, export it with set -a; . .env; set +a and skip the prompt.

If needed and not set, ask the user:

I need a Sketchfab API token to download this model. You can get one for free:

  1. Sign in at https://sketchfab.com
  2. Go to https://sketchfab.com/settings/password → "API Token"
  3. Copy the token

Paste your token below like: SKETCHFAB_TOKEN=your-token-here (It will be saved to .env and redacted from this conversation automatically.)

Then use it via: set -a; . .env; set +a && node scripts/find-3d-asset.mjs ...

Search & Download Script

Use scripts/find-3d-asset.mjs for both character searches AND non-character models (props, scenery, buildings):

bash
node scripts/find-3d-asset.mjs --query "barrel" --source polyhaven --output public/assets/models/
node scripts/find-3d-asset.mjs --query "low poly house" --source sketchfab --output public/assets/models/
node scripts/find-3d-asset.mjs --query "coin" --list-only

AssetLoader Utility

Create src/level/AssetLoader.js. Critical: use SkeletonUtils.clone() for animated models — regular .clone() breaks skeleton bindings and causes T-pose.

js
import * as THREE from 'three';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { MeshoptDecoder } from 'three/addons/libs/meshopt_decoder.module.js';
import * as SkeletonUtils from 'three/addons/utils/SkeletonUtils.js';

const loader = new GLTFLoader();
loader.setMeshoptDecoder(MeshoptDecoder); // required for meshopt-compressed GLBs
const cache = new Map();

/** Load a static (non-animated) model. Uses regular clone. */
export async function loadModel(path) {
  const gltf = await _load(path);
  const clone = gltf.scene.clone(true);
  clone.traverse((c) => {
    if (c.isMesh) { c.castShadow = true; c.receiveShadow = true; }
  });
  return clone;
}

/** Load an animated (skeletal) model. Uses SkeletonUtils.clone to preserve bone bindings. */
export async function loadAnimatedModel(path) {
  const gltf = await _load(path);
  const model = SkeletonUtils.clone(gltf.scene);
  model.traverse((c) => {
    if (c.isMesh) { c.castShadow = true; c.receiveShadow = true; }
  });
  return { model, clips: gltf.animations };
}

export function disposeAll() {
  cache.forEach((p) => p.then((gltf) => {
    gltf.scene.traverse((c) => {
      if (c.isMesh) {
        c.geometry.dispose();
        if (Array.isArray(c.material)) c.material.forEach(m => m.dispose());
        else c.material.dispose();
      }
    });
  }));
  cache.clear();
}

function _load(path) {
  if (!cache.has(path)) {
    cache.set(path, new Promise((resolve, reject) => {
      loader.load(path, resolve, undefined,
        (err) => reject(new Error(`Failed to load: ${path} — ${err.message || err}`)));
    }));
  }
  return cache.get(path);
}
Compressed GLB Support

GLBs optimized by scripts/optimize-glb.mjs (or meshy-generate.mjs / find-3d-asset.mjs which call it automatically) use meshopt compression. The MeshoptDecoder import + loader.setMeshoptDecoder() call above is required to load these compressed files. Without it, Three.js will fail to parse the geometry buffers.

CRITICAL: SkeletonUtils.clone vs .clone()
MethodUse forWhat happens
gltf.scene.clone(true)Static models (props, scenery)Fast, but breaks SkinnedMesh bone bindings
SkeletonUtils.clone(gltf.scene)Animated charactersProperly re-binds SkinnedMesh to cloned Skeleton

If you use .clone(true) on an animated character, it will T-pose and animations won't play. Always use SkeletonUtils.clone() for anything with skeletal animation.

Third-Person Character Controller

The proven pattern from the official Three.js webgl_animation_walk example:

Camera: OrbitControls with Target Follow
js
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

// Setup
const orbitControls = new OrbitControls(camera, renderer.domElement);
orbitControls.enablePan = false;
orbitControls.enableDamping = true;
orbitControls.maxPolarAngle = Math.PI / 2 - 0.05; // don't go underground
orbitControls.target.set(0, 1, 0);

// Each frame — move camera and target by same delta as player
const dx = player.position.x - oldX;
const dz = player.position.z - oldZ;
orbitControls.target.x += dx;
orbitControls.target.z += dz;
orbitControls.target.y = player.position.y + 1;
camera.position.x += dx;
camera.position.z += dz;
orbitControls.update();
Movement: Camera-Relative WASD
js
const _v = new THREE.Vector3();
const _q = new THREE.Quaternion();
const _up = new THREE.Vector3(0, 1, 0);

// Get camera azimuth from OrbitControls
const azimuth = orbitControls.getAzimuthalAngle();

// Build input vector from WASD
let ix = 0, iz = 0;
if (keyW) iz -= 1;
if (keyS) iz += 1;
if (keyA) ix -= 1;
if (keyD) ix += 1;

// Rotate input by camera azimuth → world space movement
_v.set(ix, 0, iz).normalize();
_v.applyAxisAngle(_up, azimuth);

// Move player
player.position.addScaledVector(_v, speed * delta);

// Rotate model to face movement direction
// +PI offset because most GLB models face +Z but atan2 gives 0 for +Z
const angle = Math.atan2(_v.x, _v.z) + Math.PI;
_q.setFromAxisAngle(_up, angle);
model.quaternion.rotateTowards(_q, turnSpeed * delta);
Animation: fadeToAction Pattern
js
fadeToAction(name, duration = 0.3) {
  const next = actions[name];
  if (!next || next === activeAction) return;
  if (activeAction) activeAction.fadeOut(duration);
  next.reset().setEffectiveTimeScale(1).setEffectiveWeight(1).fadeIn(duration).play();
  activeAction = next;
}

// In update loop:
if (isMoving) {
  fadeToAction(shiftHeld ? 'run' : 'walk');
} else {
  fadeToAction('idle');
}
if (mixer) mixer.update(delta);

Post-Load Verification (MANDATORY)

After loading ANY 3D model (Meshy-generated, library, or Sketchfab), always verify orientation and scale. Skipping this leads to backwards characters and models that overflow their containers.

  1. Log bounding box immediately after loading — size and center
  2. Check facing direction — most Meshy models face +Z, most library models vary. Set rotationY per model in Constants.js. Start with Math.PI for Meshy models.
  3. Check scale — calculate auto-scale to fit target height. Ensure models fit within their environment (e.g., characters inside a ring, players on a platform).
  4. Align to floor — set position.y = -box.min.y to plant feet on ground
  5. Take a Playwright screenshot to visually confirm facing + fit. Don't skip this.

See the meshyai skill's "Post-Generation Verification" section for detailed code patterns.

Show full SKILL.md (833 more words)Show less

Common Pitfalls

  1. T-posing animated characters — You used .clone() instead of SkeletonUtils.clone(). The skeleton binding is broken.
  2. Model faces wrong direction — Meshy models typically face +Z. Add rotationY: Math.PI in Constants.js. Always verify with a screenshot.
  3. Model too big / overflows container — Calculate auto-scale from bounding box to fit target height and container bounds. Never assume scale=1.0 is correct.
  4. Animation not playing — Forgot mixer.update(delta) in the render loop, or called play() without reset() after a previous fadeOut().
  5. Camera fights with OrbitControls — Never call camera.lookAt() when using OrbitControls. It manages lookAt internally.
  6. "Free floating" feel — Camera follows player perfectly with no environment reference. Add a grid (THREE.GridHelper) and place props near spawn so movement is visible.
  7. Clip names differ per model — Always log clips.map(c => c.name) on load and define a clipMap per character. Never hardcode clip names.
  8. Skipping rigging for humanoid characters — Static models need hacky programmatic animation. Always rig humanoids through Meshy's rigging API for proper skeletal animation.

Process

Step 0: Check Meshy API Key

Before starting, check if MESHY_API_KEY is available. If not, ask the user for one (see "Meshy API Key" section above). If the user skips, proceed with Tier 2+ fallbacks.

Step 1: Audit
  • Read package.json to confirm Three.js
  • Read entity files for BoxGeometry, SphereGeometry, etc.
  • List every entity using geometric shapes
Step 2: Plan
EntityModel SourceTypeNotes
PlayerMeshy text-to-3d → rigAnimated characterCustom generated + rigged
EnemyMeshy text-to-3d → rigAnimated characterCustom generated + rigged
TreeMeshy text-to-3dStatic prop"a low poly stylized tree, game asset"
BarrelMeshy text-to-3dStatic prop"a wooden barrel, low poly game asset"

If Meshy unavailable, fall back to library characters + find-3d-asset.mjs for props.

Step 3: Generate / Download
bash
# With Meshy (preferred) — generate each entity
MESHY_API_KEY=<key> node 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 humanoid characters for animation
MESHY_API_KEY=<key> node 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 scripts/meshy-generate.mjs \
  --mode text-to-3d \
  --prompt "a wooden barrel, low poly game asset" \
  --polycount 5000 \
  --output public/assets/models/ --slug barrel

# Fallback: library characters
cp <plugin-root>/assets/3d-characters/models/Soldier.glb public/assets/models/

# Fallback: search free libraries for props
node scripts/find-3d-asset.mjs --query "barrel" --source polyhaven --output public/assets/models/
Step 4: Integrate
  1. Create src/level/AssetLoader.js with SkeletonUtils.clone() for animated models
  2. Add character definitions to Constants.js with clipMap per model
  3. Set up OrbitControls camera with target-follow pattern
  4. Implement fadeToAction() for animation crossfading
  5. Use camera-relative WASD movement with applyAxisAngle(_up, azimuth)
  6. Add Math.PI offset to model facing rotation
  7. Add THREE.GridHelper to ground for visible movement reference
Step 5: Verify
  • Run npm run dev and walk around with WASD
  • Confirm character animates (Idle when stopped, Walk when moving, Run with Shift)
  • Confirm character faces movement direction
  • Orbit camera with mouse drag, zoom with scroll
  • Run npm run build to confirm no errors

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.

Sketchfab download returns 403 Forbidden

Cause: The Sketchfab API requires authentication for model downloads, or the model license doesn't permit downloading. Fix: Ensure SKETCHFAB_TOKEN is set in environment. Check the model's license on Sketchfab — only CC-licensed models can be downloaded via API. Try alternative sources (Poly Haven, Poly.pizza) which don't require auth for free models.

meshopt decoder error on model load

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

Animation not playing after model loads

Cause: Animation clips not connected to the model's AnimationMixer, or clip names don't match expected values. Fix: Create an AnimationMixer for the model, then use mixer.clipAction(clip).play(). Log gltf.animations.map(a => a.name) to see available clip names — they vary by model source. Define a clipMap per character to map generic names (idle, walk, run) to actual clip names.

Camera fights with OrbitControls (jittering)

Cause: Manual camera position updates conflict with OrbitControls trying to maintain its own camera state. Fix: Don't set camera.position directly when using OrbitControls. Instead, update controls.target to follow the player, and let OrbitControls manage the camera position relative to the target. Call controls.update() once per frame in the animation loop.

Security Notes

  • Third-party model downloads: Models downloaded from Sketchfab, Poly Haven, and Poly.pizza are binary GLB/GLTF files (3D geometry, textures, animations). They are not executable code and cannot perform arbitrary actions. Three.js's GLTFLoader parses only valid glTF data structures.
  • Meshy AI API: Meshy generates models server-side from text/image prompts. The API key is stored in a local .env file and passed only to the Meshy API. Generated models are downloaded as GLB binaries.
  • API key storage: All API keys (MESHY_API_KEY, SKETCHFAB_TOKEN) are stored in the project's .env file (which should be gitignored) and loaded via environment variables. Keys are never embedded in game source code or deployed artifacts.
  • Content scope: Downloaded models are used only as visual assets rendered by Three.js. No text content from third-party sources is interpreted as instructions or commands.

Checklist

  • AssetLoader.js uses SkeletonUtils.clone() for animated models
  • clipMap defined per character model (clip names vary)
  • OrbitControls with target-follow (not manual camera.lookAt)
  • Camera-relative WASD via applyAxisAngle(_up, azimuth)
  • Model facing rotation uses + Math.PI offset in atan2
  • fadeToAction() pattern with reset() before fadeIn().play()
  • mixer.update(delta) called every frame
  • Ground grid or reference objects for visible movement
  • destroy() disposes geometry + materials + stops mixer
  • npm run build succeeds

© corosolto, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .agents/skills/game-3d-assets of corosolto/client.

Open the folder on GitHubat commit 23c16f5

Compare with similar skills

Game 3D Assets next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Game 3D Assets compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Game 3D Assets this skillcorosolto/client257—~5.4kAutomated safety check: NotesMIT
Threejs 3D Generatorvalkor-ai/loom1.2k1 repos~2.6kAutomated safety check: PassApache-2.0
Living BackdropTheOrcDev/skills106—~2.3kAutomated safety check: PassNone
Blender Web Export Pipelinefreshtechbro/claudedesignskills1k—~4.2kAutomated safety check: PassMIT
Pneuma Lucidpandazki/pneuma-skills161—~4.6kAutomated safety check: WarnMIT
Vtj Resource ManagementhexianWeb/Third-Person-MC195—~1.6kAutomated safety check: PassMIT

Similar skills

  • Threejs 3D Generator

    valkor-ai/loom

    Generate, texture, rig, animate, stylize, convert, and download 3D assets for Three.js games via the Tripo API.

    1.2k GitHub starsUsed in 1 repo~2.6k tokens
    Game DevelopmentAuto-check passed
  • Living Backdrop

    TheOrcDev/skills

    Turn one still image into a living web backdrop - depth parallax that follows the pointer, a subject that breathes, and ambient wind, cloud drift, light and dust, in a single WebGL shader with a…

    106 GitHub stars~2.3k tokensUpdated 12 days ago
    Game DevelopmentAuto-check passed
  • Blender Web Export Pipeline

    freshtechbro/claudedesignskills

    Exports and optimizes Blender 3D models and animations for the web as glTF, covering batch Python scripting, texture baking, decimation and LOD generation for Three.js and Babylon.js.

    1k GitHub stars~4.2k tokensUpdated 10 mo ago
    Game DevelopmentAuto-check passed
  • Pneuma Lucid

    pandazki/pneuma-skills

    Pneuma Lucid Mode workspace guidelines. An agent skill from pandazki/pneuma-skills.

    161 GitHub stars~4.6k tokensUpdated yesterday
    Game DevelopmentAuto-check: warnings
  • Vtj Resource Management

    hexianWeb/Third-Person-MC

    Loads and manages 3D assets via the Resources system. An agent skill from hexianWeb/Third-Person-MC.

    195 GitHub stars~1.6k tokensUpdated 2 mo ago
    Game DevelopmentAuto-check passed
  • Game Assets

    glifxyz/glif-mcp-server

    Make art and media for a game you are building with Glif: character reference sheets, consistent characters, pixel-art sprite sheets with animation cycles, seamless and PBR textures, 3D models, item…

    213 GitHub stars~831 tokensUpdated yesterday
    Game DevelopmentAuto-check passed

More from corosolto/client

All 21 skills in this repo
  • Threejs Gameplay Systems

    corosolto/client

    Build and iterate playable Three.js game systems. An agent skill from corosolto/client.

    257 GitHub stars~1.5k tokensUpdated today
    Auto-check passed
  • Threejs Gltf Loading

    corosolto/client

    Load glTF/GLB models in three.js with GLTFLoader and play their skinned animations with AnimationMixer, including DRACO/Meshopt-compressed meshes and KTX2 textures.

    257 GitHub starsUsed in 1 repo~1.8k tokens
    Auto-check passed
  • Threejs 3D Generator

    corosolto/client

    Generate, texture, rig, animate, stylize, convert, and download 3D assets for Three.js games using the Tripo API.

    257 GitHub stars~3.4k tokensUpdated today
    Auto-check passed
  • Light and shade a three.js scene: choose materials (MeshStandardMaterial PBR vs unlit MeshBasicMaterial), add ambient/hemisphere/directional/point/spot lights, turn on shadow maps, and use an…

    257 GitHub starsUsed in 1 repo~1.8k tokens
    Auto-check passed
  • Threejs Scene Setup

    corosolto/client

    Stand up a three.js scene: import maps and the three/addons path, the Scene/PerspectiveCamera/WebGLRenderer trio, the setAnimationLoop render loop, responsive resize, and OrbitControls.

    257 GitHub starsUsed in 1 repo~1.7k tokens
    Auto-check passed
  • Threejs Game Director

    corosolto/client

    Primary entrypoint for complete Three.js browser game creation and premium iteration.

    257 GitHub stars~2.8k tokensUpdated today
    Auto-check passed

Works with

Questions about Game 3D Assets

What does Game 3D Assets do?

3D asset engineer that finds, downloads, and integrates GLB/GLTF models into Three.js browser games. Game 3D Assets is an agent skill from corosolto/client.js browser games.

When should I use Game 3D Assets?

Game 3D Assets fits situations like: A 3D game needs real models instead of primitive BoxGeometry/SphereGeometry shapes; tasks that involve Game assets and audio; tasks that involve 3D graphics and WebGL.

How do I install Game 3D Assets in Claude Code?

Run `npx skills add corosolto/client --skill game-3d-assets -a claude-code`. Or copy the skill folder (.agents/skills/game-3d-assets in corosolto/client) into .claude/skills/game-3d-assets in your project. Claude Code loads it when a task matches its description.

How do I install Game 3D Assets in Codex?

Run `npx skills add corosolto/client --skill game-3d-assets -a codex`. Or copy the skill folder (.agents/skills/game-3d-assets in corosolto/client) into .agents/skills/game-3d-assets in your project. Codex loads it when a task matches its description.

Can I use Game 3D Assets in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add corosolto/client --skill game-3d-assets -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/game-3d-assets, .gemini/skills/game-3d-assets, .github/skills/game-3d-assets and .opencode/skills/game-3d-assets in your project.

What does Game 3D Assets need to run?

Going by SKILL.md and its folder, Game 3D Assets needs the command-line tools its instructions call (node, npm and curl) and credentials named MESHY_API_KEY, SKETCHFAB_TOKEN and POLY_PIZZA_API_KEY. Our summary lists: A credential in MESHY_API_KEY; A credential in SKETCHFAB_TOKEN.

Does Game 3D Assets access the network?

SKILL.md names 2 domains. In commands or code: raw.githubusercontent.com; the agent is likely to contact it when it follows the instructions. As links in the text: sketchfab.com. This is read from the text; nothing was executed.

Is Game 3D Assets safe to install?

Our automated static check of SKILL.md found notes only (mentions a .env file), nothing it rates as a warning. It is not a guarantee. Review the folder before installing.

What licence does Game 3D Assets use?

Game 3D Assets is published under the MIT licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Game 3D Assets use?

About 5.4k tokens (SKILL.md is roughly 22k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Game 3D Assets?

Skills that share tags, products or a category with Game 3D Assets: Threejs 3D Generator (valkor-ai/loom, 1.2k stars), Living Backdrop (TheOrcDev/skills, 106 stars), Blender Web Export Pipeline (freshtechbro/claudedesignskills, 1k stars) and Pneuma Lucid (pandazki/pneuma-skills, 161 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Game 3D Assets?

corosolto (a GitHub organization) maintains it in corosolto/client, which has 257 GitHub stars. The repository holds 21 skills in this directory. The repository was last updated on October 10, 2026.

Source: corosolto/client on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.