How it works

How it works🔗

FILE.md ──► doc.rs ──────► draft.rs ─────────► scene.rs ──► Bevy
            sections +     WorldManifest       entities,
            BLAKE3 hashes  (localgpt-world-    lights, fog
                            types)                  ▲
   ▲                                                │
watch.rs: poll the file, recompile on save     tour.rs: camera + caption
  • doc.rs: Markdown → title, front matter (genre: …), and one section per place — a ## heading (world) or a ----separated slide (deck). Each section carries a hash of its text (plus any world fence).
  • draft.rs: sections → a WorldManifest with one region per section — a winding path (world) or a straight presentation path (deck) — and a tour with one stop per section. Deterministic, with entity ids that are stable per section, so editing one section leaves the other regions untouched. Per section the first of these wins: a world fence’s exact entities, the sidecar’s cached agent build, the cached recipe — else the rules.
  • assets.rs: the shared pack’s manifest, kind and span math, so a build in the sidecar places the pack’s real CC0 models by semantic kind.
  • recipe.rs / sidecar.rs: the clamped per-region recipe type with its lenient parse, and the hash-keyed <doc>.world.json v2 cache (builds + recipes). MD reads the sidecar and never writes it: no model runs in MD, and the agent working on the file authors it.
  • scene.rs: spawns the manifest in Bevy using the same mapping as LocalGPT Gen, and loads placed GLBs.
  • tour.rs and watch.rs: navigation and hot reload.

Worlds use localgpt-world-types, the Open World Format’s types with LocalGPT’s surface on top, which LocalGPT Gen saves as world.ron, and pass Gen’s own validation. --print-ron prints exactly that file.

Develop🔗

cargo test -p localgpt-md
cargo clippy -p localgpt-md --all-targets -- -D warnings
cargo fmt --check

LocalGPT MD is open source under Apache-2.0; the code is crates/md in github.com/localgpt-app/localgpt. The desktop app compiles documents with the same pure library (--no-default-features: no Bevy) and renders them in Gen’s viewport.