Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Generate visual assets from text prompts: PNG images (Gemini / xAI Grok), GLB 3D models (Tripo3D), rigged biped characters, retargeted animations, and frame-by-frame animated sprites, plus background removal. Use whenever a game needs generated art.
.claude/skills/htdt-asset-gen/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-05 | ✗→✓ | ▲ Improved | 112% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 83% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 35% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 238% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 153% | 0% |
Generate PNG images (Gemini or xAI Grok) and GLB 3D models (Tripo) from text prompts. These are paid APIs — every call costs real money. The free exception is qwen-image, a local GPU generator some machines have. Image tools live at ${ASSET_GEN_SKILL_DIR}/tools/; 3D goes through the tripo CLI. Run from the project root and keep runtime-loaded outputs under ${RUNTIME_ASSET_DIR}/.
| Model | Flag | Cost | Notes | |-------|------|------|-------| | Gemini 3.1 Flash Image | --model gemini | 5¢ (512) · 7¢ (1K) · 10¢ (2K) · 15¢ (4K) | ~10 s per image | | Grok Imagine Image 2.0 | --model grok | 6¢ (1K) · 8¢ (2K), +1¢ per reference image | 1–2 min per image | | Qwen-Image | qwen-image CLI (local, if installed) | free, minutes per image | Simple images — textures, props, icons, UI, backgrounds, in-image text; native transparency |
Gemini and Grok are equally strong: both follow detailed prompts closely, and both slip on small details — a miscounted item, a mirrored left/right. Use whichever key is set; with both, asset_gen.py defaults to Gemini for speed. When an asset is quality-critical (a character reference that anchors 3D or animation, a hero image) and both keys are set, generate it with both and keep the better one.
bashpython3 ${ASSET_GEN_SKILL_DIR}/tools/asset_gen.py image \ --prompt "the full prompt" -o ${RUNTIME_ASSET_DIR}/img/car.png
--model (default gemini when its key is set, else grok) · --size (default 1K; Gemini also 512/4K) · --aspect-ratio (default 1:1; also 16:9, 9:16, 4:3, 3:4, 3:2, 2:3).
Image-to-image: pass --image ref.png and the model sees the reference — prompt only for what changes (angle, pose, recolor), don't re-describe appearance. Use this for style families (one hero asset → the rest), variants, and multi-view sets.
Small sprites: minimum generation is 1K, so a 1024px image downscaled to 64px looks muddy. Design display sizes ≥128px, or generate a kit (multiple objects in one 1K image) and slice it with tools/grid_slice.py ... --grid 2x2 --names "a,b,c,d", or prompt for bold flat forms that survive downscaling.
Review every PNG before any GLB conversion — a bad image wastes 30+ credits downstream.
Read ${ASSET_GEN_SKILL_DIR}/rembg.md. Key rule: never prompt for a "transparent background" (the generator bakes a checkerboard) — prompt a solid color, then matte it out. The one exception is qwen-image rgba, which outputs real alpha.
qwen-image)If command -v qwen-image finds it, this machine runs Qwen-Image-2.1 on its own GPU. It costs nothing, so simple images go there first; keep the paid models for characters, references, and exact layouts.
bashqwen-image generate "the full prompt" -o ${RUNTIME_ASSET_DIR}/img/crate.png # --size WxH or --resolution N (default 1024) qwen-image rgba "a wooden shield, game icon" -o ${RUNTIME_ASSET_DIR}/img/shield.png # transparent PNG, no matting qwen-image edit -i crate.png "mossy and cracked" -o ${RUNTIME_ASSET_DIR}/img/crate_old.png # image-to-image; repeat -i for more refs
seconds in --json) and plan batches from it; --resolution 512 --steps 10 is ~8× faster for checking how a prompt reads.rgba alpha from a composite on a contrasting color (magick out.png -background magenta -flatten out_qa.png), not the raw PNG.--resolution (edits use the most). On failure, qwen-image info reports GPU and model status.Recipe: reference → pose → video → extract frames → loop-trim → rembg.
asset_gen.py video --image pose.png --duration 2 -o walk.mp4 (Grok, needs XAI_API_KEY; --duration 1–15s; --resolution 720p at 14¢/s, or 480p at 8¢/s — enough for small sprites).ffmpeg -i walk.mp4 -vsync 0 frames/%04d.png.tools/find_loop_frame.py frames/ returns the loop frame; delete frames past it. Skip for one-shots (attack/death).tools/rembg_matting.py --batch frames/ -o clean/.Reuse one reference for all of a character's actions. Chaining (feed action A's last frame as action B's start) keeps positional continuity — keep chains ≤2 deep, they drift.
The tripo CLI (npm install -g tripo-cli, key in TRIPO_API_KEY) owns the whole 3D path: submit, poll, download, credit pre-check, refunds on failure. Its own agent docs are the reference — tripo docs --llm, then tripo docs --topic commands/process / examples/animation / common-errors — this section only covers what is specific to game use here.
bashtripo make ref.png --name car -p face_limit=30000 -p auto_size=true --json --yes -o ${RUNTIME_ASSET_DIR}/glb tripo make ref.png --name hero --then rig-check,rig:model=v1.0-20240301 --json --yes -o ${RUNTIME_ASSET_DIR}/glb tripo anim retarget @hero --animation preset:biped:walk preset:biped:idle --json --yes -o ${RUNTIME_ASSET_DIR}/glb
make is blocking (default timeout 30 min) and prints one JSON line: read model_file, preview.png and credits_consumed from it. Never add your own shorter timeout, never resubmit because a task_id appeared in stderr. If the process does die, tripo task watch <id> --download finishes the same task for free.<-o dir>/<name>-<id8>/ (model.glb, preview.png, task.json). Move or reference the GLB from there; task.json keeps the seeds and task id, so there is nothing else to save.--name X makes the task addressable as @X for later steps (retarget, convert, decimate). Retarget reuses the rig task — never re-rig for another clip; up to 5 animations per call, billed per animation.face_limit ≤ 20000 the CLI silently switches to P1 (low-poly topology, no geometry_quality) — that is the right choice for mobile-style budgets, but know it happens. --for game-pc converts to FBX by default; skip it for GLB engines.-p geometry_quality=detailed -p texture_quality=detailed is the HD tier (≈ double credits).rig:model=v1.0-20240301 for bipeds — that is the rig motion.md's pipeline is certified against, and it uses the preset:biped:* clips below. The CLI's default rig (v2.5) covers quadrupeds, avians, etc. with preset:<name> clips (idle walk run dive climb jump slash shoot hurt fall turn); unverified with motion.md. rig-check in the chain aborts before rigging if the mesh isn't riggable. --animate-in-place when game code drives locomotion.Source image for make: 3/4 elevated angle, solid white/gray background, matte finish, opaque glass, single centered subject — and do not rembg it (Tripo needs the solid bg). For characters, generate the reference in a T-pose.
v1.0 biped retarget presets (pass as preset:biped:<name>):
afraid agree angry_01/02/03 basketball_shot bow box_01/02/03 cast_a_spell cheer chop
clap climb complain_01/02 cross_body_crunch crossover_dribble cry dance_01..06
defeat_02/03 depressed dig dive dribble fall fire flee_01/02 flip fold_arms
football_catch/save/pass freaky frightened front_kick_01/02 frustrated_01/02 golf
greet_01..04 heart_pose hit_to_body_01/02 hit_to_head/side/stomach hug hurt idle
jump jump_down jump_rope_01/02 laugh_01/02 lift_heavy look_around make_a_call_01/02
pitch_baseball play_mobile_game play_video_game press-up run run_upstairs scared_01/02
scratch shoot shovel sing_01..04 sit slash sob standing_relax surf swagger swim turn
victory_celebration volleyball wait walk warm_up wave_goodbye_01/02Presets are generic stock clips. Important: when gameplay needs a custom humanoid move set (state machines, root-motion locomotion, moves not in this list), read ${ASSET_GEN_SKILL_DIR}/motion.md.
Paid generations cost real money, so confirm with the user before generating; qwen-image runs are free. Quick reference: 1K image 6–7¢ · 2K background 8–10¢ · a quality-critical image generated on both models ~13¢ · sprite video 14¢/s at 720p. Tripo bills in credits (≈1¢): ~30 per model, ~25 to rig, ~10 per retargeted clip — tripo balance before a batch, and report the credits_consumed the CLI returns rather than an estimate.
Each asset_gen.py command prints JSON to stdout: {"ok": true, "path": "...", "cost_cents": 7}; tripo and qwen-image print theirs with --json. Progress goes to stderr — redirect it to a temp file and read only on failure to keep context clean:
bash_log=$(mktemp) result=$(python3 ${ASSET_GEN_SKILL_DIR}/tools/asset_gen.py image --prompt "..." -o p.png 2>"$_log") || tail -20 "$_log"
Generate independent API images in parallel (multiple Bash calls in one message).
Generators and vision checks have weak spatial sense — verify from screenshots when it matters.
magick in.png -resize 960x960 out.png).Track every generated asset in README.md with an in-game Size column — without it, coders consistently scale assets wrong:
4m long, 1.8m tall, 0.3m2m tile1920x1080, fullscreen128x128 px| Name | Description | Size | Path | Cost | |------|-------------|------|------|------| | car | sedan with spoiler | 4m long | ${RUNTIME_ASSET_DIR}/glb/car.glb | 7¢ + 30 cr |
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 44,242 | 14,158 | -68% | 1 | 1 | 0% | 8,265 | 4,004 | -52% | 0 | 0 | — |
case-02 | fail→fail | 40,145 | 19,486 | -51% | 1 | 1 | 0% | 8,248 | 3,770 | -54% | 0 | 0 | — |
case-03 | fail→fail | 45,510 | 10,569 | -77% | 1 | 1 | 0% | 8,250 | 3,774 | -54% | 0 | 0 | — |
case-04 | fail→fail | 19,041 | 17,135 | -10% | 1 | 1 | 0% | 2,669 | 4,443 | +66% | 0 | 0 | — |
case-05 | fail→pass | 17,005 | 23,104 | +36% | 1 | 1 | 0% | 2,715 | 5,769 | +112% | 0 | 0 | — |
case-06 | pass→pass | 18,166 | 11,575 | -36% | 1 | 1 | 0% | 2,895 | 5,116 | +77% | 0 | 0 | — |
case-07 | fail→pass | 16,037 | 5,752 | -64% | 1 | 1 | 0% | 2,197 | 4,019 | +83% | 0 | 0 | — |
case-08 | fail→pass | 28,697 | 13,739 | -52% | 1 | 1 | 0% | 3,979 | 5,382 | +35% | 0 | 0 | — |
case-09 | pass→pass | 11,763 | 7,448 | -37% | 1 | 1 | 0% | 1,425 | 4,311 | +203% | 0 | 0 | — |
case-10 | fail→pass | 8,886 | 10,583 | +19% | 1 | 1 | 0% | 1,189 | 4,017 | +238% | 0 | 0 | — |
case-11 | fail→pass | 13,764 | 5,287 | -62% | 1 | 1 | 0% | 1,562 | 3,956 | +153% | 0 | 0 | — |
case-12 | pass→pass | 7,595 | 4,882 | -36% | 1 | 1 | 0% | 710 | 3,759 | +429% | 0 | 0 | — |
case-13 | fail→pass | 12,624 | 3,770 | -70% | 1 | 1 | 0% | 2,039 | 3,731 | +83% | 0 | 0 | — |
case-14 | fail→pass | 16,612 | 33,928 | +104% | 1 | 1 | 0% | 2,317 | 3,582 | +55% | 0 | 0 | — |
case-15 | fail→pass | 17,328 | 4,490 | -74% | 1 | 1 | 0% | 2,386 | 3,765 | +58% | 0 | 0 | — |
case-16 | fail→pass | 14,959 | 6,951 | -54% | 1 | 1 | 0% | 1,987 | 4,019 | +102% | 0 | 0 | — |
case-17 | fail→pass | 10,013 | 4,221 | -58% | 1 | 1 | 0% | 1,244 | 3,830 | +208% | 0 | 0 | — |
case-18 | pass→pass | 17,508 | 32,174 | +84% | 1 | 1 | 0% | 2,585 | 5,408 | +109% | 0 | 0 | — |
case-19 | fail→pass | 13,090 | 5,136 | -61% | 1 | 1 | 0% | 2,064 | 3,939 | +91% | 0 | 0 | — |
case-20 | fail→pass | 13,066 | 2,863 | -78% | 1 | 1 | 0% | 1,490 | 3,426 | +130% | 0 | 0 | — |
case-21 | fail→pass | 33,380 | 4,949 | -85% | 1 | 1 | 0% | 2,231 | 3,987 | +79% | 0 | 0 | — |
case-22 | fail→pass | 19,589 | 14,690 | -25% | 1 | 1 | 0% | 3,236 | 4,647 | +44% | 0 | 0 | — |
case-23 | pass→pass | 35,543 | 41,428 | +17% | 1 | 1 | 0% | 6,310 | 11,452 | +81% | 0 | 0 | — |
case-24 | fail→fail | 44,344 | 43,733 | -1% | 1 | 1 | 0% | 8,226 | 11,447 | +39% | 0 | 0 | — |
case-25 | pass→pass | 25,296 | 29,936 | +18% | 1 | 1 | 0% | 4,920 | 10,111 | +106% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 25 cases were attempted, and 22 counted toward the lift figure. The other 3 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +56 percentage points is the difference between those two pass rates over the 22 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
| Model | Method | Date | Lift |
|---|---|---|---|
| gemini-3.6-flash | verified | 8/9/2026 | +54% |
Other measured skills in the registry, with their headline benchmark lift.