Skip to content

Workflow: Solo Indie Dev

Persona: Alex β€” building a 3D dungeon-crawler in Godot on an RTX 3060, solo, in spare time. Goal: generate a prop, texture, and music loop in a single lunch break.


The fast path β€” compose

The fastest way to get a complete, game-ready prop into Godot is a single compose command:

# Complete brazier prop: concept β†’ mesh β†’ UV β†’ texture β†’ LODs β†’ collider β†’ .glb
assgen compose prop "rusty iron brazier, medieval dungeon" \
    --engine godot --quality low --wait

That's it. When it finishes, you'll have a .glb ready to drag into res://assets/props/. The pipeline runs 7 sequential steps automatically.

For the level's audio:

# Ambient loop + dungeon music + 5 themed SFX
assgen compose soundscape "dark dungeon ambience, distant dripping water" \
    --duration 30 --wait

For ground and wall materials:

assgen compose material "cracked stone floor, dungeon" --engine godot --wait
assgen compose material "rough stone wall, dark, damp" --engine godot --wait

See the Compose Pipelines guide for all options.


Manual step-by-step (more control)

If you want to inspect or tweak each step individually β€” for example, to hand-pick the concept art before committing to a 3D pass β€” run the steps separately:


What you'll build

In about 30 minutes you'll go from a text prompt to:

  • A game-ready .glb prop (brazier, sword, chest β€” whatever you need)
  • A PBR texture set baked onto it
  • A 30-second looping dungeon music track

No cloud, no monthly fees, no leaving your terminal.


Prerequisites

# Install assgen with GPU inference support
pip install "assgen[inference]"

# Verify your server starts and your GPU is visible
assgen server status
# ⚑ No server detected β€” starting local assgen-server on http://127.0.0.1:8432
# βœ“ Server ready
# device  cuda (NVIDIA GeForce RTX 3060)

First run downloads the model

The first --wait command for each task type downloads the HuggingFace model (~1–4 GB). Subsequent runs use the local cache and are much faster.


Step 1 β€” Concept sketch (10 seconds)

Generate a reference image to guide the 3D step:

assgen gen visual concept generate \
  --prompt "rusty iron brazier, medieval, top-down view, white background" \
  --wait

Output: concept_<id>.png in your current directory. Open it, check the silhouette looks right, then move on.


Step 2 β€” Image-to-3D mesh (~3 minutes)

Pipe the concept image directly into TripoSR:

assgen gen visual model create \
  --input concept_<id>.png \
  --wait

Image input beats text-only for props

--input almost always produces a better mesh than --prompt alone. Text-to-3D works best for simple primitive-like shapes (cube, sphere, barrel).

Output: model_<id>.glb β€” a single mesh with auto-UV, ready for texturing.


Step 3 β€” PBR texture set (~4 minutes)

assgen gen visual texture generate \
  --input model_<id>.glb \
  --prompt "rusty iron, dark soot, medieval forge, PBR diffuse" \
  --wait

Output: texture_<id>.glb β€” the mesh with albedo, normal, and roughness maps baked in.

Tiling artefacts on organic shapes

If you see seams, run the inpaint command on the problem area:

assgen gen visual texture inpaint \
  --input texture_<id>.glb \
  --mask seam_mask.png \
  --wait


Step 4 β€” Looping dungeon music (~2 minutes)

assgen gen audio music loop \
  --prompt "dark dungeon ambience, low strings, eerie, minor key, loopable" \
  --duration 30 \
  --wait

Output: music_<id>.wav β€” a 30-second clip designed to loop at the endpoint.

Getting seamless loops

Include the word loopable or seamless loop in your prompt. MusicGen is trained on loop-aware conditioning. Preview in Audacity: zoom into the end→start join to check for a click.


Step 5 β€” Import into Godot

assgen outputs .glb by default β€” Godot's native format for 3D scenes.

  1. Drag texture_<id>.glb into res://assets/props/
  2. Godot auto-imports it as a GLTFDocument β€” no conversion needed
  3. The embedded PBR materials map directly to Godot's StandardMaterial3D
# Instantiate at runtime
var brazier = load("res://assets/props/texture_<id>.glb").instantiate()
add_child(brazier)

For audio:

  1. Drag music_<id>.wav into res://assets/audio/
  2. In the Import dock: set Loop Mode β†’ Forward, click Reimport
  3. Attach an AudioStreamPlayer with stream = preload("res://assets/audio/music_<id>.wav")

Full session in one script

#!/bin/bash
set -e
PROMPT="rusty iron brazier, medieval"

CONCEPT=$(assgen gen visual concept generate --prompt "$PROMPT, top-down, white bg" --wait --json | jq -r '.output_path')
MESH=$(assgen gen visual model create --input "$CONCEPT" --wait --json | jq -r '.output_path')
TEXTURED=$(assgen gen visual texture generate --input "$MESH" --prompt "$PROMPT, PBR diffuse" --wait --json | jq -r '.output_path')
MUSIC=$(assgen gen audio music loop --prompt "dark dungeon ambience, eerie, loopable" --duration 30 --wait --json | jq -r '.output_path')

echo "βœ“ Prop:  $TEXTURED"
echo "βœ“ Music: $MUSIC"

--json flag

--json is on the roadmap and will emit structured output for scripting. Until then, check assgen jobs list for output paths.


Tips for your GPU

Model VRAM needed Approx. time (RTX 3060)
TripoSR (3D mesh) ~6 GB 2–3 min
SDXL (concept/texture) ~8 GB 1–2 min
MusicGen medium (music) ~4 GB 1–2 min

If you hit OOM errors, reduce texture resolution:

assgen gen visual texture generate --input mesh.glb --resolution 1024 --wait

Next steps