| name | threejs-game-asset-generator |
| description | Procedurally generate low-poly 3D game assets (props, dungeon modules, weapons, scenery) using Three.js + TypeScript, export as Godot-ready .glb with metadata. Use this skill whenever the user wants to create, modify, preview, or export 3D game assets programmatically — including barrels, crates, swords, shields, rocks, trees, chests, dungeon rooms, walls, floors, doors, pillars, or any stylized game prop. Also trigger when the user mentions "generate a 3D model", "procedural asset", "export GLB for Godot", "low-poly prop", "game asset generator", or wants to build a Three.js-to-Godot asset pipeline.
|
Three.js Game Asset Generator
Generate low-poly / stylized 3D game assets with Three.js, export as .glb for Godot.
What This Skill Does
- Procedurally generates 3D game props, scenery, and modular level pieces
- Exports Godot-compatible
.glb files with structured metadata.json
- Every output is seed-reproducible — same seed, same mesh
- Targets real-time game rendering: low triangle count, simple materials, no external textures
Suitable Asset Types
| Category | Examples |
|---|
| Props | barrel, crate, chest, table, chair, bookshelf, candle, pot |
| Weapons | sword, axe, shield, staff, bow, dagger |
| Nature | rock, tree, bush, stump, mushroom, crystal |
| Dungeon modules | room, corridor, wall, floor, door, pillar, staircase, arch |
| Decorations | torch, banner, sign, fence, well, gravestone |
NOT Suitable For
- Characters with skeletons/rigs — use Blender or a DCC tool
- Complex skeletal animation — this generates static meshes only
- Photorealistic assets — targets stylized/low-poly aesthetic
- Organic topology (faces, muscles) — procedural geometry is blocky by design
- Assets requiring UV-painted textures — uses solid color materials only
- Large open-world terrains — use a terrain engine instead
Tech Stack
| Layer | Tool |
|---|
| Language | TypeScript (strict mode) |
| 3D Engine | Three.js (r150+) |
| Export | three/addons GLTFExporter → binary .glb |
| Materials | MeshStandardMaterial, MeshBasicMaterial only |
| Runtime | Browser (primary) or Node.js with @gltf-transform/core fallback |
| Units | 1 Three.js unit = 1 meter (Godot-native) |
Asset Generation Workflow
Follow these steps for every asset request:
1. Parse the User's Request
Identify: asset type, style (fantasy, sci-fi, medieval), size constraints, color palette,
polygon budget, and any special features (e.g. "open lid", "broken blade").
2. Select or Create the Generator
Check examples/ for an existing generator. If none fits, create a new one using
templates/asset-generator.ts as the starting point.
3. Define the Params Interface
interface BarrelParams {
height?: number;
radius?: number;
staveCount?: number;
bandCount?: number;
woodColor?: string;
bandColor?: string;
}
Every param has a sensible default. The generator must work with zero args.
4. Generate with Seed
export function createAsset(params: Partial<BarrelParams>, seed: number): THREE.Group
Use the seeded RNG from templates/metadata.ts — never call Math.random() directly.
5. Preview
Build a minimal Three.js scene with orbit controls to inspect the asset in-browser.
Read references/threejs-modeling.md for the preview setup pattern.
6. Export GLB
Use scripts/export-glb.ts to export. Read references/glb-export.md for details.
7. Generate metadata.json
Use templates/metadata.ts to produce the sidecar file. See the Metadata section below.
8. Godot Import Notes
Read references/godot-import.md and include relevant notes for the user.
9. Quality Check
Run through the checklist in the Quality section below.
10. Iterate
If the user requests changes, adjust params or modify the generator function.
Re-export with the same seed to compare.
Three.js Modeling Rules
Read references/threejs-modeling.md for detailed patterns. Key rules:
- Name everything: every
Group, Mesh, and Material gets a descriptive .name
- Group hierarchy: root Group named after the asset, child groups for logical parts
- Pivot at bottom-center:
group.position.y offset so the lowest point sits at y=0
- Face orientation: all normals pointing outward; use
geometry.computeVertexNormals()
- Merge when possible: use
BufferGeometryUtils.mergeGeometries() for static parts
- No
DoubleSide: wastes GPU; model thickness instead if needed
Material Rules
- Use
MeshStandardMaterial for lit assets, MeshBasicMaterial for unlit/UI
- Set
material.name to a descriptive string (e.g. "wood_dark", "metal_band")
- Use flat colors via
color property — no texture maps
roughness: 0.7–0.9 for wood/stone, 0.3–0.5 for metal, 0.1–0.2 for gems
metalness: 0.0 for organic, 0.6–0.9 for metal
- Avoid custom shaders — Godot's importer won't understand them
Coordinate / Unit / Pivot Rules
| Rule | Value |
|---|
| Unit scale | 1 unit = 1 meter |
| Up axis | Y-up (Three.js default, Godot converts automatically) |
| Forward | -Z (Three.js convention) |
| Pivot | Bottom-center of bounding box |
| Origin | World origin (0, 0, 0) before export |
To set bottom-center pivot:
const box = new THREE.Box3().setFromObject(group);
group.position.y = -box.min.y;
Seed / Randomization Rules
Read references/procedural-generation.md for the full seeded RNG implementation.
- Never use
Math.random() — use the seeded mulberry32 RNG
- Same seed + same params = identical output, always
- Seed affects: slight dimension variations, color jitter, rotation offsets
- Document which aspects the seed controls in each generator
metadata.json Specification
Every exported asset must have a sidecar metadata.json:
{
"id": "barrel_fantasy_001",
"name": "Fantasy Barrel",
"type": "prop",
"seed": 42,
"style": "fantasy",
"dimensions": { "width": 0.6, "height": 0.9, "depth": 0.6 },
"pivot": "bottom-center",
"collision_hint": "cylinder",
"tags": ["barrel", "container", "wood", "tavern"],
"triangle_count": 256,
"material_count": 2,
"generated_at": "2024-01-15T10:30:00Z",
"generator_version": "1.0.0"
}
Use templates/metadata.ts to generate this. The collision_hint helps Godot users
create collision shapes: "box", "cylinder", "sphere", "convex", "trimesh".
GLB Export Rules
Read references/glb-export.md for the full export pipeline.
- Export as binary
.glb (not .gltf + separate files)
- File naming:
{type}_{style}_{seed_padded}.glb (e.g. barrel_fantasy_042.glb)
- Verify file size is reasonable (a simple prop should be 5–50 KB)
- Strip editor-only data before export (helpers, wireframes, lights)
Godot Import Notes
Read references/godot-import.md for full details.
- Godot auto-converts Y-up to its coordinate system
- Materials map to
StandardMaterial3D — named materials import cleanly
- Use
-col suffix on mesh names for auto-collision in Godot (e.g. barrel_body-col)
- Use
-navmesh suffix for navigation mesh hints
Quality Checklist
Before delivering any asset, verify:
Common Failures and Fixes
| Problem | Cause | Fix |
|---|
| Black faces in Godot | Inverted normals | geometry.computeVertexNormals() after transforms |
| Asset floating above ground | Pivot not at bottom | Apply bottom-center offset before export |
| Giant/tiny in Godot | Wrong scale | Verify dimensions in meters (a barrel is ~0.9m tall) |
| Missing colors | Material not assigned | Check every mesh has a material with .name |
| Different output each run | Using Math.random() | Replace with seeded RNG |
| GLB too large | Too many triangles | Reduce segment counts on cylinders/spheres |
| Invisible parts | Faces culled | Remove DoubleSide, add thickness instead |
| Broken hierarchy in Godot | Unnamed groups | Name every Group and Mesh node |
Prompt Template for New Generators
When the user describes a new asset, use this prompt pattern internally:
Create a low-poly stylized {asset_type} generator for Three.js.
It must export createAsset(params: Partial<{ParamType}>, seed: number): THREE.Group.
Rules: no external textures, named materials (MeshStandardMaterial),
polygon count under {budget}, pivot at bottom-center, Y-up coordinate system,
1 unit = 1 meter, suitable for GLB export to Godot.
Use the seeded mulberry32 RNG — never Math.random().
Output: the generator .ts file, ready for scripts/export-glb.ts.
Asset Pack Export
Use scripts/generate-pack.ts to batch-export multiple assets:
npx ts-node scripts/generate-pack.ts --type barrel --count 5 --seed-start 1
This produces:
output/
barrel_fantasy_001.glb
barrel_fantasy_001.metadata.json
barrel_fantasy_002.glb
barrel_fantasy_002.metadata.json
...
pack-manifest.json
File Reference
| File | Purpose | When to Read |
|---|
references/threejs-modeling.md | Geometry construction patterns, preview setup | Building any generator |
references/glb-export.md | GLTFExporter usage, Node.js vs browser | Exporting assets |
references/godot-import.md | Godot-specific import settings and gotchas | Preparing delivery |
references/asset-style-guide.md | Color palettes, proportions, style rules | Designing asset look |
references/procedural-generation.md | Seeded RNG, variation techniques | Adding randomization |
examples/*.ts | Complete working generators | Starting a new generator |
scripts/export-glb.ts | GLB export pipeline | Exporting any asset |
scripts/generate-asset.ts | Single asset CLI | Quick single export |
scripts/generate-pack.ts | Batch export CLI | Multiple assets |
scripts/inspect-glb.ts | GLB validation tool | Checking export quality |
templates/asset-generator.ts | Generator boilerplate | Creating new generators |
templates/metadata.ts | Metadata generation | Every export |