WorldForge Studio

What shipped

Newest first. Each entry corresponds to a signed git tag on the main branch. For per-spec ground truth, see STATUS.md.

  1. 2026-08-23audit-2026-08-23-complete

    Full-app audit + marketing site visual refresh

    8-section audit covering test coverage, CI health, architecture, and site freshness. Ships themed SVG illustrations for the hero + feature grid + showcase, and swaps every UI emoji for lucide-react icons.

    • Themed SVG hero (2400ร—1350) + 8 feature-card illustrations + 3 showcase mockups (all generated by `apps/site/scripts/generate-marketing-svgs.mjs`).
    • Consolidated ๐ŸŒ nav-brand across 13 files into a single `<SiteBrand />` component using lucide `<Globe />`.
    • Audit report at `docs/audits/2026-08-23-full-app-audit.md` โ€” actionable 30-day pick list.
  2. 2026-08-23phase-8-print-shop-persistence-complete

    Print-shop backend stub โ†’ DB-persisted MVP

    Print-shop orders now survive server restart. New `print_orders` table, owner-scoped list endpoint, audit-row on create, and a "Your recent orders" section on the /print-shops UI.

    • `POST /print-orders` writes to the DB via drizzle (migration 0024).
    • New `GET /print-orders` โ€” lists caller's orders newest-first.
    • Non-owner reads tightened to 404 (was 403 โ€” closes an id-enumeration leak).
    • `print_order:create` audit rows with `{shopId, docId, pageCount}` payload (omits PII).
    • `usePrintOrders()` client hook + "recent orders" section on `/print-shops`.
  3. 2026-08-23phase-8-i18n-framework-complete

    i18n framework (English-only) + server helper

    Ship a zero-dep translation framework so future locale files can drop in without a rewrite. `useT()` for client components, `getT()` for RSCs โ€” both API-compatible with `next-intl` for future upgrade.

    • `apps/web/messages/en.json` seed catalog (28 strings, launcher/world/packs/branches namespaces).
    • Nested-key JSON lookup + `{name}` interpolation. Missing keys render the raw key (visible fallback).
    • `useT()` hook + `<I18nProvider>` context + `getT()` for server components.
    • Bulk-ported `<EditorLauncher>`, `<BranchesPanel>`, `<BranchAcceptPanel>`, `<WorldList>` (Delete/Duplicate) + `/packs` RSC.
    • da/de/ja translations still TODO; framework is drop-in ready.
  4. 2026-08-23phase-8-print-shop-stub-complete

    Phase 8 slice 2 โ€” print-shop backend stub + UI

    First slice of the print-shop marketplace: fixture shop directory + in-memory order creation + `/print-shops` UI with order form and QR payload receipt. Real geo lookup + notifications land later.

    • `GET /print-shops?near=lat,lng&radius_km=10` โ€” 3 fixture shops (query validated but not filtered).
    • `POST /print-orders` + `GET /print-orders/:id/qr` โ€” owner-scoped stub.
    • `/print-shops` page: shop list, order form, QR receipt.
  5. 2026-08-23phase-5-branching-slice-3-complete

    Phase 5 branching slice 3 โ€” diff + accept-into-source

    Close the branching loop. Given a fork, view the top-level JSON diff against source and hit "Accept" to replace source with branch content. Version-guarded, owner-only, snapshotted for audit.

    • `GET /worlds/:id/diff` โ€” top-level JSON key diff (added/removed/changed).
    • `POST /worlds/:id/accept { expected_source_version }` โ€” atomic replace with 409 on stale.
    • Pre-accept JSON snapshot in `world:accept-branch` audit row (recoverable).
    • `<BranchAcceptPanel>` with two-step confirm โ€” dialog says REPLACE, not merge.
    • True CRDT three-way merge still deferred โ€” needs its own spec.
  6. 2026-08-23phase-5-branching-slice-2-complete

    Phase 5 branching slice 2 โ€” branches list + source backlink

    Navigate between forks and sources. Every branch shows a link back to its source; every world shows its forks (silent-empty when neither exists).

    • `GET /worlds/:id/branches` (audit-row driven, newest-first).
    • `GET /worlds/:id/source` โ€” reverse lookup.
    • `<BranchesPanel>` on the editor header.
  7. 2026-08-23phase-5-branching-slice-1-complete

    Phase 5 branching slice 1 โ€” world fork primitive

    Fork any readable world into a new owner-scoped draft copy. Anyone (owner or member or realm-member) can duplicate; the result is always caller-owned and starts as a draft.

    • `POST /worlds/:id/duplicate` โ€” raw JSON copied verbatim, name suffixed `" (branch)"`, `world:duplicate` audit row with `fromWorldId` lineage.
    • `<DuplicateWorldButton>` on `<EditorLauncher>` + `<RecentWorlds>`.
  8. 2026-08-23pack-studio-complete

    Pack Studio โ€” full end-to-end lifecycle

    The Pack Studio ships end-to-end: create โ†’ upload assets โ†’ publish โ†’ export as `.gas-pack` zip โ†’ import someone else's zip โ†’ discover in the marketplace. Everything a pack author needs to hand a pack to a friend.

    • Asset upload pipeline (multipart, sha256-verified, 50 MB cap, sha-keyed dedup).
    • Asset list + owner delete + inline rename + thumbnails + per-kind cover art picker.
    • `/packs/mine` browse route + `/packs/[packId]` read-only detail.
    • Draft/published visibility with public marketplace filtering (published-only).
    • Cover art upload / delete / pick-from-existing / per-kind filter.
    • Bundled starter pack seeded (cover + 5 SVG asset placeholders).
    • Pack duplication (fork-semantic โ€” anyone can duplicate).
    • Whole-pack zip export (`GET /packs/:id/export`) + import (`POST /packs/import`) with verify-before-write.
    • Marketplace search + theme filter on `/packs`.
    • 17 PRs (#44โ€“#60) landed 2026-08-22 โ†’ 08-23.
  9. 2026-08-23phase-3-replay-scene-playback-complete

    Phase 3 replay scene playback

    The Replay HUD now drives the 3D scene as the cursor moves โ€” active shot follows the log's most-recent `shot-change` payload, same as-of-cursor semantics as the existing weather replay.

    • Shot observer pauses for the HUD lifetime (prevents feedback loop).
    • `usePlaybackStore.selectShot()` driven by replay cursor.
    • Unmount clears the active shot so live playback resumes clean.
    • NPC schedule replay still deferred (needs SimulationView override consumers).
  10. 2026-08-23ci-vitest-timeout-fix-complete

    CI green โ€” vitest timeout bump across 4 app configs

    App Unit Tests job was flaking on CI docker-in-docker under contention. Bumped `apps/api`, `apps/site`, `apps/library-server`, `apps/sheet-designer` to `testTimeout=15s / hookTimeout=15s` to match `apps/web` (fixed in an earlier PR).

    • Root cause: vitest default of 5 s / 1 s too tight on CI runners.
    • Local run unchanged (2717 tests still pass in aggregate).
  11. 2026-08-21m7-11-follow-ups-complete

    M7.11 follow-ups aggregate

    All 5 originally-deferred items from `m7-11-complete` now have merged PRs + working runtime: T4b generate route, T4b per-plan budget, T5-runtime music/transition, T5-runtime weather particles (Phase 2 M2.6 too), T6b fully-offline HTML viewer.

    • Aggregate tag on the "mark T6b shipped + all M7.11-deferred items closed" docs commit.
    • PRs #16 / #17 / #18 / #19 / #20.
  12. 2026-08-21m7-11-complete

    M7.11 โ€” Cinematic Director recording + export + shot schema

    The Cinematic Director recording seat is real: hit record, capture WebM via MediaRecorder, transcode to MP4/GIF with ffmpeg-wasm, and share a self-contained HTML viewer that plays offline. Shot schema landed with per-shot metadata editor and an AI-assist LLM shot list generator.

    • WebM recording via MediaRecorder + MP4/GIF transcode via ffmpeg-wasm.
    • Shot schema (`WORLD_SCHEMA_VERSION` 0.17.0 โ†’ 0.18.0) with per-shot metadata editor.
    • AI-assist shot list generator (`POST /worlds/:id/shots/generate`) with per-plan daily budget.
    • Self-contained HTML viewer (`packages/cinematic/src/export/html-viewer.ts`).
    • 148 new tests; workspace 43/43 green.
  13. 2026-08-21editor-ux-polish-complete

    Editor UX Polish โ€” palette + shortcuts + PWA + tabbed inspector + onboarding

    The editor gets the finishing touches: `โŒ˜K` command palette + shortcut overlay + registries, PWA install button + hand-rolled service worker, first-run onboarding, skeleton loaders, sync-conflict modal, error boundary, and a 6-tab inspector (Terrain / Story / Cinematic / POIs / Spawns / Packs).

    • 4 workstreams shipped as a single tag.
    • Long-term tab pattern: tabs are self-sufficient store consumers.
  14. 2026-08-20m7-10-complete

    M7.10 โ€” Cinematic Director panel + Stage

    A dedicated `/editor/[worldId]/director` route with `<CinematicDirectorPanel>` and `<CinematicStage>` (R3F Canvas with camera-playback-only view). The seat for M7.11 recording.

    • Full-page director route with playback-only 3D canvas.
    • End-to-end shot selection + playback wiring.
  15. 2026-08-20m7-9-complete

    M7.9 โ€” Camera Paths Deepening

    All 11 M7.9 tasks shipped in one arc: cubic-bezier keyframes, world-clock anchor, multi-lane timeline, drag-to-move handles, cutscene/replay evaluators, and a Zustand playback store that both the inspector panel and the 3D viewport read/write through.

    • `WORLD_SCHEMA_VERSION` 0.16.0 โ†’ 0.17.0 (identity migration).
    • New pure `<CubicBezierEditor>` + `<CinematicClockBridge>` + `usePlaybackStore` (Zustand).
    • Cutscene + replay evaluators route through `evaluateFlythrough` (no longer throw).
  16. 2026-08-20site-polish-complete

    Site Polish โ€” docs mirror + gallery + changelog + SEO

    `apps/site` gets a documentation mirror (`/docs`), a curated gallery (`/gallery`), a public changelog (`/changelog`), legal pages, sitemap.xml, robots.txt, dynamic OG images, and a hero-media auto-detect shell.

    • 33+ routes emitted at build time.
    • Sidebar-nav docs with per-doc TOC.
    • Optional newsletter deferred.
    • Hero cinematic media wired with a procedural placeholder (see `apps/site/public/hero/README.md`); a hand-captured cinematic replaces the files in place.
  17. 2026-08-19phase-1-closeout-complete

    Phase-1 Closeout โ€” Godot export + Adventure Craft round-trip

    The MVP promise honoured: a world you author in the editor now exports to a real Godot 4.4+ scene and an Adventure Craft bundle. Nothing to install; hit Export โ–พ in the editor header.

    • New Godot exporter (`packages/export/src/godot.ts`) โ€” Node2D root + Marker2D per cell + per object, with metadata. Validated against Godot 4.6.1 headless.
    • Adventure Craft round-trip (`packages/export/src/adventure-craft.ts`) โ€” canonical `.gas-world.json`, byte-stable via the deterministic `serializeWorld`.
    • Editor header `<ExportMenu>` โ€” three targets (.gas-world / Godot / Adventure Craft) plus a non-blocking warnings modal.
    • First-run guide: `docs/USAGE.md`.
  18. 2026-08-19m7-8-complete

    M7.8 โ€” Camera Paths (data model + minimal UI)

    The first authorable cinematic layer. Add camera paths to a world, pick a kind (flythrough / orbit / follow_npc), scrub the mini-timeline, and see per-keyframe depth-of-field flow through the composer.

    • Pure `samplePath(path, t, ctx)` evaluator with centripetal Catmull-Rom.
    • 3D keyframe handles + timeline strip in the editor.
    • Cutscene/replay stubs (deferred to M7.9).
  19. 2026-08-18m7-7-complete

    M7.7 โ€” Cinematic Effects (DOF + motion blur schema)

    Depth-of-field renders live in the R3F composer, driven by the world doc. Motion-blur schema shipped for forward-compat; effect mount deferred until a compatible postprocessing lib lands.

    • Optional `depthOfField` + `motionBlur` on `CinematicConfigSchema`.
    • `<CinematicSettingsPanel>` in the editor inspector.
    • `PATCH /worlds/:id/cinematic` overlay endpoint.
  20. 2026-08-18m7-6-complete

    M7.6 โ€” Cinematic Foundation

    The Cinematic Director data model + tone-mapping + colour grading, mounted at the R3F Canvas root. Zero pixel-diff for pre-M7.6 worlds via the pass-through contract.

    • `CinematicConfigSchema` + `<CinematicComposer>` composer.
    • ACES_FILMIC default tone-mapping with `agx` / `neutral` alternatives.
    • Bit-identical pre-M7.6 rendering when no cinematic config is set.
  21. 2026-08-18m7-5-complete

    M7.5 โ€” AI Biome Generation

    NPC dialogue can offer biome overlays whose concrete cells are runtime-resolved against author-pinned pools. Deterministic seeding via Mulberry32 + FNV-1a.

    • Author-pinned biome themes + pools.
    • `POST /worlds/:id/biomes/apply` + `/decline` routes.
    • Two-counter AI budget (turns + biome offers against a single daily cap).
  22. 2026-08-18m7-4-complete

    M7.4 โ€” AI Quest Generation

    NPCs can offer quests whose stages, rewards, and targets are runtime-resolved against author-pinned pools. Per-player quest instances persist across sessions.

    • Author-pinned quest templates + pools.
    • Deterministic `resolveQuestIntent(...)`; LLM never writes identifiers.
    • Player quest race-safe accept via partial-unique index.