Development
Developmentπ
Build, test, and package LocalGPT Verse β plus the map of whatβs inside.
Repository layoutπ
crates/verse/ # a member of the localgpt workspace
βββ src/
β βββ main.rs app wiring, schedules, states
β βββ theme.rs design tokens + the world-mood registry
β βββ hud.rs now-playing, progress, hints, three-state fade
β βββ overlays/ onboarding, pause, queue, settings, credits, library
β βββ playback.rs transport signals, the ownership ladder
β βββ audio.rs kira playback, live tap, pause/end-of-track
β βββ analysis.rs symphonia β realfft: tempo, grid, sections, mood
β βββ world.rs procedural backdrop, cameras, time-dilation
β βββ world_assets.rs manifest pack, placement, LOD, embeddings
β βββ ml.rs CLAP zero-shot mood + embeddings (feature: ml)
β βββ demucs.rs stem separation + curves (feature: ml)
β βββ recipe.rs the authored WorldRecipe, applied from the sidecar
βββ assets/ fonts, models (synced), ml/
xtask/ cargo xtask fetch-assets β the asset pack every app shares
Threading is channels-and-atomics only across boundaries (the single shared-state exception is a microsecond Mutex around the audio manager). No unsafe, no GPL dependencies.
Feature flagsπ
| Flag | What it adds | Fetch first |
|---|---|---|
(default) | Playback, DSP analysis, rule-mapped worlds | β |
ml | CLAP zero-shot moods, embedding-ranked placement, Demucs stems | cargo xtask fetch-clap (~78 MB) |
CI compiles the optional tier so it canβt rot, and it falls back to the rule-derived world when its model is absent. There is no language-model tier: a recipe comes from the sidecar, written by an agent.
Smoke testπ
Boots through every screen, then exits β the fastest way to catch a broken overlay:
VERSE_SMOKE=1 cargo run -p localgpt-verse # walk every screen, then quit
VERSE_SMOKE=1 VERSE_SHOT=/tmp cargo run -p localgpt-verse # + save verse-hud.png / verse-overlays.png
Screenshot readback can intermittently return black frames on some machines (thatβs why Photo mode retries). A consistent black frame is a scene bug, not the flake β check the logs.
Perf stress testπ
VERSE_STRESS=5000 cargo run -p localgpt-verse --release # 5000 extra props, fps log, exit after 30s
VERSE_STRESS=0 cargo run -p localgpt-verse --release # control run: report only
Runs uncapped so the numbers show true frame cost. On the dev machine (2026-07): baseline world ~60 fps, ~1k props β 14 fps, 5k β 9 fps β CPU-side entity overhead dominates, so ~70β90 props is the comfortable ceiling until real instancing lands. Treat dense-pack budgets as measured, not promised.
Packagingπ
cargo xtask verse-bundle # assembles crates/verse/dist/: release binary + fonts + models from localgpt-world-assets
The 171-model CC0 pack lives in the separate localgpt-world-assets repository (formerly localgpt-verse-assets); its fetch_polyhaven.py downloads it and writes the manifest (with a semantic kind per asset β 19 kinds), normalize.py packs each model to a single uncompressed .glb (bevy_gltf supports neither quantized nor meshopt-compressed geometry), and the workspaceβs cargo xtask fetch-assets copies the manifest-referenced set into the folder every LocalGPT app reads. The macOS LocalGPT.app bundle does not carry the pack; that script fetches it once per machine.
Architecture at a glanceπ
Bevy main thread other threads
ββββββββββββββββββββββββββββββββββββββββββββ βββββββββββββββββββββββββββββ
β UI (hud.rs, overlays/) β β kira audio thread (cpal) β
β reads: Playback, Beat, Theme, Comfort β β StreamingSound decode β
β writes: intent resources (Paused, β¦) β β TapEffect: energy/onset β
ββββββββββββββββββββββββββββββββββββββββββββ€ β β AtomicU32 (lock-free) β
β Transport (audio.rs systems) βββββ€ β
ββββββββββββββββββββββββββββββββββββββββββββ€ βββββββββββββββββββββββββββββ€
β Signals (playback.rs advance_playback) β β import scan thread β
β ladder: simulation β live tap β grid βββββ€ walkdir+lofty β mpsc β
ββββββββββββββββββββββββββββββββββββββββββββ€ βββββββββββββββββββββββββββββ€
β World (world.rs, world_assets.rs) β β analysis worker thread β
β procedural ambient + manifest props β β symphoniaβrealfftβtempo β
ββββββββββββββββββββββββββββββββββββββββββββ β /sections/energy/mood β
β β mpsc, JSON sidecars β
βββββββββββββββββββββββββββββ
The full review β load-bearing decisions and findings β lives in ARCHITECTURE.md; milestone status in PLAN.md. The audio engine is now the shared localgpt-world-audio crate (one kira mixer, FunDSP graphs as sources); Verseβs own code keeps its analysis, moods, placement and performance.
Licensesπ
| Part | License |
|---|---|
| LocalGPT Verse code | Apache License 2.0 |
| Marcellus & Hanken Grotesk fonts | SIL Open Font License 1.1 |
3D model pack & starter music (localgpt-world-assets) | CC0 1.0 (public domain) |
| CLAP audio model weights | CC-BY-NC-4.0 β non-commercial only |
The optional model downloads (scripts/fetch-*.sh) carry their own licenses; the asset manifest records every modelβs source, author, and license, and the in-app Credits & Licenses screen renders it.