46 KiB
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.
Priority order: 3D model re-evaluation → character development → local map development →
versioned release milestones (0.10.0) → future/deferred work. See AGENTS.md §Priority and
Versioning and §Local Blender skills.
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.
3D model re-evaluation
Goal: re-judge every shipped 3D asset against the newly available Blender skill guidance, rank
the real gaps, and fix only what the rankings justify. This is an unversioned development track:
it must not change the npc_base contract, the renderer or the 0.10.0 release candidate.
Scope: 8 library characters (npc_casual, npc_jacket, npc_coat, npc_vest, npc_dress,
npc_hoodie, npc_firefighter, npc_guard), the frozen npc_base fallback, 18 gear pieces,
20 library props, 6 generated props, and the three venue families.
Exit: docs/3d-model-review.md scores every catalogue asset; every P0/P1 is fixed or
explicitly accepted with a measurement; inspect/audit/fit/proportions, the 24-NPC budget
and the capture gates are green; no runtime contract, dependency or release artifact changed
except the rebuilt assets themselves.
A. Baseline, scorecard and routing
- Load
blender-directorplus the per-family specialists before touching geometry, and record the skill stack and the advice that changed a decision indocs/3d-model-review.md. (Routing, QA severity/verdict, texel-density tiers, character loop criteria and budget rules recorded in the review doc; MCP-only steps translated to headless flatpak runs.) - Re-run the neutral NPC baseline (48 frames), the final-context review (96 frames), the
prop gallery and the 24-NPC budget on the current build; keep raw frames in
tmp/and do not replace committed sheets until a fix lands. (48/48 and 96/96 frames captured underxvfb-run, none blank; raw sets intmp/model-baselineandtmp/model-review; committed sheets untouched. 24-NPC smoke still 6.94 ms / 168 meshes / 131,616 triangles.) - Create
docs/3d-model-review.mdwith a per-asset scorecard: silhouette, anatomy/proportion, topology/edge flow, UV/texel density, textures/materials, rig/weights, LOD/impostor, collision/grounding, export contract, provenance, skill route, verdict (P0/P1/P2/accept). (Doc created with character/gear/prop/venue tables, verdict columns and a ranked candidate list; unmeasured cells are marked—instead of being guessed.) - Collect the baseline measurements in one table:
blender_assets.py inspect,audit,fit,npc_proportions.py, texel density, triangles/meshes, 24-NPC frame time. (All seven captured;texelsandinspect --json --outwere added to make the measurements repeatable. All 46 assets audit/inspect clean; texel density 64–122 px/m authored, 287–440 effective fabric.) - Review the scorecard with the project owner, rank the P0/P1 gaps and decide fix vs accept per item; record the decision and the reason in the review document.
B. Character re-evaluation (8 variants + fallback)
Skill route: character-artist, retopology, rigging, uv-workflow, texture-workflow,
materials, hair-groom, asset-optimization, lookdev, qa-review.
- Face/head: review eye/mouth loops, cheek/brow/chin transitions and faceting at the 2 m
portrait distance against
character-artistandretopology; write the concrete edits. - Hands/grip: re-check palm, finger segments, thumb and gear contact; decide between a
finger-curl rig or the current open hand plus
HAND_ITEM_FORWARD, and record the limit. - Weights/pose: capture idle, walk, sit and wave; inspect shoulder, hip and neck collapse;
fix the worst offenders using
riggingpractice without changing the 13-bone contract. Blocked: the newcapture_npc_pose.gdreports the seated/walking pose while the saved frames still show the rest pose; direct bone writes deform the mesh, so this is a staging/ capture discrepancy that may also affect live venue frames. Seedocs/3d-model-review.md§"Pose evidence is blocked". - Rebuild the pose harness from the verified recipe. Established: the pose reaches proxies
and bones (headless test, 273/273), direct bone rotations deform the mesh, and both window
probes and a
SubViewport+RenderingServer.force_draw()probe render the crouch (offscreen diff 602 at +2/+6/+12 frames, including a re-created avatar). The current harness still saves rest frames, so its phase/camera/force-draw ordering is the remaining defect. Rebuild one pose at a time using the recipe indocs/3d-model-review.md, verify each pose visually, then wire the sheets and fill the weights/pose column. - UV/texel density: measure the 256² slot maps; decide whether atlas, UDIM or a resolution
change is justified. Do not change
CHAR_MAX_TRIS/CHAR_MAX_VERTSwithout re-running the budget smoke and the Web/Compatibility path. - Cloth and hair: re-check coat/dress hem clipping and the hair/beard/headgear meshes against
hair-groomguidance; decide explicitly whether cloth simulation stays out of scope. - Fix only the ranked P0/P1s, one asset family per commit; refresh the comparison sheet and
re-run
inspect,audit,fitandnpc_proportions.pyafter each fix. qa-reviewsign-off: a ship/no-ship verdict per variant with accepted limits recorded.
C. Gear and prop re-evaluation
Skill route: prop-artist, hard-surface, vegetation-artist, materials, collision-proxy,
lod-pipeline, qa-review.
- Gear: review the 18 pieces for silhouette, straps/buckles, helmet and lanyard readability;
verify attach space and body clearance with
fit; rebuild only what fails the scorecard. - Props: review the 20 library props plus the 6 generated props for bevels, chamfers,
silhouette, ground contact and shared material language (
prop-artist,hard-surface); list the rebuilds that are actually worth the triangle budget. - Foliage: replace the flat-shaded
_shrub()/_tree()clumps withvegetation-artist-style carded clusters; measure triangles and keep the 60kLIBRARY_TRIANGLE_BUDGET. - Materials and emissives:
lookdevpass on bulbs, signs, lanterns, the marquee and the sedan at day and late; confirm the flashlight stays a tight spot with no beam geometry. - Collision: verify every prop collider and navigation obstacle matches its silhouette and
add the missing
collision-proxyshapes where walking is blocked. - Exit: a prop/gear capture sheet, budgets and collision checks pass with no unreviewed asset.
D. Venue and camera re-evaluation
Skill route: environment-artist, archviz, set-dressing, lighting, camera-cinematography,
lookdev, rendering, qa-review.
- Facade/venue review: rank the top five shape-language fixes for Hollywood, the Joke Shop and
the TV Studio (
environment-artist,archviz) and check them against the map-budget tests. - Lighting:
lighting/lookdevpass on sconces, canopy, marquee and street lamps with day/late captures; verify local attenuation stays at 1.0 and no constant-falloff light returns. - Set dressing: review entrance and sidewalk prop clusters (
set-dressing) for occlusion, navigation obstacles and readable storytelling clusters. - Camera height: decide 1.7 m gameplay framing vs the ~1.55 m concept frames using
camera-cinematography, and record the decision instead of leaving the mismatch open. - Hooded/winter portrait: close the deferred close-up by staging a types 5–7 capture
(
--portrait-type) or adding a scenario spawn that provides one.
E. Gates and documentation
- Add the measurable checks the review needs (texel density, weight/pose sanity, collider
coverage, LOD/impostor check) as stdlib or GDScript gates where possible; CI stays offline.
(Texel-density gate in
tools/test_blender_assets.pychecks all five slots per character and the 40–400 px/m authored band plus the 250 px/m fabric floor; the pose→bone contract is covered bytest_pose_reaches_the_skeleton_bones; LOD/impostor already hastest_avatar_mesh_budget_and_lod_swap. Collider coverage is still open — split below.) - Add a collider/proxy check: every library prop that blocks walking has a
StaticBody3D+NavigationObstacle3D, checked against the catalogue. (world_builder.gdtags every library node with alibrary_propmeta and declares the non-blockingmarquee/handrail/lantern/doorset; two tests intest_world.gdverify placed props (body + shape + avoidance radius, all three venues) and library dressing (body unless documented exempt). Mutation-checked: removing_add_prop_collisionfails 3 tests, droppinghandrailfrom the exemption list fails with the exact node. Suite is 275/275.) - Add a coverage test so every catalogue asset has a scorecard row and verdict.
(
tools/test_model_review.py: everyCHARACTERS/GEAR/PROPSentry needs a row indocs/3d-model-review.md, and character rows need a non-empty verdict.) - Update
docs/blender-assets.md,docs/npc-visual-review.md,docs/3d-model-review.md,docs/architecture.mdandAGENTS.mdwith the skill routes and the new gates. - Record accepted limits and deferred rebuilds in
docs/known-limitations.mdandMEMORY.md.
Character development
Goal: break the eight-character clone effect with four licence-cleared crowd-variety looks while
keeping the frozen npc_base bone, tint-slot and gear-attach contract. The procedural generator is
the primary path; Quaternius is a reviewed reference and MakeHuman is deferred to a separate local
development pipeline.
The roster build is deliberately sequenced after the 3D model re-evaluation: the new variants must inherit the reviewed face/hand/gear baseline instead of multiplying whatever it finds.
Skill route: character-artist, retopology, rigging, uv-workflow, materials,
asset-optimization, lowpoly-style, godot-export, qa-review.
Source review and decision
- Research free/open-source character sources and evaluate at least three downloads against
the existing Blender contract. (Measured Quaternius CC0, Kenney CC0, Khronos
CesiumMan/RiggedFigure CC-BY and the MakeHuman CC0 base mesh; none is a drop-in.
Results, local preview sheet and SHA-256 provenance are in
docs/npc-model-sourcing.md.) - Review the sourcing research with the project owner and choose Option A (procedural),
Option B (Quaternius CC0 intake) or Option C (MakeHuman/MPFB body pipeline); record the
decision in an ADR and in
MEMORY.md. (2026-11-03: extend the procedural generator as the primary path, keep Quaternius as a reviewed prototype/reference, defer MakeHuman to a separate local pipeline. Recorded in ADR-0015 andMEMORY.md.) - Add a source licence allow-list and provenance rule: CC0 preferred, CC-BY only with
attribution in
CREDITS.md, and no service assets whose terms restrict redistribution. (ADR-0015; the CC-BY research previews are attributed inCREDITS.md.) - Decide whether the external preview sheet stays local under
tmp/or is committed with the required CC-BY attribution. (Committed asdocs/blender_previews/sheet_npc_sources_research.jpgwith Cesium CC-BY attribution; the project-owned crowd prototype sheet is also committed.)
Intake and validation
- Add a Blender
inspectpath that imports a GLB, applies node transforms, reports tris/verts, bounds, bones, materials, UVs and skinning, and lists contract failures. (blender_assets.py inspect --file ...applies parent/object transforms, converts to Godot Y-up, ignores the importer's bone-shape helper and prints budgets, bones, slots, UVs, skinning and animations with issues/warnings;--jsonand--categorysupported. Seven synthetic contract tests added; all 46 library GLBs inspect clean.auditremains the final gate.) - Add an
adaptpath for future external assets: scale/ground, weld seams, decimate, map the five tint slots, and either rebuild the contract armature or record an explicit second-rig contract. Useretopology/rigging/uv-workflowguidance for the manual steps, but keep the Quaternius no-go: a contract rebuild needs a proportion warp, so this is not on the character critical path. - Keep
tools/blender_assets.py auditas the single final gate; add a regression test for the intake report/adaptation using a deterministic synthetic or licence-cleared fixture. - Document the adapter commands and the go/no-go checks in
docs/asset-tooling.md.
Quaternius prototype
- Prototype one Quaternius CC0 variant: weld/decimate to budget and capture Idle/Walk
renders. (12,518 imported verts -> 3,199 after weld -> 2,423 / 4,654 tris after a 0.75
decimate; Idle/Walk quality is good. Preview in
docs/blender_previews/sheet_npc_sources_research.jpg.) - Measure the prototype against the
npc_casualcontrols: silhouette, rest pose, body proportions and gear fit. (No-go for a contract rebuild: T-pose 62-bone realistic rig, ~0.96 m hip, ~1.68 m arm span and ~0.153 m shoulder joint do not match the arm-down 13-bone contract. Keep as reference; a second rig/animation path needs its own ADR.) - Make a go/no-go decision on Option B. (No-go for the current pass; proceed with the procedural generator and keep Quaternius as a visual/style reference.)
Roster and runtime
- Approve four crowd-variety looks (build, head silhouette, hair/beard, outer layer and
accessory; no clothing that labels the NPC's behaviour). (
npc_crowd_abun/slim/sunglasses,npc_crowd_bbald/broad/beard/shoulder bag,npc_crowd_ccoat/umbrella,npc_crowd_dhood/cup; prototype sheet committed.) - Re-derive the four approved specs against the re-evaluated character baseline (face, hands, proportions, gear offsets) so the new variants do not reintroduce the gaps the review found.
- Add the four approved specs to
CHARACTERS, build and commit their GLBs/AO maps, and update the manifest with roles and tint data. Build only the new assets, never a no-op full rebuild, and remember thatexport_filter="all_resources"packs committed GLBs into the next release build: keep this offmainuntil after the 0.10.0 tag or accept the size. - Replace the fixed
character_model_for()mapping with deterministic per-role pools and add tests for repeatability and duplicate avoidance (godot-exportcontract check included). - Rebuild and verify gear fit for every new variant (
blender_assets.py fitplus the runtime gear checks) and re-runinspecton the four new GLBs.
QA and release
- Run the 24-NPC budget smoke, portrait baseline, gear fit, headless suite and a release build with the expanded library.
- Update
CREDITS.md,docs/development-status.md,docs/npc-visual-review.mdandCHANGELOG.md; record any accepted visual limits. - Exit: a reviewed 12-character library passes contract audit, portrait/gear acceptance, the 24-NPC budget and licence/provenance review without changing the runtime contract.
Deferred MakeHuman local pipeline
- Evaluate the MakeHuman CC0 base mesh for a later separate local development pipeline. (19,158 verts / 36,972 tris; scaled to 1.82 m; decimate 0.35 -> 3,780 verts / 6,468 tris; UVs present, no normals/material groups/rig. Feasible only with retopology, a custom rig and project-owned clothing; keep out of CI/build.)
- Decide whether body-shape diversity still matters after the 12-character library lands; if yes, prototype the local MPFB/MakeHuman pipeline outside the repo and commit only the final CC0-derived assets with provenance.
Local map development
Goal: build a local, data-backed map pipeline that can replace or supplement the stylized venue geometry with licensed OpenStreetMap footprints, 3D building massing, reference-derived photoreal facades and AI-assisted composition. This is an unversioned development track, not a release gate.
Skill route: environment-artist, archviz, hard-surface, geometry-nodes,
procedural-modeling, vegetation-artist, set-dressing, lighting, materials,
texture-workflow, lookdev, scene-assembly, qa-review.
Data, licensing and scope
- Define the first target block and whether the result replaces, supplements or only informs
the current stylized venue specs (
docs/hollywood-boulevard-map.md,docs/joke-shop-map.md). - Audit OpenStreetMap's ODbL attribution/share-alike obligations and decide whether derived geometry ships, stays development-only, or needs a separate data layer.
- Choose an offline OSM extract workflow (Overpass/Geofabrik) and pin the extract date and query so the map build is reproducible.
- Evaluate licence-compatible 3D building datasets (OSM Buildings, Overture, CityGML/LOD1–2 or local authority data); record coverage, accuracy, format and redistribution terms.
- Add a provenance sidecar for every map source and derived asset, including source URL, licence, capture/extract date and attribution text.
Reference imagery
- Write a reference shot list per block: facade materials, windows, signage, rooflines, street furniture, curb cuts and lighting.
- Download and catalogue reference images from Wikimedia Commons, local/own photography or other clearly licensed sources; record author, licence and attribution. Do not use unlicensed Street View or scraped commercial imagery.
- Separate development-only references from shipped textures; commit only images with clear
redistribution rights and keep the rest under
tmp/or the ignored reference folders. - Define the photoreal target and a material-derivation workflow (albedo/normal/roughness,
AO, weathering) that matches the existing Compatibility renderer (
texture-workflow,materials,lookdev).
Geometry and AI-assisted composing
- Prototype OSM footprint import into Blender at game scale and orientation, then compare it against the current venue footprint/collider layout.
- Import 3D building massing for the target block, clean the topology and assign LOD bands;
do not import unbounded city-scale meshes into the runtime (
scene-assembly,asset-optimization,lod-pipeline). - Build a reusable photoreal facade kit (window bays, cornices, storefronts, awnings, signage)
with
environment-artist/hard-surface/geometry-nodesso buildings share materials and stay inside the venue triangle/material budgets. - Add an AI-assisted composition step for palette, facade rhythm and reference boards; record the model, prompt and output, and keep human review as the acceptance gate. AI output must not be treated as licensed map data or shipped without provenance.
- Integrate the result behind
WorldBuilder.VENUE_SPECSwith colliders, navigation obstacles, occlusion and the existing day/night materials.
Gaussian splatting evaluation: photo intake and provenance
Gaussian splatting is evaluated as a photo-driven pipeline: licensed or permissioned photos become a reference, texture source, mesh proxy or distant backdrop. It is an unversioned local track with no runtime dependency or release gate until the ADR closes it, and it extends the reference-image licence and privacy gates above rather than replacing them.
- Define the accepted photo channels: project/team captures, volunteer or user-supplied photos with written permission, and downloaded images from clearly licensed archives (Wikimedia Commons, Openverse, Mapillary and similar). Record which channel produced each reconstruction.
- Write a one-page capture brief for user-supplied photos: overlapping arc or orbit around the facade, 60–80% view overlap, 12 MP+ originals, fixed exposure/white balance, HDR and filters off, no motion blur, no people or plates in frame where avoidable, overcast or even light, and the facade height/doors/steps included in several frames.
- Build an intake checklist and provenance sidecar per photo set: contributor, consent or property permission, licence and attribution text, source URL, capture date, camera/lens, location, faces/plates/interiors present, redactions applied, file hashes and whether the set is shipped or development-only.
- Set the licence gate: own photos need an explicit contributor licence; CC0/CC BY are
preferred; CC BY-SA triggers a share-alike review for derived textures and meshes; reject
Street View, social-media scrapes, unlicensed commercial imagery and AI-upscaled copies of
unknown originals. Attribution must be feasible in
CREDITS.mdbefore use. - Set the privacy gate: blur or remove faces, minors, licence plates, screens, private interiors and anything behind a closed door; obtain property permission where required; keep a redacted copy as the reconstruction input and never commit the originals.
- Treat downloaded photo sets as sparse and of unknown intrinsics. Use them for reference, palette and texture study, or as extra training views; do not expect a usable splat from 10–30 casual web photos of a facade.
- Keep photos, masks, COLMAP databases, checkpoints and splats outside git; commit only derived, licensed, provenance-stamped assets that pass the review gate.
Gaussian splatting: reconstruction and alignment
- Pin a reproducible offline toolchain (for example COLMAP or GLOMAP for camera poses plus gsplat, OpenSplat, Nerfstudio or Brush for training), with exact versions, GPU/VRAM/disk needs and known failure modes recorded in the sidecar.
- Reconstruct two quality tiers: a dense 100–400-photo arc/orbit capture and a sparse 10–30-photo downloaded set. Record camera-registration rate, training time, splat count, file size and held-out PSNR/SSIM/LPIPS for both.
- Mask sky, people, vehicles and moving foliage before training; verify the masks do not erase facade edges, signage or window detail, and keep the redacted input variant.
- Align the splat to game coordinates from the OSM footprint plus surveyed points (door
width, column spacing, step rise, storefront height) and record alignment residuals in a
Blender scene containing both the splat and the current venue geometry (
scene-assembly). - Judge quality from held-out views and a render from the game's day/night camera poses
(
camera-cinematography,lookdev,qa-review), not from training views alone; reject splats that only look correct from the capture path. - Maintain a coverage map per block: which facades, corners and rooflines have usable views, and which areas must fall back to the facade kit or stylized geometry.
Gaussian splatting: map enhancement paths
- Path A — Reference and QA (lowest risk): render the splat from game camera poses and compare it with the realism captures; derive dimensions, signage placement, facade rhythm and material colours. No splat data reaches the runtime.
- Path B — Texture derivation: project splat renders onto the facade kit to produce
albedo, normal, roughness and AO candidates; de-light and bake them (
texture-workflow), then verify UV scale, tiling and readability under the Compatibility renderer. - Path C — Mesh proxy: extract a mesh from the splat or dense reconstruction, retopo and
dress it in Blender (
retopology,prop-artist), assign LODs (lod-pipeline), and keep it inside the venue triangle/material budgets with mesh-based colliders (collision-proxy). - Path D — Distant backdrop: test a baked panorama, impostor or billboard generated from the splat for skyline and opposite-street depth where the player cannot walk; measure file size, loading and visible pop at the venue boundary.
- Path E — User-photo supplement: let a small supplied photo set improve one facade or landmark (a signage patch, colour reference or hero detail) without rebuilding the venue; define the minimum evidence and the same licence/privacy/review gate as a full capture.
- For every path record quality gain versus effort, licence compatibility of the derived output, and whether the result may ship or stays development-only. Prefer the cheapest path that closes the visible gap.
Gaussian splatting: runtime evaluation and decision
- Probe Godot 4.7.2 Compatibility and Web support for splat rendering in a throwaway scene: addon or importer availability, shader/sort cost, memory, load time and fallback behaviour. Do not add a splat dependency to the release project during evaluation.
- Set hard limits before any runtime experiment: maximum per-splat file size and total memory, allowed frame-time delta on the 24-NPC budget scene, acceptable Web load time, and no compute-shader requirement for the Compatibility/Web path.
- Keep collision and navigation mesh-based even if a splat is displayed; a splat must never become the playable floor or the access/occlusion authority.
- Write the ADR with a per-path go/no-go, the accepted licence/provenance rules, whether each result ships or stays development-only, rejected alternatives and the evidence bundle.
- 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.
QA and exit
- Compare the data-backed block against the existing screenshots and map documentation; keep the stylized fallback available.
- Run the venue triangle/mesh budget, navigation and collider checks, plus day/night capture comparisons.
- Update
docs/architecture.md, the venue map documents,docs/asset-tooling.md,docs/development-status.mdandCHANGELOG.mdwhen the pipeline ships or a source is rejected. - Exit: one local block is reconstructed from licensed data with reference-derived photoreal facades, passes performance/navigation/visual QA and has complete provenance; or the pipeline is rejected with the findings recorded.
Maintenance and documentation hygiene
Unversioned housekeeping that keeps the planning sources trustworthy. Do these when they block a task, not on a schedule.
Memory and status accuracy
- Trim
MEMORY.mdfrom ~970 lines to the durable set: drop the pre-0.8 host/disk/NSIS/release anecdotes, superseded v0.2.x handoff status and duplicated release notes, keep the gotchas that still bite (async/event wiring, import order, colliders, RNG, contracts), and keep the easter-egg note. - Re-check the remaining memory claims against code before deleting them;
MAX_LIVE_NPCSis still 16 for gameplay while the separate budget smoke spawns 24, so do not "fix" that. - Fix stale status claims as they are found (the step-collider and flashlight-beam claims were corrected on 2026-11-03); add a documentation check or grep note only if the same class of drift returns.
Blender skills upkeep
- Re-check the installed Blender pack (
version.json) when updating it and record the version inAGENTS.mdif it changes; keep.agents/gitignored and.agents/.gdignorein place. - Prune the skill routes in
AGENTS.mdif a skill stops matching the project (for example if a future second-rig path makesrigging/animationguidance authoritative).
Gap Analysis and 0.x Roadmap
Baseline: v0.9.6 (2026-11-03). Three playable venues, tutorial/campaign/checkpoint resume, difficulty/help, audio/accessibility settings, a 24-NPC budget baseline, a complete escalation/access/radio loop, shift review, the Blender asset library, 272 headless + 108 Python tests, a 21/21 clean screen-design judge and an optional Forward+ Desktop HQ build. This is the baseline; 0.10.0-rc.1 is the current candidate source, with release approvals still open.
Documentation audit (completed 2026-11-01)
- Make
docs/architecture.mdthe single architecture source: asset/content pipeline contracts, runtime venue-switch/fallback flows, deployment/version constraints, quality requirements, risk register and documentation ownership map. - Keep command-heavy operational pages separate but subordinate:
docs/asset-tooling.md,docs/blender-assets.md,docs/getting-started.md,docs/RELEASING.mdanddocs/smoke-checklist.mdlink to architecture rather than acting as parallel sources. - Remove the obsolete
docs/plan-graphics-v0.6.mdand its links; completed graphics work is represented by ADR-0013, the asset pipeline section and the changelog. - Resolve stale claims: README release version/download row, development status "Forward+ not implemented", and Blender props "not AO-baked".
- Record the documentation ownership rule in
docs/architecture.md§12: design intent (PLAN.md), mechanics (gameplay.md), system architecture/contracts (architecture.md), decisions (ADRs), status (development-status.md), roadmap (TODO.md), operations (tooling/release docs).
Gap register (remaining roadmap)
| Area | Current baseline | Remaining gap | Risk | Milestone |
|---|---|---|---|---|
| 3D model re-evaluation | 8 characters, 18 gear, 20+6 props audited against budgets/proportions; no skill-guided scorecard yet | Scorecard, ranked P0/P1 fixes, texel/weight/collider measurements and accept decisions | Unmeasured drift stays in the shipped library | Unversioned |
| Character development | 8-variant library; source/licence review and Quaternius/MakeHuman evaluation complete | Four crowd variants, role pools, gear fit and runtime integration | Repetition remains or external assets break the contract | Unversioned |
| Local map development | Stylized venue geometry and reference maps | OSM/3D data, photoreal references, AI-assisted composition and splat evaluation | Licensing/provenance or performance failure | Unversioned |
| Content and balance | 3 venues with validated 12+ event matrices, recovery events and contextual dialogue | External playtest evidence, balance/fairness pass, event-weight tuning and final content lock | Repetition or unfair outcomes survive into the release candidate | 0.10.0 |
| Dialog/UI | Audited terminology, copy, button states, focus/navigation, modal close, long strings and all 21 screen captures | Keep the capture/compare/judge gate current as content changes | Low; the remaining risk is drift after new UI is added | Complete (0.9.3) |
| Animation/presentation | Procedural pose layers, portrait captures, reduced hem clipping, 8,000/8,000 NPC cap | Thorough NPC silhouette/face/gear/pose/LOD optimization before visual QA | Close-up jank reduces perceived quality | Complete (0.9.4) |
| Audio/accessibility | Procedural ambience/SFX, volume controls, captions/reduce-motion settings, searchable Help | Full accessibility/localization acceptance review, audio caption coverage and P0/P1 fixes | Public release cannot claim accessible play | 0.10.0 |
| Localization | English JSON table, validation and input-generated Help | Pseudo-locale/layout audit and translator workflow sign-off | Text expansion/clipping at release | 0.10.0 |
| Performance/platform | 24-NPC headless budget (6.94 ms), Compatibility/Web/HQ paths | Target hardware matrix, Web/HQ manual profiling, frame-time/memory evidence | Platform-specific drops or startup failures | 0.9.6 / 0.10.0 |
| Save lifecycle | Settings/campaign/history/checkpoint files, atomic writes | Migration fixtures from 0.8/0.9, fresh-install/upgrade verification, rollback instructions | Player progress loss on upgrade | 0.10.0 |
| QA/CI | Headless suite, smokes, screenshot compare, 21/21 judge | Release-candidate smoke matrix, final gallery and release dry run | Regressions escape the release gate | 0.9.6 / 0.10.0 |
| Release/legal | Unsigned desktop/macOS builds, Web/HQ packages | Signing/notarization decision, checksums, AI-asset provenance, credits, privacy/body-camera and rating review | Public release blocked by trust/policy | 0.10.0 |
| Documentation | Architecture/ADR/status/roadmap ownership established | Final README/changelog/status/TODO/smoke-checklist sign-off and known-limitations page | Docs drift at launch | 0.9.6 / 0.10.0 |
| Future 0.x | Stable 0.x feature set | Live replay, more venues, VO/music, image-to-mesh props and seasonal content | Scope creep before release | Unscheduled |
Current priority: the unversioned 3D model re-evaluation runs first because its findings
gate the crowd-variant roster; Character development and Local map development follow.
The 0.10.0 release candidate is the next versioned release; content lock, external playtest,
balance, save migration and release/legal sign-off remain tracked there. The source version is
0.10.0-rc.1; the v0.9.6 release is published. Earlier map/NPC/UI/texture/integration passes are
complete and in DONE.md.
Milestone 0.10.0 — Release candidate
Goal: freeze the feature set, prove it with external players, clear release/legal blockers and verify every distribution path. This remains the next versioned release after the 0.9.x patch line, but follows the unversioned 3D re-evaluation, character and local-map tracks in planning order. Only a release-blocking defect from those tracks may enter this milestone before the tag.
Content lock and external playtest
- 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.)
- Produce a release-candidate build with the tutorial, campaign, all three venues, Help,
accessibility settings and checkpoint/resume enabled. (Clean worktree
a9658ecbuilt0.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
- Define measurable targets for routine compliance, access-decision accuracy, peaceful
resolution, justified emergency calls and false-positive/false-negative rates.
(
docs/balance-acceptance.mddefines 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.mdorMEMORY.md.
Save migration and session reliability
- 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.) - 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 bysmoke_session_shell.gd.) - 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_jsonnow uses the non-logging JSON instance parser.) - 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.) - Document save locations, schema versions, reset behavior and rollback/export instructions in
docs/getting-started.mdand the release notes. (getting-started.mdnow documents the four files, version-1 checkpoint, atomic write/fallback, clean install, reset and backup/rollback.)
Release engineering and distribution
- Run
tools/build_releases.shfrom a clean checkout and verify Linux/Windows/macOS/Web/HQ artifact names, sizes and checksums. (Clean worktreea9658ecbuilt the five artifacts listed above;PUBLISH_DRY_RUN=1produced and printedbuild/SHA256SUMS-0.10.0-rc.1.txtwithout 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.)
- 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.shchecks artifact size/free space, writes SHA-256 checksums, supportsPUBLISH_DRY_RUN, rolls back uploaded assets/new releases on failure, and offers opt-inRETAIN_RELEASESpruning; dry-run verified.) - 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.shdocuments opt-inRETAIN_RELEASESpruning andRELEASING.mddescribes the seven-release policy.) - 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.mdandknown-limitations.md.)
Legal, credits and platform policy
- Audit AI-assisted asset provenance and licenses; record source/model usage and any
redistribution constraints for textures, characters, props and UI art.
(
CREDITS.mdrecords the Blender/OpenRouter toolchain, default model slugs, missing per-file generation metadata and the commercial-rights review as an explicit release blocker.) - 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.mdrecords this.) - Review body-camera/privacy language, mental-health-crisis representation, age/content rating
and storefront requirements; fix any release-blocking copy or content.
(
PRIVACY.mdclarifies 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.) - Add the player-facing credits, known limitations, accessibility statement and privacy note to
the release package/README. (
README.mdlinksCREDITS.md,PRIVACY.md,docs/accessibility.mdanddocs/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/smoke-checklist.md,CHANGELOG.mdand this roadmap. - Regenerate the full screenshot gallery and realism baselines after content lock; run
check_screenshots.shand the pinned vision judge, recording model/spend/verdicts. - 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.
- Remove or archive stale plans/notes and confirm no contradictory version/status claims remain.
- 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.0version 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.
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/fitand 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>.glbcontract. - Rare easter eggs/cameos (e.g. Bob Dobbs) only after core content and QA are stable.