aallbrig/AssetGen

0

stars

61

commits

Python

primary language

Jun 23, 2026

updated

aallbrig.github.io/AssetGen/

README

assgen

AI-driven game asset generation pipeline β€” Kubernetes-style client/server architecture for 3D game development.

CI Docs

πŸ“– Full Documentation β†’ aallbrig.github.io/assgen

Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  assgen  (client CLI)                                      β”‚
β”‚  β”œβ”€β”€ visual model create --prompt "sword" --wait           β”‚
β”‚  β”œβ”€β”€ audio sfx generate "laser blast" --wait              β”‚
β”‚  └── jobs list / status / wait / cancel                   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    β”‚ HTTP (REST)
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  assgen-server                                             β”‚
β”‚  β”œβ”€β”€ FastAPI REST API  (/jobs  /models  /health)          β”‚
β”‚  β”œβ”€β”€ WorkerThread      (polls SQLite queue)               β”‚
β”‚  β”œβ”€β”€ ModelManager      (HuggingFace Hub download/cache)   β”‚
β”‚  └── Validation        (allow-list + HF tag check)        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    β”‚
         ~/.config/assgen/assgen.db   (SQLite)
         ~/.local/share/assgen/models/  (model cache)

The client auto-detects whether a server is configured:

  • If server_url is set in ~/.config/assgen/client.yaml β†’ use that server.
  • Otherwise β†’ start a local assgen-server process (PID-tracked) and use it.

This lets you run the server on a powerful GPU machine and point your laptop's client at it, or just run everything locally.

Installation

pip install assgen

# For GPU inference (RTX 4070 recommended):
pip install "assgen[inference]"

[inference] extra: Installs torch, transformers, diffusers, accelerate, and trimesh for local GPU inference. Without it, assgen is a fully functional client that can talk to a remote assgen-server, but a local server will return stub outputs instead of running real models.

For CI environments or machines without a GPU, pip install assgen (without [inference]) is the right choice.

Development Setup

Clone and run from source:

git clone https://github.com/aallbrig/assgen.git
cd assgen

# Create and activate a virtual environment
python -m venv .venv
source .venv/bin/activate        # Linux / macOS
# .venv\Scripts\activate         # Windows PowerShell

# Install in editable mode with dev dependencies
pip install -e ".[dev]"

# For GPU inference (optional β€” needs CUDA-capable GPU):
pip install -e ".[dev,inference]"

# Verify the install
assgen version
assgen-server --help

Run tests: pytest -v (or make test)

Version note: assgen uses hatch-vcs to derive its version from git tags. If you install without a git tag (fresh clone, no tags), the version will appear as 0.1.dev0. Run git tag v0.1.0 to set a version, or ignore the warning β€” it does not affect functionality.

Quick Start

# Check version
assgen version

# Start local server (optional β€” client auto-starts if not configured)
assgen-server start --daemon

# Once the server is running, explore the REST API interactively:
# http://127.0.0.1:8432/docs      (Swagger UI)
# http://127.0.0.1:8432/redoc     (ReDoc)
# http://127.0.0.1:8432/health    (health check)

# Generate a 3D model
assgen visual model create --prompt "low-poly medieval sword" --wait

# Generate sound effects
assgen audio sfx generate "laser gun firing" --wait

# Generate background music
assgen audio music compose "epic orchestral battle theme" --duration 30 --wait

# Auto-rig a character
assgen visual rig auto character.glb --wait

# List recent jobs
assgen jobs list

# Point client at a remote GPU server
assgen client config set-server http://my-gpu-machine:8432

# View full game dev task β†’ model catalog
assgen tasks

# Show current server config
assgen server config show

assgen-server vs assgen server:

  • assgen-server start β€” runs the inference server directly (the process itself)
  • assgen server start β€” tells the client to launch a local assgen-server process for you
  • assgen server status / assgen server stop β€” manage the locally auto-started server

For a remote GPU machine, run assgen-server start --daemon there, then on your laptop: assgen client config set-server http://<gpu-machine>:8432

CLI Command Tree

assgen
β”œβ”€β”€ tasks                     # View all game dev tasks and their assigned models
β”‚   └── [--domain DOMAIN]     # filter by visual / audio / scene / pipeline / qa / support
β”œβ”€β”€ visual                    # All 3D visual assets
β”‚   β”œβ”€β”€ concept               # AI concept art (SDXL)
β”‚   β”‚   β”œβ”€β”€ generate          # text β†’ concept art
β”‚   β”‚   β”œβ”€β”€ ref               # multi-view reference sheet
β”‚   β”‚   └── style             # art style samples
β”‚   β”œβ”€β”€ blockout              # Greybox prototyping
β”‚   β”‚   β”œβ”€β”€ create            # text/image β†’ blockout mesh
β”‚   β”‚   β”œβ”€β”€ assemble          # combine pieces into scene
β”‚   β”‚   └── iterate           # quick variation
β”‚   β”œβ”€β”€ model                 # 3D mesh generation
β”‚   β”‚   β”œβ”€β”€ create            # text/image β†’ .glb (TripoSR)
β”‚   β”‚   β”œβ”€β”€ highpoly          # high-poly refinement
β”‚   β”‚   β”œβ”€β”€ retopo            # auto-retopology
β”‚   β”‚   β”œβ”€β”€ splat             # Gaussian Splatting (3DGS)
β”‚   β”‚   β”œβ”€β”€ edit              # deform / boolean / combine
β”‚   β”‚   β”œβ”€β”€ optimize          # LOD generation
β”‚   β”‚   └── export            # convert to engine format
β”‚   β”œβ”€β”€ uv                    # UV unwrapping
β”‚   β”‚   β”œβ”€β”€ auto              # AI smart-unwrap
β”‚   β”‚   β”œβ”€β”€ manual            # seam suggestions
β”‚   β”‚   └── optimize          # texel density optimisation
β”‚   β”œβ”€β”€ texture               # PBR texturing & baking
β”‚   β”‚   β”œβ”€β”€ generate          # text β†’ albedo + PBR maps
β”‚   β”‚   β”œβ”€β”€ apply             # project onto mesh
β”‚   β”‚   β”œβ”€β”€ bake              # high-to-low bake
β”‚   β”‚   └── pbr               # full PBR material set
β”‚   β”œβ”€β”€ rig                   # Character rigging
β”‚   β”‚   β”œβ”€β”€ auto              # auto-skeleton (UniRig)
β”‚   β”‚   β”œβ”€β”€ skin              # skin weight maps
β”‚   β”‚   └── retarget          # rig retargeting
β”‚   β”œβ”€β”€ animate               # Animation generation
β”‚   β”‚   β”œβ”€β”€ keyframe          # text β†’ animation (AnimateDiff)
β”‚   β”‚   β”œβ”€β”€ mocap             # video β†’ motion capture
β”‚   β”‚   β”œβ”€β”€ blend             # mix/loop animations
β”‚   β”‚   └── retarget          # animation retargeting
β”‚   β”œβ”€β”€ vfx                   # VFX & particles
β”‚   β”‚   β”œβ”€β”€ particle          # particle sprite sheets
β”‚   β”‚   β”œβ”€β”€ decal             # dynamic decal textures
β”‚   β”‚   └── sim               # physics VFX bake
β”‚   └── ui                    # UI/HUD elements
β”‚       β”œβ”€β”€ icon              # icons & sprites
β”‚       β”œβ”€β”€ hud               # health bars, minimaps
β”‚       └── overlay           # 2D canvas overlays
β”œβ”€β”€ audio                     # Sound & music
β”‚   β”œβ”€β”€ sfx                   # Sound effects (AudioLDM2)
β”‚   β”‚   β”œβ”€β”€ generate          # text β†’ WAV
β”‚   β”‚   β”œβ”€β”€ edit              # pitch/reverb/layer
β”‚   β”‚   └── library           # browse local SFX library
β”‚   β”œβ”€β”€ music                 # Music (MusicGen)
β”‚   β”‚   β”œβ”€β”€ compose           # text β†’ music track
β”‚   β”‚   β”œβ”€β”€ loop              # seamless loop generation
β”‚   β”‚   └── adaptive          # mood-based stems
β”‚   └── voice                 # Voice synthesis (Bark)
β”‚       β”œβ”€β”€ tts               # text β†’ speech
β”‚       β”œβ”€β”€ clone             # voice cloning
β”‚       └── dialog            # batch NPC dialog
β”œβ”€β”€ scene                     # Physics + lighting data
β”‚   β”œβ”€β”€ physics               # Collision & simulation
β”‚   β”‚   β”œβ”€β”€ collider          # optimised collision mesh
β”‚   β”‚   β”œβ”€β”€ rigid             # rigid body setup
β”‚   β”‚   β”œβ”€β”€ cloth             # cloth/hair simulation bake
β”‚   β”‚   └── export            # engine physics export
β”‚   └── lighting              # Lighting assets
β”‚       β”œβ”€β”€ hdri              # text β†’ HDR sky map
β”‚       β”œβ”€β”€ probes            # reflection/irradiance probes
β”‚       β”œβ”€β”€ volumetrics       # fog, clouds, atmosphere
β”‚       └── bake              # GI lightmap bake
β”œβ”€β”€ pipeline                  # Orchestration
β”‚   β”œβ”€β”€ workflow              # Multi-step workflows
β”‚   β”‚   β”œβ”€β”€ create            # define step sequence
β”‚   β”‚   β”œβ”€β”€ run               # execute with inputs
β”‚   β”‚   └── list              # browse saved workflows
β”‚   β”œβ”€β”€ batch                 # Batch processing
β”‚   β”‚   β”œβ”€β”€ queue             # enqueue from JSON manifest
β”‚   β”‚   β”œβ”€β”€ variant           # style/damage variants
β”‚   β”‚   └── status            # batch queue overview
β”‚   └── integrate             # Engine integration
β”‚       β”œβ”€β”€ export            # engine-specific export
β”‚       β”œβ”€β”€ prefab            # bundle into prefab
β”‚       └── script            # behavior stubs
β”œβ”€β”€ support                   # Narrative & data
β”‚   β”œβ”€β”€ narrative
β”‚   β”‚   β”œβ”€β”€ dialog            # NPC dialog trees
β”‚   β”‚   └── lore              # world-building text
β”‚   └── data
β”‚       β”œβ”€β”€ lightmap          # AI lightmap baking
β”‚       └── proc              # procedural gen scripts
β”œβ”€β”€ qa                        # Quality assurance
β”‚   β”œβ”€β”€ validate              # mesh/UV/normal checks
β”‚   β”œβ”€β”€ perf                  # polygon/VRAM analysis
β”‚   β”œβ”€β”€ style                 # art style consistency
β”‚   └── report                # full QA report
β”œβ”€β”€ jobs                      # Job management
β”‚   β”œβ”€β”€ list                  # list all jobs
β”‚   β”œβ”€β”€ status <id>           # single job status (8-char prefix ok)
β”‚   β”œβ”€β”€ wait <id>             # wait with progress bar
β”‚   β”œβ”€β”€ cancel <id>           # cancel a job
β”‚   └── clean                 # remove old jobs from DB
β”œβ”€β”€ models                    # Model management
β”‚   β”œβ”€β”€ list                  # catalog + install status
β”‚   β”œβ”€β”€ status <id>           # single model details
β”‚   └── install [id...]       # download from HuggingFace
β”œβ”€β”€ config                    # Task β†’ model catalog management
β”‚   β”œβ”€β”€ list [--domain]       # browse all job types and their models
β”‚   β”œβ”€β”€ show <job-type>       # detail for one job type
β”‚   β”œβ”€β”€ set <job-type>        # set model for a job type (interactive HF search)
β”‚   β”œβ”€β”€ remove <job-type>     # revert user override β†’ built-in catalog
β”‚   └── search <query>        # search HuggingFace for compatible models
β”œβ”€β”€ client                    # Client-side configuration
β”‚   └── config
β”‚       β”œβ”€β”€ show              # show resolved server URL + health check
β”‚       β”œβ”€β”€ set-server <url>  # point client at a remote server
β”‚       └── unset-server      # revert to auto-start local server
└── server                    # Server management
    β”œβ”€β”€ start [--daemon]      # start local server
    β”œβ”€β”€ stop                  # stop local server
    β”œβ”€β”€ status                # server health check
    β”œβ”€β”€ config
    β”‚   β”œβ”€β”€ show              # show all server settings
    β”‚   β”œβ”€β”€ set <key> <val>   # persist a setting to server.yaml
    β”‚   └── models [--domain] # view/manage task β†’ model catalog
    β”œβ”€β”€ use <url>             # (alias for client config set-server)
    └── unset                 # (alias for client config unset-server)

Configuration

Config lives in the OS-appropriate directory (XDG on Linux/macOS, %APPDATA% on Windows):

FilePurpose
client.yamlServer URL, poll interval, default --wait
server.yamlHost, port, device, security policy
models.yamlUser catalog overrides (task β†’ HF model)
assgen.dbSQLite job database
server.pidRunning local server PID
# ~/.config/assgen/client.yaml
server_url: null          # null = auto-start local server
default_wait: false
poll_interval: 2.0

# ~/.config/assgen/server.yaml
host: "127.0.0.1"
port: 8432
device: "auto"            # auto | cuda | cpu
log_level: "info"

# Security / model governance
allow_list: []            # [] = allow all models; restrict with a list:
                          # allow_list: ["stabilityai/TripoSR", "cvssp/audioldm2"]
skip_model_validation: false  # true = bypass HF pipeline_tag compatibility checks

Task β†’ Model Catalog

Every game-dev task maps to a HuggingFace model. The built-in catalog lives in src/assgen/catalog.yaml. Users can override any entry:

# Browse all tasks and their models
assgen tasks

# Override the model for a task (interactive HF Hub search)
assgen config set visual.model.create

# Or specify directly
assgen config set visual.model.create --model-id stabilityai/TripoSR

# Revert to built-in
assgen config remove visual.model.create

Client-side overrides are stored in ~/.config/assgen/models.yaml and sent with each job submission (via the model_id field in the job request).

Model Validation

When a job is submitted the server validates the requested model against the task type using the HuggingFace Hub API:

  1. Allow-list check β€” if allow_list is non-empty in server.yaml, only models on the list may be downloaded/used.
  2. Pipeline-tag check β€” the model's pipeline_tag from HF Hub is checked against a compatibility table for the task (e.g., a TTS model will be rejected for visual.model.create which expects image-to-3d).
# Restrict downloads to approved models only
assgen server config set allow_list '["stabilityai/TripoSR","cvssp/audioldm2"]'

# Trust all models (default)
assgen server config set allow_list '[]'

# Skip compatibility checks (useful for research / experimental models)
assgen server config set skip_model_validation true

When skip_model_validation: false (default) and the HF Hub API is unreachable, the server allows the model (fail-open for offline use).

Running as a systemd Service

# /etc/systemd/system/assgen-server.service
[Unit]
Description=assgen asset generation server
After=network.target

[Service]
Type=simple
User=youruser
ExecStart=/path/to/.venv/bin/assgen-server start
Restart=on-failure
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
systemctl enable --now assgen-server
journalctl -u assgen-server -f   # follow JSON-structured logs

Hardware Notes

  • RTX 4070 (12GB VRAM): Sufficient for SDXL, TripoSR, MusicGen-Medium, AudioLDM2
  • Set device: "cuda" in server.yaml for GPU acceleration
  • For lighter models, device: "cpu" works but is slower
  • Use HF_TOKEN env var for authenticated Hub downloads (higher rate limits)

Adding Real Inference Handlers

The worker dispatches each job_type to assgen/server/handlers/<job_type>.py. Create a module with a run() function:

# src/assgen/server/handlers/visual_model_create.py
from pathlib import Path
from typing import Any, Callable

def run(
    job_type: str,
    params: dict[str, Any],
    model_id: str | None,
    model_path: str | None,
    device: str,
    progress_cb: Callable[[float, str], None],
    output_dir: str,
) -> dict[str, Any]:
    progress_cb(0.2, "Loading model")
    # ... load transformers pipeline from model_path ...
    progress_cb(0.8, "Running inference")
    # ... write output files to output_dir ...
    return {
        "files": ["output.glb"],
        "metadata": {"model": model_id},
    }

Without a handler, jobs run through the stub handler (which simulates steps and returns immediately β€” useful for development).

Contributing

PRs welcome. CI runs on every push/PR:

  • ruff check β€” linting
  • pytest -v β€” unit tests (no GPU required)
pip install -e ".[dev]"
ruff check src/ tests/
pytest -v

Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  assgen  (client CLI)                                      β”‚
β”‚  β”œβ”€β”€ visual model create --prompt "sword" --wait           β”‚
β”‚  β”œβ”€β”€ audio sfx generate "laser blast" --wait              β”‚
β”‚  └── jobs list / status / wait / cancel                   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    β”‚ HTTP (REST)
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  assgen-server                                             β”‚
β”‚  β”œβ”€β”€ FastAPI REST API  (/jobs  /models  /health)          β”‚
β”‚  β”œβ”€β”€ WorkerThread      (polls SQLite queue)               β”‚
β”‚  └── ModelManager      (HuggingFace Hub download/cache)   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    β”‚
         ~/.config/assgen/assgen.db   (SQLite)
         ~/.local/share/assgen/models/  (model cache)

The client auto-detects whether a server is configured:

  • If server_url is set in ~/.config/assgen/client.yaml β†’ use that server.
  • Otherwise β†’ start a local assgen-server process (PID-tracked) and use it.

This lets you run the server on a powerful GPU machine and point your laptop's client at it, or just run everything locally.

Installation

pip install assgen

# For GPU inference (RTX 4070 recommended):
pip install "assgen[inference]"

Quick Start

# Check version
assgen version

# Start local server (optional β€” client auto-starts if not configured)
assgen-server start --daemon

# Generate a 3D model
assgen visual model create --prompt "low-poly medieval sword" --wait

# Generate sound effects
assgen audio sfx generate "laser gun firing" --wait

# Generate background music
assgen audio music compose "epic orchestral battle theme" --duration 30 --wait

# Auto-rig a character
assgen visual rig auto character.glb --wait

# List recent jobs
assgen jobs list

# Point client at a remote server
assgen server use http://my-gpu-machine:8432

CLI Command Tree

assgen
β”œβ”€β”€ visual                    # All 3D visual assets
β”‚   β”œβ”€β”€ concept               # AI concept art (SDXL)
β”‚   β”‚   β”œβ”€β”€ generate          # text β†’ concept art
β”‚   β”‚   β”œβ”€β”€ ref               # multi-view reference sheet
β”‚   β”‚   └── style             # art style samples
β”‚   β”œβ”€β”€ blockout              # Greybox prototyping
β”‚   β”‚   β”œβ”€β”€ create            # text/image β†’ blockout mesh
β”‚   β”‚   β”œβ”€β”€ assemble          # combine pieces into scene
β”‚   β”‚   └── iterate           # quick variation
β”‚   β”œβ”€β”€ model                 # 3D mesh generation
β”‚   β”‚   β”œβ”€β”€ create            # text/image β†’ .glb (TripoSR)
β”‚   β”‚   β”œβ”€β”€ highpoly          # high-poly refinement
β”‚   β”‚   β”œβ”€β”€ retopo            # auto-retopology
β”‚   β”‚   β”œβ”€β”€ splat             # Gaussian Splatting (3DGS)
β”‚   β”‚   β”œβ”€β”€ edit              # deform / boolean / combine
β”‚   β”‚   β”œβ”€β”€ optimize          # LOD generation
β”‚   β”‚   └── export            # convert to engine format
β”‚   β”œβ”€β”€ uv                    # UV unwrapping
β”‚   β”‚   β”œβ”€β”€ auto              # AI smart-unwrap
β”‚   β”‚   β”œβ”€β”€ manual            # seam suggestions
β”‚   β”‚   └── optimize          # texel density optimisation
β”‚   β”œβ”€β”€ texture               # PBR texturing & baking
β”‚   β”‚   β”œβ”€β”€ generate          # text β†’ albedo + PBR maps
β”‚   β”‚   β”œβ”€β”€ apply             # project onto mesh
β”‚   β”‚   β”œβ”€β”€ bake              # high-to-low bake
β”‚   β”‚   └── pbr               # full PBR material set
β”‚   β”œβ”€β”€ rig                   # Character rigging
β”‚   β”‚   β”œβ”€β”€ auto              # auto-skeleton (UniRig)
β”‚   β”‚   β”œβ”€β”€ skin              # skin weight maps
β”‚   β”‚   └── retarget          # rig retargeting
β”‚   β”œβ”€β”€ animate               # Animation generation
β”‚   β”‚   β”œβ”€β”€ keyframe          # text β†’ animation (AnimateDiff)
β”‚   β”‚   β”œβ”€β”€ mocap             # video β†’ motion capture
β”‚   β”‚   β”œβ”€β”€ blend             # mix/loop animations
β”‚   β”‚   └── retarget          # animation retargeting
β”‚   β”œβ”€β”€ vfx                   # VFX & particles
β”‚   β”‚   β”œβ”€β”€ particle          # particle sprite sheets
β”‚   β”‚   β”œβ”€β”€ decal             # dynamic decal textures
β”‚   β”‚   └── sim               # physics VFX bake
β”‚   └── ui                    # UI/HUD elements
β”‚       β”œβ”€β”€ icon              # icons & sprites
β”‚       β”œβ”€β”€ hud               # health bars, minimaps
β”‚       └── overlay           # 2D canvas overlays
β”œβ”€β”€ audio                     # Sound & music
β”‚   β”œβ”€β”€ sfx                   # Sound effects (AudioLDM2)
β”‚   β”‚   β”œβ”€β”€ generate          # text β†’ WAV
β”‚   β”‚   β”œβ”€β”€ edit              # pitch/reverb/layer
β”‚   β”‚   └── library           # browse local SFX library
β”‚   β”œβ”€β”€ music                 # Music (MusicGen)
β”‚   β”‚   β”œβ”€β”€ compose           # text β†’ music track
β”‚   β”‚   β”œβ”€β”€ loop              # seamless loop generation
β”‚   β”‚   └── adaptive          # mood-based stems
β”‚   └── voice                 # Voice synthesis (Bark)
β”‚       β”œβ”€β”€ tts               # text β†’ speech
β”‚       β”œβ”€β”€ clone             # voice cloning
β”‚       └── dialog            # batch NPC dialog
β”œβ”€β”€ scene                     # Physics + lighting data
β”‚   β”œβ”€β”€ physics               # Collision & simulation
β”‚   β”‚   β”œβ”€β”€ collider          # optimised collision mesh
β”‚   β”‚   β”œβ”€β”€ rigid             # rigid body setup
β”‚   β”‚   β”œβ”€β”€ cloth             # cloth/hair simulation bake
β”‚   β”‚   └── export            # engine physics export
β”‚   └── lighting              # Lighting assets
β”‚       β”œβ”€β”€ hdri              # text β†’ HDR sky map
β”‚       β”œβ”€β”€ probes            # reflection/irradiance probes
β”‚       β”œβ”€β”€ volumetrics       # fog, clouds, atmosphere
β”‚       └── bake              # GI lightmap bake
β”œβ”€β”€ pipeline                  # Orchestration
β”‚   β”œβ”€β”€ workflow              # Multi-step workflows
β”‚   β”‚   β”œβ”€β”€ create            # define step sequence
β”‚   β”‚   β”œβ”€β”€ run               # execute with inputs
β”‚   β”‚   └── list              # browse saved workflows
β”‚   β”œβ”€β”€ batch                 # Batch processing
β”‚   β”‚   β”œβ”€β”€ queue             # enqueue from JSON manifest
β”‚   β”‚   β”œβ”€β”€ variant           # style/damage variants
β”‚   β”‚   └── status            # batch queue overview
β”‚   └── integrate             # Engine integration
β”‚       β”œβ”€β”€ export            # engine-specific export
β”‚       β”œβ”€β”€ prefab            # bundle into prefab
β”‚       └── script            # behavior stubs
β”œβ”€β”€ support                   # Narrative & data
β”‚   β”œβ”€β”€ narrative
β”‚   β”‚   β”œβ”€β”€ dialog            # NPC dialog trees
β”‚   β”‚   └── lore              # world-building text
β”‚   └── data
β”‚       β”œβ”€β”€ lightmap          # AI lightmap baking
β”‚       └── proc              # procedural gen scripts
β”œβ”€β”€ qa                        # Quality assurance
β”‚   β”œβ”€β”€ validate              # mesh/UV/normal checks
β”‚   β”œβ”€β”€ perf                  # polygon/VRAM analysis
β”‚   β”œβ”€β”€ style                 # art style consistency
β”‚   └── report                # full QA report
β”œβ”€β”€ jobs                      # Job management
β”‚   β”œβ”€β”€ list                  # list all jobs
β”‚   β”œβ”€β”€ status <id>           # single job status
β”‚   β”œβ”€β”€ wait <id>             # wait with progress bar
β”‚   β”œβ”€β”€ cancel <id>           # cancel a job
β”‚   └── clean                 # remove old jobs from DB
β”œβ”€β”€ models                    # Model management
β”‚   β”œβ”€β”€ list                  # catalog + install status
β”‚   β”œβ”€β”€ status <id>           # single model details
β”‚   └── install [id...]       # download from HuggingFace
└── server                    # Server management
    β”œβ”€β”€ start [--daemon]       # start local server
    β”œβ”€β”€ stop                   # stop local server
    β”œβ”€β”€ status                 # server health check
    β”œβ”€β”€ config                 # show resolved config
    β”œβ”€β”€ use <url>              # point client at server
    └── unset                  # revert to auto-start

Configuration

Config lives in the OS-appropriate directory (XDG on Linux/macOS, %APPDATA% on Windows):

FilePurpose
client.yamlServer URL, poll interval, default --wait
server.yamlHost, port, device (cuda/cpu), log level
models.yamlUser catalog overrides
assgen.dbSQLite job database
server.pidRunning local server PID
# ~/.config/assgen/client.yaml
server_url: null          # null = auto-start local server
default_wait: false
poll_interval: 2.0

# ~/.config/assgen/server.yaml
host: "127.0.0.1"
port: 8432
device: "auto"            # auto | cuda | cpu
log_level: "info"

Running as a systemd Service

# /etc/systemd/system/assgen-server.service
[Unit]
Description=assgen asset generation server
After=network.target

[Service]
Type=simple
User=youruser
ExecStart=/path/to/.venv/bin/assgen-server start
Restart=on-failure
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
systemctl enable --now assgen-server
journalctl -u assgen-server -f   # follow JSON-structured logs

Hardware Notes

  • RTX 4070 (12GB VRAM): Sufficient for SDXL, TripoSR, MusicGen-Medium, AudioLDM2
  • Set device: "cuda" in server.yaml for GPU acceleration
  • For lighter models, device: "cpu" works but is slower
  • Use HF_TOKEN env var for authenticated Hub downloads (higher rate limits)

Adding Real Inference Handlers

The worker dispatches each job_type to assgen/server/handlers/<job_type>.py. Create a module with a run() function:

# src/assgen/server/handlers/visual_model_create.py
from pathlib import Path
from typing import Any, Callable

def run(
    job_type: str,
    params: dict[str, Any],
    model_id: str | None,
    model_path: str | None,
    device: str,
    progress_cb: Callable[[float, str], None],
    output_dir: str,
) -> dict[str, Any]:
    progress_cb(0.2, "Loading model")
    # ... load transformers pipeline from model_path ...
    progress_cb(0.8, "Running inference")
    # ... write output files to output_dir ...
    return {
        "files": ["output.glb"],
        "metadata": {"model": model_id},
    }

Without a handler, jobs run through the stub handler (which simulates steps and returns immediately β€” useful for development).

Contributors

aallbrig

55 commits

Copilot

6 commits

aallbrig/AssetGen

0

stars

61

commits

Python

primary language

Jun 23, 2026

updated

aallbrig.github.io/AssetGen/

README

assgen

AI-driven game asset generation pipeline β€” Kubernetes-style client/server architecture for 3D game development.

CI Docs

πŸ“– Full Documentation β†’ aallbrig.github.io/assgen

Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  assgen  (client CLI)                                      β”‚
β”‚  β”œβ”€β”€ visual model create --prompt "sword" --wait           β”‚
β”‚  β”œβ”€β”€ audio sfx generate "laser blast" --wait              β”‚
β”‚  └── jobs list / status / wait / cancel                   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    β”‚ HTTP (REST)
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  assgen-server                                             β”‚
β”‚  β”œβ”€β”€ FastAPI REST API  (/jobs  /models  /health)          β”‚
β”‚  β”œβ”€β”€ WorkerThread      (polls SQLite queue)               β”‚
β”‚  β”œβ”€β”€ ModelManager      (HuggingFace Hub download/cache)   β”‚
β”‚  └── Validation        (allow-list + HF tag check)        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    β”‚
         ~/.config/assgen/assgen.db   (SQLite)
         ~/.local/share/assgen/models/  (model cache)

The client auto-detects whether a server is configured:

  • If server_url is set in ~/.config/assgen/client.yaml β†’ use that server.
  • Otherwise β†’ start a local assgen-server process (PID-tracked) and use it.

This lets you run the server on a powerful GPU machine and point your laptop's client at it, or just run everything locally.

Installation

pip install assgen

# For GPU inference (RTX 4070 recommended):
pip install "assgen[inference]"

[inference] extra: Installs torch, transformers, diffusers, accelerate, and trimesh for local GPU inference. Without it, assgen is a fully functional client that can talk to a remote assgen-server, but a local server will return stub outputs instead of running real models.

For CI environments or machines without a GPU, pip install assgen (without [inference]) is the right choice.

Development Setup

Clone and run from source:

git clone https://github.com/aallbrig/assgen.git
cd assgen

# Create and activate a virtual environment
python -m venv .venv
source .venv/bin/activate        # Linux / macOS
# .venv\Scripts\activate         # Windows PowerShell

# Install in editable mode with dev dependencies
pip install -e ".[dev]"

# For GPU inference (optional β€” needs CUDA-capable GPU):
pip install -e ".[dev,inference]"

# Verify the install
assgen version
assgen-server --help

Run tests: pytest -v (or make test)

Version note: assgen uses hatch-vcs to derive its version from git tags. If you install without a git tag (fresh clone, no tags), the version will appear as 0.1.dev0. Run git tag v0.1.0 to set a version, or ignore the warning β€” it does not affect functionality.

Quick Start

# Check version
assgen version

# Start local server (optional β€” client auto-starts if not configured)
assgen-server start --daemon

# Once the server is running, explore the REST API interactively:
# http://127.0.0.1:8432/docs      (Swagger UI)
# http://127.0.0.1:8432/redoc     (ReDoc)
# http://127.0.0.1:8432/health    (health check)

# Generate a 3D model
assgen visual model create --prompt "low-poly medieval sword" --wait

# Generate sound effects
assgen audio sfx generate "laser gun firing" --wait

# Generate background music
assgen audio music compose "epic orchestral battle theme" --duration 30 --wait

# Auto-rig a character
assgen visual rig auto character.glb --wait

# List recent jobs
assgen jobs list

# Point client at a remote GPU server
assgen client config set-server http://my-gpu-machine:8432

# View full game dev task β†’ model catalog
assgen tasks

# Show current server config
assgen server config show

assgen-server vs assgen server:

  • assgen-server start β€” runs the inference server directly (the process itself)
  • assgen server start β€” tells the client to launch a local assgen-server process for you
  • assgen server status / assgen server stop β€” manage the locally auto-started server

For a remote GPU machine, run assgen-server start --daemon there, then on your laptop: assgen client config set-server http://<gpu-machine>:8432

CLI Command Tree

assgen
β”œβ”€β”€ tasks                     # View all game dev tasks and their assigned models
β”‚   └── [--domain DOMAIN]     # filter by visual / audio / scene / pipeline / qa / support
β”œβ”€β”€ visual                    # All 3D visual assets
β”‚   β”œβ”€β”€ concept               # AI concept art (SDXL)
β”‚   β”‚   β”œβ”€β”€ generate          # text β†’ concept art
β”‚   β”‚   β”œβ”€β”€ ref               # multi-view reference sheet
β”‚   β”‚   └── style             # art style samples
β”‚   β”œβ”€β”€ blockout              # Greybox prototyping
β”‚   β”‚   β”œβ”€β”€ create            # text/image β†’ blockout mesh
β”‚   β”‚   β”œβ”€β”€ assemble          # combine pieces into scene
β”‚   β”‚   └── iterate           # quick variation
β”‚   β”œβ”€β”€ model                 # 3D mesh generation
β”‚   β”‚   β”œβ”€β”€ create            # text/image β†’ .glb (TripoSR)
β”‚   β”‚   β”œβ”€β”€ highpoly          # high-poly refinement
β”‚   β”‚   β”œβ”€β”€ retopo            # auto-retopology
β”‚   β”‚   β”œβ”€β”€ splat             # Gaussian Splatting (3DGS)
β”‚   β”‚   β”œβ”€β”€ edit              # deform / boolean / combine
β”‚   β”‚   β”œβ”€β”€ optimize          # LOD generation
β”‚   β”‚   └── export            # convert to engine format
β”‚   β”œβ”€β”€ uv                    # UV unwrapping
β”‚   β”‚   β”œβ”€β”€ auto              # AI smart-unwrap
β”‚   β”‚   β”œβ”€β”€ manual            # seam suggestions
β”‚   β”‚   └── optimize          # texel density optimisation
β”‚   β”œβ”€β”€ texture               # PBR texturing & baking
β”‚   β”‚   β”œβ”€β”€ generate          # text β†’ albedo + PBR maps
β”‚   β”‚   β”œβ”€β”€ apply             # project onto mesh
β”‚   β”‚   β”œβ”€β”€ bake              # high-to-low bake
β”‚   β”‚   └── pbr               # full PBR material set
β”‚   β”œβ”€β”€ rig                   # Character rigging
β”‚   β”‚   β”œβ”€β”€ auto              # auto-skeleton (UniRig)
β”‚   β”‚   β”œβ”€β”€ skin              # skin weight maps
β”‚   β”‚   └── retarget          # rig retargeting
β”‚   β”œβ”€β”€ animate               # Animation generation
β”‚   β”‚   β”œβ”€β”€ keyframe          # text β†’ animation (AnimateDiff)
β”‚   β”‚   β”œβ”€β”€ mocap             # video β†’ motion capture
β”‚   β”‚   β”œβ”€β”€ blend             # mix/loop animations
β”‚   β”‚   └── retarget          # animation retargeting
β”‚   β”œβ”€β”€ vfx                   # VFX & particles
β”‚   β”‚   β”œβ”€β”€ particle          # particle sprite sheets
β”‚   β”‚   β”œβ”€β”€ decal             # dynamic decal textures
β”‚   β”‚   └── sim               # physics VFX bake
β”‚   └── ui                    # UI/HUD elements
β”‚       β”œβ”€β”€ icon              # icons & sprites
β”‚       β”œβ”€β”€ hud               # health bars, minimaps
β”‚       └── overlay           # 2D canvas overlays
β”œβ”€β”€ audio                     # Sound & music
β”‚   β”œβ”€β”€ sfx                   # Sound effects (AudioLDM2)
β”‚   β”‚   β”œβ”€β”€ generate          # text β†’ WAV
β”‚   β”‚   β”œβ”€β”€ edit              # pitch/reverb/layer
β”‚   β”‚   └── library           # browse local SFX library
β”‚   β”œβ”€β”€ music                 # Music (MusicGen)
β”‚   β”‚   β”œβ”€β”€ compose           # text β†’ music track
β”‚   β”‚   β”œβ”€β”€ loop              # seamless loop generation
β”‚   β”‚   └── adaptive          # mood-based stems
β”‚   └── voice                 # Voice synthesis (Bark)
β”‚       β”œβ”€β”€ tts               # text β†’ speech
β”‚       β”œβ”€β”€ clone             # voice cloning
β”‚       └── dialog            # batch NPC dialog
β”œβ”€β”€ scene                     # Physics + lighting data
β”‚   β”œβ”€β”€ physics               # Collision & simulation
β”‚   β”‚   β”œβ”€β”€ collider          # optimised collision mesh
β”‚   β”‚   β”œβ”€β”€ rigid             # rigid body setup
β”‚   β”‚   β”œβ”€β”€ cloth             # cloth/hair simulation bake
β”‚   β”‚   └── export            # engine physics export
β”‚   └── lighting              # Lighting assets
β”‚       β”œβ”€β”€ hdri              # text β†’ HDR sky map
β”‚       β”œβ”€β”€ probes            # reflection/irradiance probes
β”‚       β”œβ”€β”€ volumetrics       # fog, clouds, atmosphere
β”‚       └── bake              # GI lightmap bake
β”œβ”€β”€ pipeline                  # Orchestration
β”‚   β”œβ”€β”€ workflow              # Multi-step workflows
β”‚   β”‚   β”œβ”€β”€ create            # define step sequence
β”‚   β”‚   β”œβ”€β”€ run               # execute with inputs
β”‚   β”‚   └── list              # browse saved workflows
β”‚   β”œβ”€β”€ batch                 # Batch processing
β”‚   β”‚   β”œβ”€β”€ queue             # enqueue from JSON manifest
β”‚   β”‚   β”œβ”€β”€ variant           # style/damage variants
β”‚   β”‚   └── status            # batch queue overview
β”‚   └── integrate             # Engine integration
β”‚       β”œβ”€β”€ export            # engine-specific export
β”‚       β”œβ”€β”€ prefab            # bundle into prefab
β”‚       └── script            # behavior stubs
β”œβ”€β”€ support                   # Narrative & data
β”‚   β”œβ”€β”€ narrative
β”‚   β”‚   β”œβ”€β”€ dialog            # NPC dialog trees
β”‚   β”‚   └── lore              # world-building text
β”‚   └── data
β”‚       β”œβ”€β”€ lightmap          # AI lightmap baking
β”‚       └── proc              # procedural gen scripts
β”œβ”€β”€ qa                        # Quality assurance
β”‚   β”œβ”€β”€ validate              # mesh/UV/normal checks
β”‚   β”œβ”€β”€ perf                  # polygon/VRAM analysis
β”‚   β”œβ”€β”€ style                 # art style consistency
β”‚   └── report                # full QA report
β”œβ”€β”€ jobs                      # Job management
β”‚   β”œβ”€β”€ list                  # list all jobs
β”‚   β”œβ”€β”€ status <id>           # single job status (8-char prefix ok)
β”‚   β”œβ”€β”€ wait <id>             # wait with progress bar
β”‚   β”œβ”€β”€ cancel <id>           # cancel a job
β”‚   └── clean                 # remove old jobs from DB
β”œβ”€β”€ models                    # Model management
β”‚   β”œβ”€β”€ list                  # catalog + install status
β”‚   β”œβ”€β”€ status <id>           # single model details
β”‚   └── install [id...]       # download from HuggingFace
β”œβ”€β”€ config                    # Task β†’ model catalog management
β”‚   β”œβ”€β”€ list [--domain]       # browse all job types and their models
β”‚   β”œβ”€β”€ show <job-type>       # detail for one job type
β”‚   β”œβ”€β”€ set <job-type>        # set model for a job type (interactive HF search)
β”‚   β”œβ”€β”€ remove <job-type>     # revert user override β†’ built-in catalog
β”‚   └── search <query>        # search HuggingFace for compatible models
β”œβ”€β”€ client                    # Client-side configuration
β”‚   └── config
β”‚       β”œβ”€β”€ show              # show resolved server URL + health check
β”‚       β”œβ”€β”€ set-server <url>  # point client at a remote server
β”‚       └── unset-server      # revert to auto-start local server
└── server                    # Server management
    β”œβ”€β”€ start [--daemon]      # start local server
    β”œβ”€β”€ stop                  # stop local server
    β”œβ”€β”€ status                # server health check
    β”œβ”€β”€ config
    β”‚   β”œβ”€β”€ show              # show all server settings
    β”‚   β”œβ”€β”€ set <key> <val>   # persist a setting to server.yaml
    β”‚   └── models [--domain] # view/manage task β†’ model catalog
    β”œβ”€β”€ use <url>             # (alias for client config set-server)
    └── unset                 # (alias for client config unset-server)

Configuration

Config lives in the OS-appropriate directory (XDG on Linux/macOS, %APPDATA% on Windows):

FilePurpose
client.yamlServer URL, poll interval, default --wait
server.yamlHost, port, device, security policy
models.yamlUser catalog overrides (task β†’ HF model)
assgen.dbSQLite job database
server.pidRunning local server PID
# ~/.config/assgen/client.yaml
server_url: null          # null = auto-start local server
default_wait: false
poll_interval: 2.0

# ~/.config/assgen/server.yaml
host: "127.0.0.1"
port: 8432
device: "auto"            # auto | cuda | cpu
log_level: "info"

# Security / model governance
allow_list: []            # [] = allow all models; restrict with a list:
                          # allow_list: ["stabilityai/TripoSR", "cvssp/audioldm2"]
skip_model_validation: false  # true = bypass HF pipeline_tag compatibility checks

Task β†’ Model Catalog

Every game-dev task maps to a HuggingFace model. The built-in catalog lives in src/assgen/catalog.yaml. Users can override any entry:

# Browse all tasks and their models
assgen tasks

# Override the model for a task (interactive HF Hub search)
assgen config set visual.model.create

# Or specify directly
assgen config set visual.model.create --model-id stabilityai/TripoSR

# Revert to built-in
assgen config remove visual.model.create

Client-side overrides are stored in ~/.config/assgen/models.yaml and sent with each job submission (via the model_id field in the job request).

Model Validation

When a job is submitted the server validates the requested model against the task type using the HuggingFace Hub API:

  1. Allow-list check β€” if allow_list is non-empty in server.yaml, only models on the list may be downloaded/used.
  2. Pipeline-tag check β€” the model's pipeline_tag from HF Hub is checked against a compatibility table for the task (e.g., a TTS model will be rejected for visual.model.create which expects image-to-3d).
# Restrict downloads to approved models only
assgen server config set allow_list '["stabilityai/TripoSR","cvssp/audioldm2"]'

# Trust all models (default)
assgen server config set allow_list '[]'

# Skip compatibility checks (useful for research / experimental models)
assgen server config set skip_model_validation true

When skip_model_validation: false (default) and the HF Hub API is unreachable, the server allows the model (fail-open for offline use).

Running as a systemd Service

# /etc/systemd/system/assgen-server.service
[Unit]
Description=assgen asset generation server
After=network.target

[Service]
Type=simple
User=youruser
ExecStart=/path/to/.venv/bin/assgen-server start
Restart=on-failure
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
systemctl enable --now assgen-server
journalctl -u assgen-server -f   # follow JSON-structured logs

Hardware Notes

  • RTX 4070 (12GB VRAM): Sufficient for SDXL, TripoSR, MusicGen-Medium, AudioLDM2
  • Set device: "cuda" in server.yaml for GPU acceleration
  • For lighter models, device: "cpu" works but is slower
  • Use HF_TOKEN env var for authenticated Hub downloads (higher rate limits)

Adding Real Inference Handlers

The worker dispatches each job_type to assgen/server/handlers/<job_type>.py. Create a module with a run() function:

# src/assgen/server/handlers/visual_model_create.py
from pathlib import Path
from typing import Any, Callable

def run(
    job_type: str,
    params: dict[str, Any],
    model_id: str | None,
    model_path: str | None,
    device: str,
    progress_cb: Callable[[float, str], None],
    output_dir: str,
) -> dict[str, Any]:
    progress_cb(0.2, "Loading model")
    # ... load transformers pipeline from model_path ...
    progress_cb(0.8, "Running inference")
    # ... write output files to output_dir ...
    return {
        "files": ["output.glb"],
        "metadata": {"model": model_id},
    }

Without a handler, jobs run through the stub handler (which simulates steps and returns immediately β€” useful for development).

Contributing

PRs welcome. CI runs on every push/PR:

  • ruff check β€” linting
  • pytest -v β€” unit tests (no GPU required)
pip install -e ".[dev]"
ruff check src/ tests/
pytest -v

Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  assgen  (client CLI)                                      β”‚
β”‚  β”œβ”€β”€ visual model create --prompt "sword" --wait           β”‚
β”‚  β”œβ”€β”€ audio sfx generate "laser blast" --wait              β”‚
β”‚  └── jobs list / status / wait / cancel                   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    β”‚ HTTP (REST)
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  assgen-server                                             β”‚
β”‚  β”œβ”€β”€ FastAPI REST API  (/jobs  /models  /health)          β”‚
β”‚  β”œβ”€β”€ WorkerThread      (polls SQLite queue)               β”‚
β”‚  └── ModelManager      (HuggingFace Hub download/cache)   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    β”‚
         ~/.config/assgen/assgen.db   (SQLite)
         ~/.local/share/assgen/models/  (model cache)

The client auto-detects whether a server is configured:

  • If server_url is set in ~/.config/assgen/client.yaml β†’ use that server.
  • Otherwise β†’ start a local assgen-server process (PID-tracked) and use it.

This lets you run the server on a powerful GPU machine and point your laptop's client at it, or just run everything locally.

Installation

pip install assgen

# For GPU inference (RTX 4070 recommended):
pip install "assgen[inference]"

Quick Start

# Check version
assgen version

# Start local server (optional β€” client auto-starts if not configured)
assgen-server start --daemon

# Generate a 3D model
assgen visual model create --prompt "low-poly medieval sword" --wait

# Generate sound effects
assgen audio sfx generate "laser gun firing" --wait

# Generate background music
assgen audio music compose "epic orchestral battle theme" --duration 30 --wait

# Auto-rig a character
assgen visual rig auto character.glb --wait

# List recent jobs
assgen jobs list

# Point client at a remote server
assgen server use http://my-gpu-machine:8432

CLI Command Tree

assgen
β”œβ”€β”€ visual                    # All 3D visual assets
β”‚   β”œβ”€β”€ concept               # AI concept art (SDXL)
β”‚   β”‚   β”œβ”€β”€ generate          # text β†’ concept art
β”‚   β”‚   β”œβ”€β”€ ref               # multi-view reference sheet
β”‚   β”‚   └── style             # art style samples
β”‚   β”œβ”€β”€ blockout              # Greybox prototyping
β”‚   β”‚   β”œβ”€β”€ create            # text/image β†’ blockout mesh
β”‚   β”‚   β”œβ”€β”€ assemble          # combine pieces into scene
β”‚   β”‚   └── iterate           # quick variation
β”‚   β”œβ”€β”€ model                 # 3D mesh generation
β”‚   β”‚   β”œβ”€β”€ create            # text/image β†’ .glb (TripoSR)
β”‚   β”‚   β”œβ”€β”€ highpoly          # high-poly refinement
β”‚   β”‚   β”œβ”€β”€ retopo            # auto-retopology
β”‚   β”‚   β”œβ”€β”€ splat             # Gaussian Splatting (3DGS)
β”‚   β”‚   β”œβ”€β”€ edit              # deform / boolean / combine
β”‚   β”‚   β”œβ”€β”€ optimize          # LOD generation
β”‚   β”‚   └── export            # convert to engine format
β”‚   β”œβ”€β”€ uv                    # UV unwrapping
β”‚   β”‚   β”œβ”€β”€ auto              # AI smart-unwrap
β”‚   β”‚   β”œβ”€β”€ manual            # seam suggestions
β”‚   β”‚   └── optimize          # texel density optimisation
β”‚   β”œβ”€β”€ texture               # PBR texturing & baking
β”‚   β”‚   β”œβ”€β”€ generate          # text β†’ albedo + PBR maps
β”‚   β”‚   β”œβ”€β”€ apply             # project onto mesh
β”‚   β”‚   β”œβ”€β”€ bake              # high-to-low bake
β”‚   β”‚   └── pbr               # full PBR material set
β”‚   β”œβ”€β”€ rig                   # Character rigging
β”‚   β”‚   β”œβ”€β”€ auto              # auto-skeleton (UniRig)
β”‚   β”‚   β”œβ”€β”€ skin              # skin weight maps
β”‚   β”‚   └── retarget          # rig retargeting
β”‚   β”œβ”€β”€ animate               # Animation generation
β”‚   β”‚   β”œβ”€β”€ keyframe          # text β†’ animation (AnimateDiff)
β”‚   β”‚   β”œβ”€β”€ mocap             # video β†’ motion capture
β”‚   β”‚   β”œβ”€β”€ blend             # mix/loop animations
β”‚   β”‚   └── retarget          # animation retargeting
β”‚   β”œβ”€β”€ vfx                   # VFX & particles
β”‚   β”‚   β”œβ”€β”€ particle          # particle sprite sheets
β”‚   β”‚   β”œβ”€β”€ decal             # dynamic decal textures
β”‚   β”‚   └── sim               # physics VFX bake
β”‚   └── ui                    # UI/HUD elements
β”‚       β”œβ”€β”€ icon              # icons & sprites
β”‚       β”œβ”€β”€ hud               # health bars, minimaps
β”‚       └── overlay           # 2D canvas overlays
β”œβ”€β”€ audio                     # Sound & music
β”‚   β”œβ”€β”€ sfx                   # Sound effects (AudioLDM2)
β”‚   β”‚   β”œβ”€β”€ generate          # text β†’ WAV
β”‚   β”‚   β”œβ”€β”€ edit              # pitch/reverb/layer
β”‚   β”‚   └── library           # browse local SFX library
β”‚   β”œβ”€β”€ music                 # Music (MusicGen)
β”‚   β”‚   β”œβ”€β”€ compose           # text β†’ music track
β”‚   β”‚   β”œβ”€β”€ loop              # seamless loop generation
β”‚   β”‚   └── adaptive          # mood-based stems
β”‚   └── voice                 # Voice synthesis (Bark)
β”‚       β”œβ”€β”€ tts               # text β†’ speech
β”‚       β”œβ”€β”€ clone             # voice cloning
β”‚       └── dialog            # batch NPC dialog
β”œβ”€β”€ scene                     # Physics + lighting data
β”‚   β”œβ”€β”€ physics               # Collision & simulation
β”‚   β”‚   β”œβ”€β”€ collider          # optimised collision mesh
β”‚   β”‚   β”œβ”€β”€ rigid             # rigid body setup
β”‚   β”‚   β”œβ”€β”€ cloth             # cloth/hair simulation bake
β”‚   β”‚   └── export            # engine physics export
β”‚   └── lighting              # Lighting assets
β”‚       β”œβ”€β”€ hdri              # text β†’ HDR sky map
β”‚       β”œβ”€β”€ probes            # reflection/irradiance probes
β”‚       β”œβ”€β”€ volumetrics       # fog, clouds, atmosphere
β”‚       └── bake              # GI lightmap bake
β”œβ”€β”€ pipeline                  # Orchestration
β”‚   β”œβ”€β”€ workflow              # Multi-step workflows
β”‚   β”‚   β”œβ”€β”€ create            # define step sequence
β”‚   β”‚   β”œβ”€β”€ run               # execute with inputs
β”‚   β”‚   └── list              # browse saved workflows
β”‚   β”œβ”€β”€ batch                 # Batch processing
β”‚   β”‚   β”œβ”€β”€ queue             # enqueue from JSON manifest
β”‚   β”‚   β”œβ”€β”€ variant           # style/damage variants
β”‚   β”‚   └── status            # batch queue overview
β”‚   └── integrate             # Engine integration
β”‚       β”œβ”€β”€ export            # engine-specific export
β”‚       β”œβ”€β”€ prefab            # bundle into prefab
β”‚       └── script            # behavior stubs
β”œβ”€β”€ support                   # Narrative & data
β”‚   β”œβ”€β”€ narrative
β”‚   β”‚   β”œβ”€β”€ dialog            # NPC dialog trees
β”‚   β”‚   └── lore              # world-building text
β”‚   └── data
β”‚       β”œβ”€β”€ lightmap          # AI lightmap baking
β”‚       └── proc              # procedural gen scripts
β”œβ”€β”€ qa                        # Quality assurance
β”‚   β”œβ”€β”€ validate              # mesh/UV/normal checks
β”‚   β”œβ”€β”€ perf                  # polygon/VRAM analysis
β”‚   β”œβ”€β”€ style                 # art style consistency
β”‚   └── report                # full QA report
β”œβ”€β”€ jobs                      # Job management
β”‚   β”œβ”€β”€ list                  # list all jobs
β”‚   β”œβ”€β”€ status <id>           # single job status
β”‚   β”œβ”€β”€ wait <id>             # wait with progress bar
β”‚   β”œβ”€β”€ cancel <id>           # cancel a job
β”‚   └── clean                 # remove old jobs from DB
β”œβ”€β”€ models                    # Model management
β”‚   β”œβ”€β”€ list                  # catalog + install status
β”‚   β”œβ”€β”€ status <id>           # single model details
β”‚   └── install [id...]       # download from HuggingFace
└── server                    # Server management
    β”œβ”€β”€ start [--daemon]       # start local server
    β”œβ”€β”€ stop                   # stop local server
    β”œβ”€β”€ status                 # server health check
    β”œβ”€β”€ config                 # show resolved config
    β”œβ”€β”€ use <url>              # point client at server
    └── unset                  # revert to auto-start

Configuration

Config lives in the OS-appropriate directory (XDG on Linux/macOS, %APPDATA% on Windows):

FilePurpose
client.yamlServer URL, poll interval, default --wait
server.yamlHost, port, device (cuda/cpu), log level
models.yamlUser catalog overrides
assgen.dbSQLite job database
server.pidRunning local server PID
# ~/.config/assgen/client.yaml
server_url: null          # null = auto-start local server
default_wait: false
poll_interval: 2.0

# ~/.config/assgen/server.yaml
host: "127.0.0.1"
port: 8432
device: "auto"            # auto | cuda | cpu
log_level: "info"

Running as a systemd Service

# /etc/systemd/system/assgen-server.service
[Unit]
Description=assgen asset generation server
After=network.target

[Service]
Type=simple
User=youruser
ExecStart=/path/to/.venv/bin/assgen-server start
Restart=on-failure
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
systemctl enable --now assgen-server
journalctl -u assgen-server -f   # follow JSON-structured logs

Hardware Notes

  • RTX 4070 (12GB VRAM): Sufficient for SDXL, TripoSR, MusicGen-Medium, AudioLDM2
  • Set device: "cuda" in server.yaml for GPU acceleration
  • For lighter models, device: "cpu" works but is slower
  • Use HF_TOKEN env var for authenticated Hub downloads (higher rate limits)

Adding Real Inference Handlers

The worker dispatches each job_type to assgen/server/handlers/<job_type>.py. Create a module with a run() function:

# src/assgen/server/handlers/visual_model_create.py
from pathlib import Path
from typing import Any, Callable

def run(
    job_type: str,
    params: dict[str, Any],
    model_id: str | None,
    model_path: str | None,
    device: str,
    progress_cb: Callable[[float, str], None],
    output_dir: str,
) -> dict[str, Any]:
    progress_cb(0.2, "Loading model")
    # ... load transformers pipeline from model_path ...
    progress_cb(0.8, "Running inference")
    # ... write output files to output_dir ...
    return {
        "files": ["output.glb"],
        "metadata": {"model": model_id},
    }

Without a handler, jobs run through the stub handler (which simulates steps and returns immediately β€” useful for development).

Contributors

aallbrig

55 commits

Copilot

6 commits

Languages

Python

99.7%