Plan the 0.9.9-1.0.0 roadmap and re-evaluate the NPC base
Full build / Import + headless tests (push) Successful in 48s
Full build / Full desktop build + optional release (push) Skipped

Move the gap analysis and risks into PLAN.md, version the character track
(0.9.9 rig correction, 0.9.10 roster) and split 0.9.11-0.9.12 polish and
verification out of the old 0.10.0 milestone. Add roadmaps to 0.10.0, 0.11.0
and 1.0.0, record the Quaternius face-fidelity gate and the rest-relative
pose finding in MEMORY.md, and move the completed 0.9.7 and pose-harness
sections to DONE.md.
This commit is contained in:
zwitschi committed 2026-11-06 09:40:28 +01:00
1 parent 5508f5510f
commit 140a7ada0f
7 files changed
+760 -445

No files matched your search

+461 -398
View File
@@ -1,156 +1,43 @@
# TODO
Work is grouped by theme. Each item should be small enough to complete and verify on its own;
see `AGENTS.md` for the workflow and `MEMORY.md` for the decisions behind these plans.
Active task list. Work is grouped by milestone and workstream; every item is small enough to
complete and verify on its own. The product plan, gap analysis and release roadmap live in
[`PLAN.md`](PLAN.md); durable decisions and gotchas live in [`MEMORY.md`](MEMORY.md);
[`AGENTS.md`](AGENTS.md) defines the workflow.
**Priority order (2026-11-05, owner):** 1) **Quaternius NPC base migration** — use the CC0
Quaternius character as the mesh/animation source and bake it to the runtime contract; 2) the 3D
model and local map improvements; 3) ship it together in the **0.10.0 minor**. The 0.9.7/0.9.8
character patches are published. See `AGENTS.md` §Priority and Versioning and §Local Blender skills.
**Current state (2026-11-05):** v0.9.8 is published. Three venues, the shift loop, the
tutorial/campaign, the access/escalation system and the 12-character procedural library are
shipped. The character plan changed twice and landed on the CC0 Quaternius base; the owner
accepted the 62-joint runtime rig ([ADR-0018](docs/adr/0018-quaternius-stage2-runtime-rig.md)),
but the base does not yet render or animate correctly in Godot.
**Roadmap (detail in [`PLAN.md`](PLAN.md#release-roadmap)):**
| Version | Type | Scope |
| --- | --- | --- |
| `0.9.9` | patch | Quaternius pilot base: rig/export fix, pose composition, face/silhouette gate |
| `0.9.10` | patch | 12-role roster on the approved base, gear fit, budget evidence |
| `0.9.11` | patch | Scheduled venue, prop, foliage, lighting and set-dressing polish |
| `0.9.12` | patch | Performance/Web/accessibility verification before the minor |
| `0.10.0` | minor | Public-readiness release: playtests, balance, legal, platform matrix, docs |
| `0.10.1`–`0.10.3` | patch | Onboarding, balance and stability follow-ups |
| `0.11.0` | minor | Live body-camera replay, fourth venue, localization foundation |
| `0.12.0` | minor | Signed/storefront builds, frozen save contract, launch languages |
| `0.13.0` | minor | Content complete and feature freeze for 1.0.0 |
| `0.13.1`–`0.13.2` | patch | Release candidates |
| `1.0.0` | major | Stable release with a documented compatibility promise |
**Priority now:** the `0.9.9` rig-and-export correction. Do not start the 12-role roster
(`0.9.10`) before the single-variant pilot renders, animates and passes the owner face gate.
The unversioned tracks (3D review evidence, maintenance, Gaussian splatting) stay at the top of
this file because their work is not release-scoped; each milestone below is versioned and must
follow the release procedure in `AGENTS.md`.
The MIT Blender skill pack lives locally at `.agents/skills/blender-skills/` (gitignored). Every
3D workstream below names the skills to load; they are guidance only, and the project contract,
`blender_assets.py audit`/`fit`/`inspect` and the capture gates stay authoritative.
## Quaternius NPC base migration (top priority)
Goal: replace the generator-first NPC base with the CC0 **Quaternius Ultimate Modular
Characters** as the primary mesh and animation source, while keeping one committed
`npc_base` skinned mesh, the five tint slots and a runtime contract that Godot, gear
and tests can consume. The detailed decision is [ADR-0017](docs/adr/0017-quaternius-npc-base.md);
it supersedes the generator-first sourcing decision in ADR-0015.
**Why:** the research pack already has a coherent low-poly human silhouette, 21 modular
outfits and 24 animations. The current procedural body needs a separate head, hands, neck
and shoe pipeline to look human; using Quaternius as the base removes that bespoke body work.
**Default path (Stage 1):** retarget and proportion-warp the Quaternius mesh onto the
existing 13-core contract, so `NpcAvatar`, gear attach points and the current animation
composition keep working. The 62-joint Quaternius rig and its 24 clips are an authoring
source, not a new runtime dependency.
**Stage 2 gate:** if the proportion warp cannot preserve the Quaternius silhouette and
deformation at an acceptable level, stop the rollout and write a new ADR for adopting the
62-joint rig at runtime. Do not ship a hybrid rig or silently change `NpcAvatar`.
**Exit:** one committed Quaternius-derived source GLB produces all 12 variants inside
24,000 tris / 24,000 glTF vertices, with five slots, gear fit, Idle/Walk deformation,
`audit`/`fit`/`inspect` clean, the 24-NPC budget measured, and an owner-approved 12 × 6
baseline sheet.
### 1. Intake and canonical base
- [x] Keep the three researched CC0 GLBs (`Casual`, `Casual_Hoodie`, `Worker`) plus the
licence/mirror notes in `tmp/npc-research/quaternius/`; record the source URL,
licence, SHA-256 and download date in `docs/npc-model-sourcing.md`.
Verified: the three GLBs are in `tmp/npc-research/quaternius/`, SHA-256 re-hash matches the
recorded table, the mirror HTML/README are retained next to the folder, and the download
date (2026-11-03) is now recorded.
- [x] Inventory the four meshes, 62 joints, 24 clips and material names in each GLB; map
Quaternius materials to the five project slots (`skin`, `cloth`, `pants`, `accessory`,
`hair`).
Recorded in `docs/npc-model-sourcing.md` §Quaternius GLB inventory: 4 meshes per GLB
(Body/Feet/Head/Legs, 10.5k–13.0k verts), 62 joints (8 spine + 8 arm + 2 PT + 30 finger +
6 leg), 24 shared clips (retarget scope: Idle + Walk), and the material→slot map by mesh
region (Skin→skin; head hair→hair; body→cloth; legs→pants; feet→accessory).
- [x] Choose the initial outfit scope: build the three full GLBs first; only use the 21-part
modular builder if the three looks cannot cover the 12 roles.
Decided: the three full GLBs are the canonical-base + silhouette-gate scope. They cover
~3 of 12 roles (casual, hood, vest); jacket/coat/dress/responder/guard need the 21-part
modular builder or new clothing at §4. Recorded in `docs/npc-model-sourcing.md`.
- [x] Build a canonical `quaternius_base.glb`: one welded, triangulated, grounded 1.81 m
humanoid with front on Blender −Y, no animation, and a documented bone/part inventory.
Built from `Casual_Hoodie.glb` via `tmp/npc-research/build_quaternius_base.py`: one `npc_base`
mesh (3,199 welded verts / 6,206 tris), 62 joints, skinned, 1.81 m grounded, T-pose, no
clips, `inspect` clean. Inventory in `docs/npc-model-sourcing.md` §Canonical base.
### 2. Contract bake and animation
- [x] Author the 62-joint → 13-core joint map, including optional finger/face extras if
they survive within 24,000 vertices; record it in `docs/npc-model-sourcing.md`.
Map recorded: Hips←Hips (Root+Body collapse), Spine←Abdomen/Torso/Chest, Neck←Neck,
Head←Head, Shoulder←UpperArm (collar collapses), Elbow←LowerArm, Hand←Wrist,
Hip←UpperLeg, Knee←LowerLeg. Optional: 30 finger bones + Foot.L/R (toe); dropped: PT.L/R
pole targets. Quaternius hierarchy measured (Foot is a child of Root, not LowerLeg).
- [x] Bake the rest pose and proportion warp to the contract hip, knee, shoulder, elbow,
wrist and head positions. Measure the warp at every joint and record the silhouette
deltas; do not accept a distorted deltoid or shortened arm.
Arm-down bake works (`warp_full.py`: pose-rotate UpperArm −90° + modifier-apply +
`armature_apply`). Warp deltas recorded in `docs/npc-model-sourcing.md`: arm ×1.63,
leg ×0.74, torso ×1.61, hip −0.249, shoulder +0.122. Vision-judged as distorted
(paddle hands, lost forearms, stretched shins). **Gate fails — Stage 2 (62-joint runtime
ADR) indicated; do not rebuild on the warped base.**
- [-] Skin the Quaternius mesh and verify Idle, Walk, seated and arm-down poses. The old
MPFB/arm-retarget warps are not a reference; judge the Quaternius result directly.
(Direction set: ADR-0018 option 2 — 62-joint runtime. `NpcAvatar` maps the Quaternius
names + derives proxy pivots from `get_bone_global_rest` (commits `271f10a`/`0cd12af`).
Two blockers remain: (1) the arm-down GLB's **skinning** renders A-pose in Godot even
though its rest is arm-down — the `armature_apply` + `export_apply=True` bake writes
wrong inverse bind matrices, so fix the Blender export first; (2) `_pose_bone` uses
`rest * Quaternion(axis, angle)`, which only cancels when `rest² = identity` (the old rig's
180° rest); the Quaternius ~76° rest does not, so the pose formula must be derived from the
actual `set_bone_pose_rotation` semantics for a non-180° rest.)
- [ ] Retarget Idle and Walk from the 24 Quaternius clips to the contract rig; discard
combat, gun and sword clips. Verify looping, foot contact and frame rate in Godot.
(Direction set: no retarget needed — the clips are authored for the 62-joint rig; only
verify looping/foot contact in Godot.)
- [ ] Map the five slots, unwrap per slot, bake 256² AO/albedo/normal/ORM maps and check
texel density before any roster build.
### 3. Silhouette gate
- [ ] Render the base at 1.5 m and 1.85 m in front, three-quarter and profile; compare
against the Quaternius source and the current `npc_casual`. Use the vision judge for a
written verdict, but the owner decides.
- [ ] Confirm gear attach points (head, hand, back, chest) and test cap, helmet, backpack,
shoulder bag, lanyard, clipboard and firefighter tank against the new shoulders/hips.
- [ ] Go/no-go: if the warp fails the silhouette gate, stop and write the 62-joint runtime
ADR (Stage 2). Do not start the 12-variant rebuild.
### 4. Roster and rollout
- [ ] Map the 12 roles to Quaternius outfits/parts, build them in asset-family batches,
and keep every variant inside the 24,000/24,000 cap.
- [ ] Run `audit`, `fit`, `inspect`, `texels` and `npc_proportions.py report`; record the
12-variant table and the warp measurements.
- [ ] Re-run the 24-NPC budget smoke and the Web/Compatibility capture; record frame time
before and after the base swap.
- [ ] Capture the 12 × 6 baseline (`capture_npc_baseline.gd` → `npc_baseline.py sheet`) and
get owner approval before replacing the committed character GLBs.
- [ ] Rebuild AO maps, manifest entries, credits and review docs; commit one asset family per
change and never run a no-op full-library rebuild.
### 5. Retire the old character tracks
- [x] Remove the MPFB/MakeHuman development scripts, renders and review directories from
`tmp/` (done 2026-11-05). Keep only the Quaternius source pack and its licence notes.
- [x] Keep the committed `makehuman_head.glb` and the procedural `npc_base` only as tested
fallbacks until the Quaternius rollout is complete; do not add new MPFB work.
- [ ] Update `docs/development-status.md`, `CHANGELOG.md` and `CREDITS.md` when the new base
ships. MPFB must never become a CI, build or runtime dependency.
## Fix the Rig pose harness
Goal: `src/test/capture_npc_pose.gd` reports a pose but saves rest frames; the root cause is
narrowed to the skinned mesh ignoring its `Rig` parent transform. Fixing it unblocks the
weights/pose column of the 3D review; the evidence now feeds the Quaternius base bake.
*Skill route: `rigging`; evidence in `docs/3d-model-review.md` §"Pose evidence is blocked".*
- [x] Root cause found (2026-11-04): the harness never disabled the avatar's `_physics_process`,
so `_advance_fsm` + `_move_toward_target` ran every tick and reset `arrived`/velocity, which
made `theater_pose()` return "idle" and reverted the pose to rest. (The earlier "moving the
`Rig` child does not render" probe was a red herring: it set `rig.position.y` inside `_shoot()`
in the same frame as `root.get_texture().get_image()`, so it never got a rendered frame.)
- [x] Harness rebuilt: `capture_npc_pose.gd` now calls `set_physics_process(false)`/
`set_process(false)` after staging the avatar; the pose survives because only the direct
`_animate()` ticks drive it. Verified: sit vs idle diff 5.63, walk vs idle diff 2.29, and the
vision judge confirms the seated frame reads as crouched.
- [x] Captured all poses for all 12 variants (idle / walk_contact / walk_pass / sit × full +
shoulder views = 96 frames) and built `sheet_pose.jpg`/`sheet_shoulder.jpg` under `tmp/`.
(No separate "wave" theater pose exists; the escalation raise-hand gesture is not a distinct
capture in this harness.)
## 3D model and local map re-evaluation
Goal: re-judge every shipped 3D asset against the newly available Blender skill guidance, rank
@@ -159,14 +46,15 @@ venues against licensed real-world data — OSM footprints and building massing,
photoreal facades and the photo-driven geometry pipeline (sections H–M). Evidence comes from three
separate sources: licensed real-location photos, generated concept boards, and build captures. This
is an unversioned development track: it must not change the `npc_base` contract, the renderer or
the 0.10.0 release candidate.
the public 0.10.0 release.
**Sequencing (2026-11-03, owner):** the asset-review fixes (A–G, notably the character P0/P1
rebuilds and the face/foliage prototypes) stay **blocked** until the full local map rebuild
(H–M) is done **and** a fresh 3D model review runs against the new maps. The measurements and
scorecard in `docs/3d-model-review.md` stand as the pre-rebuild baseline, not a go-ahead to start
character work now. (Character development has since shipped — see `DONE.md` — and the next
character pass is the Quaternius base above.)
**Sequencing (updated 2026-11-05):** the old block is cleared. The local map rebuild (H–M) is
done, the 96/96 review ran against the new maps, and character work moved to the versioned
`0.9.9`/`0.9.10` milestones. This section is now the **evidence, scorecard and measurement
source**, not an open-ended backlog: the venue/prop/lighting fixes are scheduled into
`0.9.11`, the budget/LOD checks into `0.9.12`, and the character items (C) are superseded by
`0.9.9`/`0.9.10`. Fixes are made from the milestone checklists; the scorecard keeps the
measurements and verdicts.
**Map rebuild status (2026-11-03):** H–M are complete — the Joke Shop is now a 6.0 m low hall
(dark stucco, white signature fascia, tied-back curtains, hotel tower) and Hollywood/TV Studio
@@ -253,7 +141,14 @@ licence-free zone only.
per item; record the decision and the reason in the review document. **Deferred until the
full map rebuild (H–M) lands and a fresh 3D review runs against the new maps.**
### C. Character re-evaluation (8 variants + fallback)
### C. Character re-evaluation (superseded 2026-11-05)
The procedural character review is complete and its evidence stays in
`docs/3d-model-review.md`. The next character pass is the Quaternius base in
[`Milestone 0.9.9`](#milestone-099--quaternius-npc-base-swap-patch) and
[`Milestone 0.9.10`](#milestone-0910--npc-roster-rollout-patch); the open items below are kept
as evidence for what the new base must not regress (face read, hands, weights, cloth, texel
density, crowd variety).
*Skill route: `character-artist`, `retopology`, `rigging`, `uv-workflow`, `texture-workflow`,
`materials`, `hair-groom`, `asset-optimization`, `lookdev`, `qa-review`.*
@@ -291,8 +186,8 @@ licence-free zone only.
plus stride scaling are the accepted approach; a baked cloth-sim pipeline would only be
reconsidered if a later close-up shows visible hem/coat stiffness.
- [ ] Fix only the ranked P0/P1s, one asset family per commit; refresh the comparison sheet and
re-run `inspect`, `audit`, `fit` and `npc_proportions.py` after each fix. **Blocked until
the map rebuild + second 3D review (see the track's sequencing note).**
re-run `inspect`, `audit`, `fit` and `npc_proportions.py` after each fix. **Scheduled: the
remaining character items are covered by Milestone 0.9.9/0.9.10; this row is evidence only.**
- [x] Crowd-variety reference: five licence-cleared Commons photos fetched to
`tmp/research/crowd-variety/` (CC0 ×2, CC BY 2.0, CC BY 3.0, PD) covering umbrella/dense
crowds and a pedestrian mall — general build/hair/outer-layer variety context, reference
@@ -701,11 +596,11 @@ pass. The current `_build_comedy_store_building()` stays as the fallback.*
Unversioned housekeeping that keeps the planning sources trustworthy. Do these when they block a
task, not on a schedule.
**Status (2026-11-03):** v0.10.0-rc.1 source; three venues; 277 headless + 161 Python tests; the
**Status (2026-11-05):** v0.9.8 published; three venues; 277 headless + 162 Python tests; the
Hollywood and Joke Shop facade-realism passes landed (`limestone_ashlar`, `dark_stucco`, banner
night emissive, marquee emissive test); reference boards (`hollywood`, `joke-shop`) with sidecars;
three-up boards; `tools/refboard.py` + reference-anchored generation (`--reference`, `anchor`) +
`tools/three_up.py`. Gaussian splatting is deferred to the end of this file.
`tools/three_up.py`. Gaussian splatting stays deferred at the end of this file.
### Memory and status accuracy
@@ -720,8 +615,8 @@ three-up boards; `tools/refboard.py` + reference-anchored generation (`--referen
contradiction and the old 272/108 counts.)
- [x] Fix stale status claims as they are found; add a documentation check or grep note only if
the same class of drift returns. (Counts and the sign-in state corrected on 2026-11-03.)
- [x] Keep the Gap Analysis baseline and the README status line in sync when a test count, version
or feature milestone changes (the baseline was bumped to 277/161 on 2026-11-03).
- [x] Keep the `PLAN.md` gap-analysis baseline and the README status line in sync when a test count,
version or feature milestone changes (baseline bumped to 277/162 on 2026-11-05).
### Imagery and provenance upkeep
@@ -763,245 +658,6 @@ three-up boards; `tools/refboard.py` + reference-anchored generation (`--referen
- [ ] Prune the skill routes in `AGENTS.md` if a skill stops matching the project (for example if
a future second-rig path makes `rigging`/`animation` guidance authoritative).
## Gap Analysis and 0.x Roadmap
**Published baseline:** v0.9.6 (2026-11-03) — three playable venues, tutorial/campaign/checkpoint
resume, access/radio/escalation loop, shift review, the Blender asset library, 277 Godot + 161
Python tests, a 21/21 screen-design judge and Compatibility/Web/Desktop HQ builds.
**Current source:** 0.10.0-rc.1. Its clean release-candidate build is verified, but it is not
published while the gates below remain open.
### Open gaps
| Area | Remaining gap | Milestone |
| --- | --- | --- |
| 3D model and local map re-evaluation | Skill-guided asset scorecard/repairs; OSM/3D data, reference-derived facades, AI-assisted composition and map QA | Unversioned |
| Character development | Complete (moved to `DONE.md`); the Quaternius NPC base migration is the next character pass | 0.10.0 |
| Content and balance | External first-time-player evidence, balance sweeps/tuning and content lock | 0.10.0 |
| Audio, accessibility and localization | Accessibility/localization acceptance, caption coverage and pseudo-locale/layout sign-off | 0.10.0 |
| Performance and platform | Target-hardware matrix, Web/Desktop HQ profiling and frame/memory evidence | 0.10.0 |
| QA and release engineering | Final smoke matrix, clean build/checksum verification and target-matrix launch tests | 0.10.0 |
| Legal, signing and storefront | macOS signing/notarization, AI-provider rights, storefront/rating approval and privacy sign-off | 0.10.0 |
| Documentation and sign-off | Final README/status/TODO/manual evidence and known-limitations sign-off | 0.10.0 |
| Future 0.x | Live replay, more venues, VO/music, image-to-mesh props and seasonal content | Unscheduled |
The 0.9.3 UI, 0.9.4 animation, 0.9.5 texture, 0.9.6 integration and save-migration work are
complete in `DONE.md`; they are not remaining gaps. The 2026-11-01 documentation audit
(architecture ownership, stale-claim cleanup and obsolete-plan removal) is also closed.
**Priority (2026-11-05):** finish the `Rig` pose harness, then the Quaternius NPC base
migration, then re-evaluate the 3D models, then ship the **0.10.0** minor release. The 0.10.0 candidate
still accepts only release-blocking fixes until its external-playtest, legal/storefront, signing
and platform gates clear.
## Milestone 0.10.0 — 3D model and map improvements (minor)
Goal: ship all 3D model and map improvements together as the **0.10.0 minor** — the Quaternius
NPC base bake (contract armature + five slots), the rebuilt Comedy Store/Hollywood maps,
and the re-evaluated 3D scorecard — plus the external playtest, legal/storefront, signing and
platform gates from the old release candidate. The character-development patch (0.9.7) ships
first; this minor contains the model/map work.
### Content lock and external playtest
### Content lock and external playtest
- [x] Declare a content/feature freeze for 0.10.0; only release-blocking fixes and balance changes
may land after the freeze. (Frozen 2026-11-03 after the 0.9.6 integration
checkpoint; this pass is limited to release reliability, accessibility,
balance evidence and packaging.)
- [x] Produce a release-candidate build with the tutorial, campaign, all three venues, Help,
accessibility settings and checkpoint/resume enabled. (Clean worktree
`a9658ec` built `0.10.0-rc.1`: Linux 161.5 MB, Windows 197.2 MB, macOS
148.0 MB, Web 97.8 MB and HQ 241.6 MB. The Web/HQ archives include the
credits, privacy, accessibility and known-limitations pages; SHA-256
manifests were written; the Linux and HQ binaries launched headless and the
Web index/wasm/pck/docs returned HTTP 200. Not published because external
playtest and legal approval remain open.)
- [ ] Run at least five first-time-player sessions covering the tutorial and one full venue shift;
record where players get stuck, misunderstand evidence or choose disproportionate escalation.
- [ ] Triage findings by severity (P0/P1/P2) and fix every P0/P1 onboarding/accessibility issue;
keep the rest as explicit known limitations or post-0.10 items.
- [ ] Re-run the affected tutorial/campaign smokes after each fix and capture a fresh first-hour
walkthrough for the release notes.
### Balance and fairness pass
- [x] Define measurable targets for routine compliance, access-decision accuracy, peaceful
resolution, justified emergency calls and false-positive/false-negative rates.
(`docs/release-qa.md#balance-acceptance` defines cohorts, denominators, 36 matrix cells,
seeds, thresholds and matched emergency-first comparisons. Documentation verified;
targets are not measured results.)
- [ ] Run scripted venue sweeps across easy/normal/hard and all four phases; compare outcomes and
tune event weights, reaction tables, compliance and report strictness where targets fail.
- [ ] Review emergency calls against actual danger: no routine behavior should make emergency the
dominant winning move, and genuine threats must remain answerable. Include the
type-derived `_read_npc_truth()` mismatch with observed threats/forced entry;
use independently labelled behavior evidence, not the helper as its own oracle.
- [ ] Verify the reputation grades, debrief explanations and campaign progression still communicate
the de-escalation-first design after tuning.
- [ ] Record the balance evidence and any deliberate exceptions in `docs/development-status.md`
or `MEMORY.md`.
### Save migration and session reliability
- [x] Add fixtures for a 0.8-era settings/campaign/history save and a 0.9.0 checkpoint; verify
migration/default-filling and a clean first launch with no files. (Committed
fixtures under `src/test/fixtures/saves/`; 9 migration/failure tests cover
old settings/campaign/history, the 0.9.0 checkpoint, all three venue
checkpoint round-trips, clean install, corrupt JSON and a blocked atomic
replace. Suite is now 272 tests.)
- [x] Test fresh install → tutorial → campaign → pause → quit → resume → review → next venue on
an isolated user-data directory. (Tutorial and campaign smokes shared one
isolated `XDG_DATA_HOME`; tutorial completion/replay/skip then campaign
resume/review-continue/help both passed. Pause/menu behavior is covered by
`smoke_session_shell.gd`.)
- [x] Test corrupt JSON, partial temp files, missing optional fields and a failed atomic rename;
confirm fallback behavior never destroys a valid save. (Corrupt/partial files
fall back to defaults; a blocked temp path reports an error and leaves the
prior valid settings intact. `_load_json` now uses the non-logging JSON
instance parser.)
- [x] Verify checkpoint resume after all three venues, after an incident, with NPCs at the door and
with flashlight/body-camera/door state set. (The migration suite round-trips a
checkpoint for Hollywood, the Joke Shop and the TV Studio with an open
incident, one NPC row, flashlight/body-camera/door flags; the campaign smoke
resumes a live checkpoint through the real `GameManager`.)
- [x] Document save locations, schema versions, reset behavior and rollback/export instructions in
`docs/getting-started.md` and the release notes. (`getting-started.md` now
documents the four files, version-1 checkpoint, atomic write/fallback,
clean install, reset and backup/rollback.)
### Release engineering and distribution
- [x] Run `tools/build_releases.sh` from a clean checkout and verify Linux/Windows/macOS/Web/HQ
artifact names, sizes and checksums. (Clean worktree `a9658ec` built the
five artifacts listed above; `PUBLISH_DRY_RUN=1` produced and printed
`build/SHA256SUMS-0.10.0-rc.1.txt` without touching the API.)
- [ ] Smoke-test fresh Linux portable/AppImage, Windows portable/installer, macOS unzip/launch,
Web static hosting and Desktop HQ Vulkan fallback on the target matrix.
(Linux portable and Desktop HQ launched headless; Web files served over a
local static server with HTTP 200. AppImage/installer were not built locally
and Windows/macOS launch testing still needs the target matrix.)
- [x] Add a disk-space preflight and retention policy to the release/publish scripts so a full
Gitea host cannot leave a partially uploaded release. (`publish_release.sh`
checks artifact size/free space, writes SHA-256 checksums, supports
`PUBLISH_DRY_RUN`, rolls back uploaded assets/new releases on failure, and
offers opt-in `RETAIN_RELEASES` pruning; dry-run verified.)
- [x] Verify release metadata, tag/version consistency, asset counts and download links; retain
at least the latest 0.8/0.9 releases and document older-asset pruning.
(Source/version and tag are both 0.9.6; all seven published releases carry
5–7 assets, including the retained v0.8.0/v0.8.1/v0.9.0/v0.9.1 line.
`publish_release.sh` documents opt-in `RETAIN_RELEASES` pruning and
`RELEASING.md` describes the seven-release policy.)
- [x] Decide and document whether macOS signing/notarization is required for 0.10.0 or explicitly
remains a future release blocker; record the quarantine instructions either way.
(0.10.0 ships unsigned with quarantine instructions; signing/notarization
remains an explicit public-release blocker in `RELEASING.md` and
`known-limitations.md`.)
### Legal, credits and platform policy
- [x] Audit AI-assisted asset provenance and licenses; record source/model usage and any
redistribution constraints for textures, characters, props and UI art.
(`CREDITS.md` records the Blender/OpenRouter toolchain, default model slugs,
missing per-file generation metadata and the commercial-rights review as an
explicit release blocker.)
- [x] Audit audio/SFX/music licensing (or confirm everything is procedural) and add a credits file.
(All runtime audio is procedural; no external music/SFX files are bundled.
`CREDITS.md` records this.)
- [x] Review body-camera/privacy language, mental-health-crisis representation, age/content rating
and storefront requirements; fix any release-blocking copy or content.
(`PRIVACY.md` clarifies the simulated body camera/local-only data; the
accessibility and known-limitations pages record the remaining
mental-health/rating/storefront review as a release blocker rather than
claiming approval.)
- [x] Add the player-facing credits, known limitations, accessibility statement and privacy note to
the release package/README. (`README.md` links `CREDITS.md`, `PRIVACY.md`,
`docs/accessibility.md` and `docs/known-limitations.md`; the Web and Desktop
HQ package builders copy those documents into the shipped archives.)
- [ ] Mark external legal/storefront approval as complete or explicitly block the 0.10.0 release on it.
### Documentation and visual sign-off
- [ ] Update `README.md`, `PLAN.md`, `docs/architecture.md`, ADRs, `docs/development-status.md`,
`docs/getting-started.md`, `docs/release-qa.md#manual-smoke-checklist`, `CHANGELOG.md` and this roadmap.
- [ ] Regenerate the full screenshot gallery and realism baselines from the release-candidate
build (not the dev tree) after content lock; run `check_screenshots.sh` and the pinned vision
judge, recording model/spend/verdicts, and refresh the README and venue-doc images.
- [ ] Include the reference/concept boards and the updated asset sheets in the release docs, and
verify every README and docs-page image resolves from the tagged build.
- [ ] Run the manual smoke checklist on every target and attach/link the release-candidate evidence.
- [ ] Verify the tutorial/campaign/help text at maximum font scale and with the longest strings.
- [x] Remove or archive stale plans/notes and confirm no contradictory version/status claims remain.
- [x] Document the character development toolchain in `docs/architecture.md`: base vs library
sources, tool/artifact/gate table, runtime attach/animation contracts and rebuild discipline.
(Added §5 "Character development tooling" plus risk and ownership-map updates;
documentation check passed.)
### Release-candidate QA and exit
- [ ] Run the complete headless suite, Python tooling, tutorial/campaign/session/scenario smokes,
24-NPC budget smoke and release build from a clean checkout.
- [ ] Run the manual QA matrix: fresh install, upgrade, offline launch, gamepad, accessibility
settings, pause/resume, all venues and Desktop HQ fallback.
- [ ] Confirm no P0/P1 defects remain; P2 items must be documented as known limitations or
post-0.10 work.
- [ ] Create the `v0.10.0` version bump, changelog entry and tag; build/publish the release and
verify all assets and download links.
- [ ] Exit: the release candidate is content-locked, externally played, legally reviewed,
documented, reproducibly built, and approved as the 0.10.0 release candidate.
## Milestone 0.9.7 — Character development (patch)
Goal: release the finished procedural character development — the realistic face on all eight
variants, the four crowd-variety characters and the per-role pools — as a **patch** on top of
0.9.6. This keeps the 3D model and map improvements out of the patch; they land together in the
0.10.0 minor.
- [x] Rig pose harness fixed and the weights/pose evidence captured (see the top track).
- [x] Character work done: 12-character library, realistic face, crowd variants, per-role pools,
24-NPC budget 6.94 ms (152,464 tris / 168 meshes).
- [x] QA + local build for 0.9.7: Godot 277/277, Python 161/161, audit 49 OK, fit/proportions
12/12, release smoke matrix green, gallery 21/0, clean worktree build (Linux 172 MB,
Windows 206 MB, macOS 159 MB, Web 111 MB, HQ 266 MB), checksums verified, Linux binary
launches headless. Tagged `v0.9.7` (CI build/publish follows).
**Exit:** met — 0.9.7 ships the 12-character library (face realism + crowd variety) with the pose
harness fixed; the runtime contract is unchanged. The Quaternius NPC base and the map rebuild are
not in this patch (they target 0.10.0).
## Roadmap dependencies and risks
- Content volume is the largest schedule risk; tutorial and campaign work must not outrun the
event/dialogue matrix.
- The vision judge is a dev-time aid with an external key/budget; CI must never make it a hard gate.
- Godot version changes can alter lighting/imports; do not combine an engine baseline move with a
content/feature milestone.
- Signed macOS builds and legal/AI provenance are release blockers, not polish.
- Photo-derived map assets add a second provenance risk: downloaded or user-supplied photos can
carry unclear licences, identifiable people, plates and property restrictions. No photo or
splat-derived asset ships without a completed sidecar, consent/licence review and redaction.
- Gaussian-splat training is GPU/disk-heavy and the toolchain churns quickly; keep it offline,
version-pinned and outside CI, and never make a runtime splat renderer a release dependency.
- Keep the de-escalation-first rules and rare-emergency design unchanged while adding progression,
difficulty and feedback.
- The Blender skill pack is local, unversioned guidance; it can drift from the project contract or
assume Blender MCP. Re-verify every adopted technique with `inspect`/`audit`/`fit` and never
make a skill, asset pack or tool version a build or CI dependency.
- The 3D re-evaluation can expand without bound (retopo every head, rig every finger). Cap it with
the scorecard ranking: P0/P1 only, one asset family per commit, and an explicit accept for
everything else.
## Future / deferred (not scheduled)
- [ ] Live 3D body-camera replay; the timeline is text-only today.
- [ ] Additional venues or seasonal events authored from the `content/venues/` resources.
- [ ] Real voice/dialogue audio; ambience, cues and radio crackle are procedural.
- [ ] Swap the primitive prop builder for an image-to-mesh model API behind the same
`assets/models/generated/<prop>.glb` contract.
- [ ] Rare easter eggs/cameos (e.g. Bob Dobbs) only after core content and QA are stable.
## Gaussian splatting evaluation (deferred)
Postponed for further development on 2026-11-03. The local-map track ships the facade kit and
@@ -1098,3 +754,410 @@ reference-image licence and privacy gates above rather than replacing them.
- [ ] Exit: one licensed photo capture measurably improves a venue through a documented path and
passes visual, performance and provenance review; or the approach is rejected with
reproducible findings and removed from the release path.
## Milestone 0.9.9 — Quaternius NPC base swap (patch)
Goal: make one Quaternius-derived NPC render and animate correctly in Godot and ship it as the
pilot base, with the procedural library still selectable as the fallback. This is the first
versioned character milestone; it contains the rig correction that has been blocking the
ADR-0018 rollout.
**Why this is a patch:** it changes character presentation and animation quality but adds no new
player-facing system. The 0.10.0 minor is reserved for the release gates (see below), so a
blocked rig can no longer block the whole release.
### Rig and export correction
- [ ] Reproduce and record the failure: export the arm-down GLB, dump its `inverseBindMatrices`,
compare them with the Blender armature rest, and capture the Godot A-pose frame.
- [ ] Fix the arm-down bake so the exported skin matches the rest. Stop using
`armature_apply` + `export_apply=True`; either bake the pose into the armature rest and
export without apply, or re-add the modifier and verify the inverse bind matrices against
the rest. Do not ship a hybrid or hand-patched GLB.
- [ ] Re-derive the pose composition for a non-180° rest. Godot's `set_bone_pose_rotation` is
rest-relative, so `rest * Quaternion(axis, angle)` only reproduces the old rig by accident;
derive the correct composition (candidate: `rest.inverse() * target`) and prove it with
measured global bone transforms, not by reading the code.
- [ ] Add regression tests: a bone with a ~76° rest reaches a known global orientation; the
Quaternius joint map resolves; the 13-core fallback poses exactly as it does today.
- [ ] Verify Idle and Walk on the 62-joint rig: loop seam, foot contact, root motion and frame
rate. Record which of the 24 clips are in scope and which stay unused.
- [ ] Decide and record how poses the clips do not cover (seated, raise-hand, head turn) are
driven at runtime.
- [ ] Keep the fallback tested: `npc_base`, the MakeHuman head and `_build_body()` remain
selectable; no MPFB work is reopened and no Stage-1 proportion warp returns.
### Silhouette and face gate (owner)
- [ ] Re-run the silhouette gate at gameplay distance and in portrait against the current
`npc_casual`, front / three-quarter / profile. This is a new gate: ADR-0018 removed the
proportion warp, so source proportions are now accepted by definition.
- [ ] Face-fidelity comparison. The Quaternius head is low-poly (≈6.2k tris for the whole body);
the 0.9.7 library has a sculpted realistic face. Capture both heads and let the owner pick:
(a) full swap, (b) Quaternius for crowd roles with the procedural library for named roles,
or (c) add head subdivision/hair cards to the Quaternius head.
- [ ] Apply the chosen face path within 24,000 tris / 24,000 glTF vertices and re-run the gate.
- [ ] Record the decision and its consequence in `MEMORY.md`, `docs/npc-model-sourcing.md` and
(if it changes the contract) a new ADR. Do not silently lower character fidelity.
### Pilot rollout
- [ ] Map the five tint slots onto the Quaternius materials; unwrap per slot; bake 256²
AO/albedo/normal/ORM and check texel density.
- [ ] Re-fit gear attach points against the Quaternius skeleton and test cap, helmet, backpack,
shoulder bag, lanyard, clipboard and firefighter tank.
- [ ] Wire the approved base into one role (or the crowd roles if option b is chosen) with the
procedural model as an instant fallback; no runtime download or optional dependency.
- [ ] Run `blender_assets.py inspect`/`audit`/`fit`, `npc_proportions.py`, the 24-NPC budget smoke
and the capture gate; record the measurements before/after.
- [ ] Release `0.9.9`: update the version source in `project.godot` (`config/version`), write the
`CHANGELOG.md` entry, run `tools/build_releases.sh`, verify checksums, commit, tag and push.
**Exit:** one committed Quaternius GLB renders arm-down with correct skinning, plays Idle and
Walk on the 62-joint rig, poses correctly under the new composition, passes the owner face and
silhouette gate, fits the 18 gear pieces, stays inside budget, and ships as `0.9.9` with the
procedural library still available as a fallback.
## Milestone 0.9.10 — NPC roster rollout (patch)
Goal: extend the approved base to the full 12-role roster in asset-family batches, without
regressing gear fit, budget or readability.
### Roster build
- [ ] Map the 12 roles to Quaternius outfits/parts; mark the roles that need the 21-part modular
builder instead of the three full GLBs, and the roles that keep a procedural look under the
0.9.9 option-b decision.
- [ ] Build one asset family per commit, AO-baked and re-imported; never run a no-op full-library
rebuild. Use the concept + vision-judge loop for head/outfit decisions and record model,
prompt and spend.
- [ ] Keep every variant inside 24,000 tris / 24,000 glTF vertices and the five tint slots; no
new bone beyond the accepted 62-joint set without an ADR.
- [ ] Refresh `CHARACTERS`, the manifest roles/tint data, `CREDITS.md` and the review doc rows as
each family lands.
### Gates and rollout
- [ ] Re-bake AO per rebuilt GLB and refresh the stale `.godot` import cache (scratch-copy
import) before judging any face or body change.
- [ ] Run `inspect`/`audit`/`fit`/`texels` and `npc_proportions.py report`; record the
12-variant measurement table.
- [ ] Capture the 12 × 6 baseline and get owner approval before replacing the committed GLBs.
- [ ] Re-run the 24-NPC budget smoke and the Web/Compatibility capture; record frame time,
mesh/triangle counts and Web load before/after.
- [ ] Retire the procedural variants that are no longer used, keeping one tested fallback; update
`docs/development-status.md`, `docs/3d-model-review.md`, `docs/blender-previews` sheets and
the README character row.
- [ ] Release `0.9.10` with the full procedure (version, changelog, local build, checksums, tag).
**Exit:** all 12 roles use the approved base or an explicitly kept fallback, every variant passes
the contract and gear gates, the 24-NPC and Web budgets are measured and documented, and the
baseline sheet is owner-approved.
## Milestone 0.9.11 — Venue, prop and lighting polish (patch)
Goal: close the scheduled subset of the unversioned 3D review backlog. Only ranked P1/P2 items
whose fix is visible at gameplay distance are in scope; the review doc stays the evidence and
scorecard source, this milestone is the actionable list.
### Props, gear and foliage
- [ ] Rebuild the ranked prop candidates from §D: the foliage-language P1
(`planter_box`/`round_planter` foliage, `street_tree`/`palm_tree`), plus the
`newspaper_box` slot and `bollard` collar if the budget allows.
- [ ] Replace the flat `_shrub()`/`_tree()` clumps with carded clusters and keep the 60k
library triangle budget; measure before/after.
- [ ] Review the 18 gear pieces for silhouette and strap/buckle readability and rebuild only what
fails; re-run `fit` after every change.
- [ ] Verify prop colliders and navigation obstacles against the final silhouettes.
### Venue, lighting and set dressing
- [ ] Joke Shop / Hollywood shape language: fix the ranked remaining items (west rounded corner,
canopy pitch, facade reveal depth) only where a capture shows a readable gain.
- [ ] `lighting`/`lookdev` pass: flashlight cone/energy for the `06-night-flashlight` stage,
marquee/event-banner emissive read under the Compatibility renderer, street-lamp pools.
- [ ] Set dressing: fix the Joke Shop queue story (podium/stanchion line at the door), rope
barrier thickness, the west palm overlap and the empty sidewalk light pool; apply the same
review to Hollywood and the TV Studio.
- [ ] Build one real-photo comparison for street furniture and record the accepted mismatches.
### Evidence and release
- [ ] Refresh `sheet_props.jpg`, `sheet_npc_gear.jpg`, the three-up boards, the affected venue
captures and the README asset rows.
- [ ] Re-run `tools/check_screenshots.sh` and `python3 tools/check_docs.py`; record both results.
- [ ] Release `0.9.11` with the full procedure.
**Exit:** every scheduled P1/P2 item is fixed or explicitly accepted with a measurement, the
capture gallery and asset sheets are current, and no unreviewed asset remains in the shipped
catalogue.
## Milestone 0.9.12 — Performance, Web and accessibility (patch)
Goal: prove the new character and venue content still meets the frame, memory, load and
accessibility targets on every target before the minor release.
### Performance and platform
- [ ] Profile the 24-NPC budget scene on Compatibility/Web and Desktop HQ; record frame time,
draw calls, texture memory and pck size against the pre-character baselines.
- [ ] Verify LOD/impostor thresholds, the 60k library and 150k/700 venue budgets, and the Web
load time after the character and texture changes.
- [ ] Confirm the Compatibility/Web build still avoids compute shaders and Vulkan-only features;
spot-check the HQ fallback message.
- [ ] Re-run the save/session regression suite on an isolated user-data directory after the
content changes.
### Accessibility and localization readiness
- [ ] Verify font scaling at maximum, the longest strings, caption coverage, reduced motion,
colour-independent escalation cues and the hold-to-confirm emergency path.
- [ ] Run the string catalogue through a pseudo-locale/length check; move remaining hardcoded UI
strings into `content/strings.en.json`.
- [ ] Fix only the issues the checks expose; new accessibility features are 0.11.0 scope.
### Release
- [ ] Regenerate the full capture gallery and the screen-design judge from the current build;
record model, spend and verdict.
- [ ] Release `0.9.12` with the full procedure.
**Exit:** the character and venue changes do not regress frame time, memory, Web load,
save/session reliability or accessibility behaviour, and both automated gates are green.
## Milestone 0.10.0 — Public-readiness release (minor)
Goal: ship the new characters, the polished venues and the public-readiness gates as the
**0.10.0 minor**, after the patch milestones above have landed. Content is frozen at 0.9.12;
only release-blocking fixes and balance changes may land here.
### External playtest and onboarding
- [ ] Run at least five first-time-player sessions covering the tutorial and one full venue
shift; record where players get stuck, misread evidence or over-escalate.
- [ ] Triage by severity and fix every P0/P1 onboarding, evidence or accessibility issue; record
the rest as known limitations or post-0.10 work.
- [ ] Re-run the tutorial/campaign smokes after each fix and capture a first-hour walkthrough.
### Balance and fairness
- [ ] Run the scripted venue sweeps across easy/normal/hard and all four phases using the
`docs/release-qa.md#balance-acceptance` targets; tune event weights, reaction tables,
compliance and report strictness where targets fail.
- [ ] Review emergency calls against independent behaviour labels, not `_read_npc_truth()` as its
own oracle; no routine behaviour may make emergency the dominant winning move.
- [ ] Verify reputation grades, debrief text and campaign progression still teach
de-escalation-first after tuning; record the evidence and deliberate exceptions.
### Legal, signing and storefront
- [ ] Resolve the macOS signing/notarization decision and record the quarantine instructions.
- [ ] Clear or explicitly block on AI-provider commercial rights, storefront/rating approval and
the privacy/mental-health representation review.
- [ ] Confirm every shipped image, texture, character and audio asset has provenance and credits.
### Platform and release engineering
- [ ] Smoke-test the target matrix: Linux portable/AppImage, Windows portable/installer, macOS
unzip/launch, Web static hosting and the Desktop HQ Vulkan fallback.
- [ ] Run `tools/build_releases.sh` from a clean checkout, verify artifact names, sizes, checksums
and download links, and do a `PUBLISH_DRY_RUN`.
- [ ] Run the complete headless suite, Python tooling tests, tutorial/campaign/session/scenario
smokes and the 24-NPC budget smoke.
- [ ] Confirm no P0/P1 defects remain; document P2 items as known limitations.
### Documentation and visual sign-off
- [ ] Update `README.md`, `PLAN.md`, `docs/architecture.md`, the ADRs, `docs/development-status.md`,
`docs/getting-started.md`, `docs/release-qa.md`, `CHANGELOG.md` and this roadmap.
- [ ] Regenerate the gallery and realism baselines from the release-candidate build, not the dev
tree; verify every README/docs image resolves from the tagged build.
- [ ] Run the manual smoke checklist on every target and link the evidence.
- [ ] Release `0.10.0`: version, changelog, clean build, checksums, tag, push and post-release
record.
**Exit:** 0.10.0 is content-locked, externally played, legally reviewed, documented,
reproducibly built and approved for public download.
## Milestone 0.10.1 — Onboarding and accessibility fixes (patch)
- [ ] Fix the onboarding, tutorial and evidence-reading issues deferred from the 0.10.0 playtests
that are cheap and non-structural.
- [ ] Fix accessibility issues found at maximum font scale, in captions or in the colour-blind
cue set.
- [ ] Re-run the manual smoke checklist on the affected paths and release `0.10.1`.
**Exit:** first-hour comprehension and accessibility defects from the 0.10.0 evidence are closed.
## Milestone 0.10.2 — Balance and fairness follow-up (patch)
- [ ] Re-run the venue sweeps against the 0.10.0 targets and tune the remaining failing cells.
- [ ] Review shift-review explanations, reputation grades and campaign difficulty progression.
- [ ] Record the balance evidence and release `0.10.2`.
**Exit:** every balance-acceptance cell is inside target or explicitly accepted with a reason.
## Milestone 0.10.3 — Stability and quality-of-life (patch)
- [ ] Fix save/checkpoint edge cases, UI focus traps, gamepad remapping and pause/resume defects
reported after 0.10.0.
- [ ] Add the small quality-of-life items that need no new system (default focus, key hints,
settings persistence).
- [ ] Release `0.10.3` with the full procedure.
**Exit:** no known P1 stability defect remains before the 0.11.0 feature work starts.
## Milestone 0.11.0 — Systems and content depth (minor)
Goal: add the first post-1.0-track feature set on top of a stable 0.10.x line: a live incident
replay, a fourth venue and the localization foundation.
### Live body-camera replay
- [ ] Replace the text-only incident timeline with a replay of recorded positions, actions and
timestamps; define the recording format, memory cap and deterministic playback.
- [ ] Keep the replay review-only (no new escalation mechanics) and verify it on Compatibility/Web.
- [ ] Add a skip path and a captioned summary so replay is never a hard gate on the shift review.
### Fourth venue
- [ ] Evaluate and select the fourth real-site venue (candidate: the TCL Chinese Theatre
forecourt at 6925 Hollywood Blvd) in an ADR covering layout, access policy, gameplay
distinctness and asset budget.
- [ ] Build the venue under `content/venues/` with licensed reference, sidecar provenance and the
three-up board; enter it from venue selection and the campaign.
- [ ] Add venue-specific events, access artifacts and escalation cases; extend the balance matrix
to the new cells.
### Localization foundation
- [ ] Extract every remaining hardcoded string into the JSON catalogue and make the pseudo-locale
length check a CI gate.
- [ ] Add one full secondary language (text, layout, font coverage) with the translation workflow
documented; no machine-translated release without review.
- [ ] Verify layout at maximum font scale in both languages.
### Release
- [ ] Re-run the capture gallery, screen-design judge, budget and platform smokes for the new
content; release `0.11.0` with the full procedure.
**Exit:** the replay, the fourth venue and one secondary language ship without regressing the
0.10.x performance, accessibility or balance baselines.
## Milestone 0.11.1 — Replay and venue fixes (patch)
- [ ] Fix the replay, new-venue and localization defects found in wider play.
- [ ] Re-run the new venue's balance cells and the replay capture gate; release `0.11.1`.
**Exit:** no P1 defect remains in the 0.11.0 feature set.
## Milestone 0.11.2 — Content and balance polish (patch)
- [ ] Tune the new venue events and the campaign pacing; fix the remaining content readability
issues.
- [ ] Refresh the affected captures, boards and asset rows; release `0.11.2`.
**Exit:** the 0.11.x line is stable enough to freeze its contracts.
## Milestone 0.12.0 — Platform and distribution (minor)
Goal: make the game distributable on the launch platforms with signed builds, a frozen save
contract and complete localization.
### Signing and storefronts
- [ ] Sign and notarize the macOS build; record the exact commands and certificate handling.
- [ ] Produce the storefront packages and metadata (rating, privacy, credits, screenshots) for the
chosen stores; complete the AI-provenance and commercial-rights review.
- [ ] Add the storefront-facing extras that are in scope (achievements, cloud-save decision,
controller/Steam Deck verification) behind explicit feature flags.
### Contracts and hardware
- [ ] Freeze the save/checkpoint format as version 2 with export/import and forward-migration
tests; document the compatibility promise.
- [ ] Verify the target-hardware matrix (minimum GPU, Steam Deck, Web browsers, integrated
graphics) and publish the measured results.
- [ ] Finish the launch languages and the accessibility statement for the shipped feature set.
### Release
- [ ] Release `0.12.0` with the full procedure and the storefront artifacts.
**Exit:** signed, storefront-ready builds exist for every launch platform with a frozen save
contract, complete localization and measured hardware support.
## Milestone 0.12.1 — Distribution fixes (patch)
- [ ] Fix signing, installer, storefront-metadata and save-migration defects found in the
storefront dry runs; release `0.12.1`.
**Exit:** every storefront build installs, launches and migrates saves cleanly.
## Milestone 0.13.0 — Content complete (minor)
Goal: finish the planned content and lock it for the 1.0.0 release candidate.
### Content and presentation
- [ ] Finalise all planned venues, events, dialogue and access artifacts; close the content
backlog with an explicit accept list.
- [ ] Complete recorded audio (VO and music) if the 0.11.0 audio decision funded it; otherwise
record the accepted procedural-only direction.
- [ ] Finalise the tutorial and first-hour flow against the playtest evidence.
### Release candidate preparation
- [ ] Run a full accessibility audit against the shipped features and fix the remaining issues.
- [ ] Run the balance acceptance protocol one final time and freeze the tuning.
- [ ] Declare content and feature freeze; only release-blocking fixes may land after this point.
- [ ] Release `0.13.0` as the content-complete milestone.
**Exit:** all planned content is implemented and frozen, and no known P0/P1 feature gap remains.
## Milestone 0.13.1 — Release candidate 1 (patch)
- [ ] Build release candidates on every platform from a clean worktree; run the complete smoke
matrix, save migration, performance and accessibility checks.
- [ ] Fix release-blocking defects only; release `0.13.1`.
**Exit:** a release candidate exists that passes every gate except final legal/storefront
approval.
## Milestone 0.13.2 — Release candidate 2 (patch)
- [ ] Verify the 0.13.1 fixes on the target matrix and re-run the full gallery and judge.
- [ ] Freeze the release notes, credits, privacy and known-limitations documents; release
`0.13.2` as the final candidate.
**Exit:** the candidate is build-reproducible, documented and awaiting only the final 1.0.0
release decision.
## Milestone 1.0.0 — Release (major)
Goal: publish the first stable release with a documented compatibility promise.
- [ ] Confirm legal, privacy, rating and storefront approval is complete in writing.
- [ ] Confirm the hardware matrix, accessibility audit and localization sign-off are complete.
- [ ] Confirm no P0/P1 defects remain and every P2 is a documented known limitation.
- [ ] Update `README.md`, `PLAN.md`, `docs/development-status.md`, `CHANGELOG.md`, `CREDITS.md`,
`PRIVACY.md` and the release notes for 1.0.0.
- [ ] Run the full release procedure: version 1.0.0, changelog, clean build, checksum
verification, tag, push and publish.
- [ ] Record the post-release state in `MEMORY.md` and open the 1.0.x maintenance list.
**Exit:** 1.0.0 is published on every launch platform with complete documentation, verified
checksums and no open release blocker.
## Future / deferred (not scheduled)
- [ ] Seasonal events or a fifth venue after the 0.11.0 fourth venue proves the venue pipeline.
- [ ] Real voice/dialogue audio if the 0.13.0 audio decision does not fund it; ambience, cues and
radio crackle stay procedural until then.
- [ ] Swap the primitive prop builder for an image-to-mesh model API behind the same
`assets/models/generated/<prop>.glb` contract.
- [ ] Rare easter eggs/cameos (e.g. Bob Dobbs) only after core content and QA are stable.
- [ ] A second Chinese Theatre/forecourt style venue if the fourth venue is not enough.