S = the skills folder. Every .py runs headless via python S/blender-core/scripts/run_in_blender.py --blend F.blend S/<skill>/scripts/<x>.py -- ..., or live via MCP import + run() (see blender-core). Gate = stop and fix before continuing. Save after every stage (--save).
1. Game prop, mid-poly (fast, no bake)
- Blockout at real scale (
blender-hardsurface-modeling). Gate:ob.dimensionsvs reference. - UV the blockout before beveling (the Bevel/Boolean modifiers carry UVs):
uv_pack.py --objects SM_X --method seams --seams-from-sharp 60→texel_density.py --res 2048 --set 512 apply_stack.py --objects SM_X --preset midpoly [--cutters ...](keep it live;--apply --triangulateonly on the export copy)- Materials:
build_pbr_material.py --preset ...or tiling/trim textures. - Gate:
qa_check.py --objects SM_X --profile gamepasses, pluslook(angles, material + wireframe). mesh_stats.py --budget <platform>→make_lods.py --objects SM_X --renameexport_asset.py --preset <engine> --objects SM_X_LOD0 SM_X_LOD1 ...Gate: re-import dims / GLB summary.
2. Game prop, high → low baked (hero quality)
- High poly: hardsurface
--preset subdor sculpt (sculpt_ops.py), namedX_high. - Low:
auto_retopo.py --objects X_high --tris N --method planar|decimate|quadriflow, or manual. Rename itSM_X. uv_pack.py --objects SM_X --method seams --seams-from-sharp 60 --margin-px 16- Gate:
qa_check.pyonSM_X(game) andX_high(render profile, no inverted parts). bake_maps.py --low SM_X --high X_high --maps normal ao curvature id --pack-orm [--directx for Unreal]build_pbr_material.py --name M_X --textures //textures --objects SM_X(+ basecolor/roughness from texturing).- Gate:
lookin material shading (no seams/waviness), then steps 6–7 of recipe 1.
3. Game character (sculpt or AI mesh → animated export)
- Source mesh (sculpt /
generate_3d/ scan) at real height, facing -Y, feet on Z=0. Runqa_check.py --profile render. auto_retopo.py --method quadriflow --tris 20000(or manual retopo for heroes, keeping the edge flow rules).uv_pack.py --method min_stretch.bake_maps.py --low Body --high Body_src --maps normal ao basecolor(basecolor via emission override if the source has colors/materials).rigify_build.py --add basic_human --fit Body→ place joints (look xray) →--metarig META_Body --generatebind_mesh.py --armature RIG_Body --meshes Body→stress_poses.py --armature RIG_Body→look(mode="frames"). Gate: no collapse at the elbows/knees/shoulders. Fix weights.rigify_build.py --rig RIG_Body --game-skeleton→rig_check.py --armature GAME_RIG_Body --profile unity|unreal- Animate on RIG_Body (
blender-animation) →bake_action.py --source RIG_Body --target GAME_RIG_Body [--root-motion xy --hips spine] export_asset.py --preset unity_skeletal|unreal_skeletal --objects GAME_RIG_Body(meshes are included as children). Gate: GLB/FBX summary shows skins + all clips. Engine scale check.
4. Roblox
- MeshPart prop: recipe 1 with
--profile robloxin QA (≤20k tris, watertight, no n-gons, single UV 0–1), separate grayscale maps (no ORM),export_asset.py --preset roblox(FBX) orroblox_gltf. Textures 1024² (PBR). - Rigid accessory: ≤4k tris, an attachment point empty matching an R15
_Attname,--preset roblox. - Layered clothing: start from Roblox's official cage templates. Build
<Name>_InnerCage/_OuterCage(never change cage vertex count/order/UVs), skin to R15 bones, ≤4 influences, no weights on Root. Validate in Studio's Accessory Fitting Tool. - Avatar body: 15
_Geoparts, R15 skeleton, attachments, outer cages, 10,742 tri budget. Readblender-export-pipelines/references/roblox.mdfirst. - Upload: Studio
AssetService:CreateAssetAsyncfor batches.
5. Cleaning AI-generated / downloaded assets
- Import (
import_asset/generate_3d/ file). Scale to real size (world_bounding_box), origin to the bottom, ground at z=0,transform_apply. scene_audit.py --fix purge scale→qa_check.py --profile game. Typical findings: non-manifold, duplicate verts, inverted islands, floating debris, z-fighting shells.- Fix:
make_lods.py --cleanup(merge/degenerate/loose), recalc normals, delete floating debris (orremeshviasculpt_ops.pyfor garbage topology), thenauto_retopo.py --method decimateto budget. - Re-UV if the UVs are fragmented (
uv_pack.py) and re-bake from the original (bake_maps.py --high original). - Gate: QA passes +
look. Never ship generated meshes unreviewed.
6. Procedural environment
- Terrain/ground mesh, then a scatter tree with
gn_builder.py --spec scatter.json --apply Ground --set Density=... Seed=...(recipes inblender-geometry-nodes/references/recipes.md). - Assets to scatter: optimized props with LODs (recipe 1). Keep instances (don't realize) for engines that support instancing (
export_gpu_instances). - Gate:
mesh_stats.pyon the evaluated result, pluslookfrom the gameplay camera height.
7. Web / AR asset
Recipe 1 or 2 with budgets --budget web (≤30k tris, 1–2 materials, 2k textures) → export_asset.py --preset web (meshopt + WebP) → optional gltf-transform optimize --texture-compress ktx2. USDZ for iOS AR: --preset usd --out x.usdz. Gate: GLB summary (size < 5 MB) and Khronos PBR Neutral look-dev match.
8. Product shot / turntable
- Materials with measured values (
build_pbr_material.py --preset), and QA for z-fighting/floating parts (very visible in close-ups). - Set the render resolution, then
turntable.py --objects Product --rig studio --backdrop --frames 120 --lens 85 render_batch.py --preset preview --frames 1→ review →--preset product --frames 1-120 --format PNG→ encode, or--format MP4.- Gate: no fireflies or clipped highlights (AgX / Khronos PBR Neutral), and the product sits on the backdrop (contact shadow).