From game-creator
Replaces primitive 3D shapes like BoxGeometry and SphereGeometry with GLB models—animated characters via Meshy AI, props, buildings—for Three.js games.
npx claudepluginhub opusgamelabs/game-creator --plugin game-creatorThis skill uses the workspace's default tool permissions.
- Take your time to do this thoroughly
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Checks Next.js compilation errors using a running Turbopack dev server after code edits. Fixes actionable issues before reporting complete. Replaces `next build`.
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.
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.
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:
- Sign up at https://app.meshy.ai
- Go to Settings → API Keys
- 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.
package.json to confirm this is a Three.js game (not Phaser — use /add-assets for 2D games)src/core/Constants.js for entity types, sizes, colorssrc/gameplay/*.js, src/entities/*.js) — find BoxGeometry, SphereGeometry, etc.src/level/LevelBuilder.js for environment primitivesSplit 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/:
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 |
With Meshy (preferred):
# 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):
# 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
src/level/AssetLoader.js — use SkeletonUtils.clone() for animated models (import from three/addons/utils/SkeletonUtils.js). Regular .clone() breaks skeleton → T-pose.CHARACTER to Constants.js with path, scale, facingOffset, clipMapASSET_PATHS and MODEL_CONFIG for static modelsPlayer.js:
THREE.Group as position anchorloadAnimatedModel() + AnimationMixerfadeToAction() for idle/walk/run crossfadeapplyAxisAngle(_up, cameraAzimuth)atan2(v.x, v.z) + CHARACTER.facingOffsetmodel.quaternion.rotateTowards(targetQuat, turnSpeed * delta)Game.js:
OrbitControls — third-person camera orbiting playerorbitControls.target + camera.position by player deltaorbitControls.getAzimuthalAngle() to Player for camera-relative movementloadModel() calls + .catch() fallbackTHREE.GridHelper for visible movement referencepreloadAll() for instant loadingnpm run dev — walk around with WASD, orbit camera with mouseMODEL_CONFIG values (scale, rotationY, offsetY) per modelnpm run build to confirm no errorsATTRIBUTION.md from .meta.json files/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.
/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.
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.
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.
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.
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);
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.
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 SkeletonUtilspublic/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_CONFIGin Constants.js to fine-tune scale and orientation.