Compare commits

..
117 Commits
Author SHA1 Message Date
zwitschi 69f4f11633 Date the 0.9.8 release
Full build / Full desktop build + optional release (push) Successful in 13m27s
Full build / Import + headless tests (push) Successful in 1m33s
2026-11-04 12:28:38 +01:00
zwitschi d1fa25629e Bump to 0.9.8 and stage the weights-fix changelog entry
Full build / Import + headless tests (push) Successful in 8m22s
Full build / Full desktop build + optional release (push) Skipped
2026-11-04 12:26:56 +01:00
zwitschi 359bb9a8c7 Fix the hip/thigh collapse and knee pinch: rigid thigh/shin with a short knee blend
Full build / Import + headless tests (push) Successful in 8m52s
Full build / Full desktop build + optional release (push) Skipped
2026-11-04 12:26:23 +01:00
zwitschi 36576a023a Fix the wrist/hand detachment: wrist tracks the hand bone, sleeve cuff follows the hand, hand raised to meet the wrist
Full build / Import + headless tests (push) Successful in 40s
Full build / Full desktop build + optional release (push) Skipped
2026-11-04 12:11:37 +01:00
zwitschi c1ccfd6e72 Review the pose/weight evidence: wrist detachment + hip/knee flexion are the P1 fixes
Full build / Import + headless tests (push) Successful in 55s
Full build / Full desktop build + optional release (push) Skipped
2026-11-04 12:03:42 +01:00
zwitschi 27b8f9a249 Record the MakeHuman final-body swap and its remaining retopology refinement
Full build / Import + headless tests (push) Successful in 54s
Full build / Full desktop build + optional release (push) Skipped
2026-11-04 12:02:40 +01:00
zwitschi d5a2c911a6 Record the 0.9.7 release: QA, clean build, v0.9.7 tag
Full build / Import + headless tests (push) Successful in 41s
Full build / Full desktop build + optional release (push) Skipped
2026-11-04 12:00:44 +01:00
zwitschi 236fbf537f Date the 0.9.7 release
Full build / Import + headless tests (push) Successful in 49s
Full build / Full desktop build + optional release (push) Successful in 5m5s
2026-11-04 12:00:25 +01:00
zwitschi 588722fe7a Refresh the gallery for the 0.9.7 character pass
Full build / Full desktop build + optional release (push) Skipped
Full build / Import + headless tests (push) Successful in 47s
2026-11-04 11:59:03 +01:00
zwitschi 7f2f06bf42 Re-plan releases: 0.9.7 character patch, 0.10.0 for all 3D/map improvements
Full build / Import + headless tests (push) Successful in 1m11s
Full build / Full desktop build + optional release (push) Skipped
2026-11-04 11:53:04 +01:00
zwitschi 6db3cc0873 Plan the finished character development as the 0.10.1 patch; MakeHuman targets 0.11.0
Full build / Import + headless tests (push) Successful in 3m6s
Full build / Full desktop build + optional release (push) Skipped
2026-11-04 11:49:13 +01:00
zwitschi 8938dd918c Taper the arm-scale falloff; record the remaining deltoid retopology gap
Full build / Import + headless tests (push) Successful in 2m14s
Full build / Full desktop build + optional release (push) Skipped
2026-11-04 11:45:12 +01:00
zwitschi 742bfd3898 Paint the five tint slots on the MakeHuman body; record the retarget vision review
Full build / Import + headless tests (push) Successful in 3m23s
Full build / Full desktop build + optional release (push) Skipped
2026-11-04 11:43:50 +01:00
zwitschi 87069a30e8 Retarget the MakeHuman body to the 13-bone contract (arm-down + weights + skinning)
Full build / Full desktop build + optional release (push) Skipped
Full build / Import + headless tests (push) Successful in 1m42s
2026-11-04 11:40:17 +01:00
zwitschi 3f5c5ce442 Prototype the MakeHuman intake: adapt the CC0 body to the character budget
Full build / Import + headless tests (push) Successful in 40s
Full build / Full desktop build + optional release (push) Skipped
2026-11-04 11:30:14 +01:00
zwitschi 28fcd96b59 Add the external-mesh adapt intake command for the MakeHuman pipeline
Full build / Import + headless tests (push) Successful in 46s
Full build / Full desktop build + optional release (push) Skipped
2026-11-04 11:27:43 +01:00
zwitschi e984129597 Fix the pose harness: disable the avatar process so the FSM cannot revert the pose
Full build / Import + headless tests (push) Successful in 46s
Full build / Full desktop build + optional release (push) Skipped
2026-11-04 11:24:35 +01:00
zwitschi 75dea2e7c2 Re-prioritize: Rig harness -> MakeHuman -> 3D re-eval -> 0.11.0; move character development to DONE
Full build / Import + headless tests (push) Successful in 48s
Full build / Full desktop build + optional release (push) Skipped
2026-11-04 11:15:54 +01:00
zwitschi 09d07452af Close the crowd-variety QA and release exit
Full build / Import + headless tests (push) Successful in 49s
Full build / Full desktop build + optional release (push) Skipped
2026-11-04 11:04:17 +01:00
zwitschi f5ee2b7408 Record the crowd-variety roster and the expanded budget in the docs
Full build / Import + headless tests (push) Successful in 55s
Full build / Full desktop build + optional release (push) Skipped
2026-11-04 11:03:55 +01:00
zwitschi 5980d329e8 Close the crowd-variant fit, reference and baseline items
Full build / Full desktop build + optional release (push) Skipped
Full build / Import + headless tests (push) Successful in 47s
2026-11-04 11:03:25 +01:00
zwitschi 6052ea391b Wire the crowd variants into per-role pools and verify every seed resolves
Full build / Import + headless tests (push) Successful in 55s
Full build / Full desktop build + optional release (push) Skipped
2026-11-04 11:03:01 +01:00
zwitschi 4e8665e25b Add the four crowd-variety characters and extend the baseline to twelve
Full build / Full desktop build + optional release (push) Skipped
Full build / Import + headless tests (push) Successful in 42s
2026-11-04 10:57:58 +01:00
zwitschi b945eb6e8f Fetch the licensed crowd-variety reference photos
Full build / Import + headless tests (push) Successful in 40s
Full build / Full desktop build + optional release (push) Skipped
2026-11-04 10:47:44 +01:00
zwitschi 03c13c716a Record the qa-review sign-off: all eight characters ship with notes
Full build / Import + headless tests (push) Successful in 40s
Full build / Full desktop build + optional release (push) Skipped
2026-11-04 10:44:29 +01:00
zwitschi 0a9c78cb30 Give the foliage two green tones and fix the textured_solid import bug
Full build / Full desktop build + optional release (push) Skipped
Full build / Import + headless tests (push) Successful in 42s
2026-11-04 10:40:27 +01:00
zwitschi abe5c3f933 Update development-status: the face pass now covers all eight variants
Full build / Import + headless tests (push) Successful in 47s
Full build / Full desktop build + optional release (push) Skipped
2026-11-04 10:33:20 +01:00
zwitschi 140ab42536 Apply the realistic face to the remaining seven variants and refresh the baseline
Full build / Import + headless tests (push) Successful in 43s
Full build / Full desktop build + optional release (push) Skipped
2026-11-04 10:33:11 +01:00
zwitschi 8bdfd0176e Refresh the NPC baseline sheet and record the face prototype in development status
Full build / Full desktop build + optional release (push) Skipped
Full build / Import + headless tests (push) Successful in 45s
2026-11-04 10:26:14 +01:00
zwitschi 4e23cc3ad5 Prototype a more realistic face on npc_casual (higher subdivision, brow ridge, both lids, fuller lip)
Full build / Import + headless tests (push) Successful in 42s
Full build / Full desktop build + optional release (push) Skipped
2026-11-04 10:24:21 +01:00
zwitschi 8d32a8cac0 Record the map rebuild completion and the fresh NPC review against the new maps
Full build / Import + headless tests (push) Successful in 46s
Full build / Full desktop build + optional release (push) Skipped
2026-11-04 10:03:14 +01:00
zwitschi 2445ddab34 Close the map-track J/L workstreams: procedural approach supersedes the facade kit
Full build / Import + headless tests (push) Successful in 44s
Full build / Full desktop build + optional release (push) Skipped
2026-11-04 10:00:36 +01:00
zwitschi 8cacd510bf Record the rounded-corner simplification and close the local-map QA/exit
Full build / Import + headless tests (push) Successful in 47s
Full build / Full desktop build + optional release (push) Skipped
2026-11-04 09:58:47 +01:00
zwitschi bf383aa0fa Note the Joke Shop facade-height fix in the review doc
Full build / Import + headless tests (push) Successful in 48s
Full build / Full desktop build + optional release (push) Skipped
2026-11-04 09:48:47 +01:00
zwitschi 4bbc576b7f Lower the Joke Shop facade to 6 m so the canopy caps the low hall
Full build / Full desktop build + optional release (push) Skipped
Full build / Import + headless tests (push) Successful in 44s
2026-11-04 09:48:20 +01:00
zwitschi 542b1264da Close the Comedy Store map recreation and document describe_image in asset-tooling
Full build / Import + headless tests (push) Successful in 45s
Full build / Full desktop build + optional release (push) Skipped
2026-11-04 09:42:31 +01:00
zwitschi 56f4833c8e Record the local-map data, licensing and scope decisions (section H)
Full build / Import + headless tests (push) Successful in 47s
Full build / Full desktop build + optional release (push) Skipped
2026-11-04 09:41:46 +01:00
zwitschi 1b31dfdbe4 Add the Ramada Plaza hotel tower mass behind the Joke Shop west neighbour
Full build / Import + headless tests (push) Successful in 45s
Full build / Full desktop build + optional release (push) Skipped
2026-11-04 09:41:11 +01:00
zwitschi 5158efc467 Retire the unused beanie gear and sequence asset fixes after the map rebuild
Full build / Full desktop build + optional release (push) Skipped
Full build / Import + headless tests (push) Successful in 43s
2026-11-04 09:36:10 +01:00
zwitschi ac0cf35cfb Fix the stale Joke Shop map count in the review doc
Full build / Import + headless tests (push) Successful in 44s
Full build / Full desktop build + optional release (push) Skipped
2026-11-04 09:30:44 +01:00
zwitschi 6655edb5c6 Sync development-status with the 3D re-evaluation facade/prop work and current counts
Full build / Import + headless tests (push) Successful in 52s
Full build / Full desktop build + optional release (push) Skipped
2026-11-04 09:22:27 +01:00
zwitschi 60f389c16b Force-spawn the requested portrait role and close the hooded close-up
Full build / Import + headless tests (push) Successful in 46s
Full build / Full desktop build + optional release (push) Skipped
2026-11-04 09:09:44 +01:00
zwitschi 3084145031 Rank the Comedy Store shape-language gaps (top-five list)
Full build / Import + headless tests (push) Successful in 50s
Full build / Full desktop build + optional release (push) Skipped
2026-11-04 09:04:30 +01:00
zwitschi 34bca89885 Record the set-dressing vision review findings
Full build / Import + headless tests (push) Successful in 46s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 22:00:49 +01:00
zwitschi b53e8a67f9 Polish the bollard base and newspaper-box door (recessed slot + seam)
Full build / Import + headless tests (push) Successful in 41s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 21:59:06 +01:00
zwitschi cdfd57fb65 Record the prop-gallery vision review findings
Full build / Import + headless tests (push) Successful in 43s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 21:56:50 +01:00
zwitschi 5bab6754c0 Rebuild the fire hydrant silhouette (flange, bonnet, outlets)
Full build / Import + headless tests (push) Successful in 53s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 21:56:28 +01:00
zwitschi 7dd8251a0c Extract and reconcile the Comedy Store proportions via the vision tool
Full build / Import + headless tests (push) Successful in 41s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 21:50:20 +01:00
zwitschi 8e113a4110 Tighten the gap analysis register
Full build / Full desktop build + optional release (push) Skipped
Full build / Import + headless tests (push) Successful in 42s
2026-11-03 21:02:01 +01:00
zwitschi 32c9c45605 Document the lighting vision review and add describe_image to the tools inventory
Full build / Full desktop build + optional release (push) Skipped
Full build / Import + headless tests (push) Successful in 46s
2026-11-03 21:00:54 +01:00
zwitschi e4065c2068 Tie back the Joke Shop curtain bays and add the describe_image vision tool
Full build / Import + headless tests (push) Successful in 39s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 20:58:05 +01:00
zwitschi e7d733bc93 Record the gear fit readings and caveats in the review doc
Full build / Full desktop build + optional release (push) Skipped
Full build / Import + headless tests (push) Successful in 42s
2026-11-03 20:25:39 +01:00
zwitschi 93da916f90 Gate venue light falloff with a test (physical attenuation = 1.0)
Full build / Full desktop build + optional release (push) Skipped
Full build / Import + headless tests (push) Successful in 39s
2026-11-03 20:14:23 +01:00
zwitschi e3ec4a356a Sync the stale Python test count (143 -> 160) in TODO
Full build / Import + headless tests (push) Successful in 41s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 20:13:10 +01:00
zwitschi 55339f23c1 Document the texel/coverage/collider gates and correct the face limitation note
Full build / Import + headless tests (push) Successful in 48s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 20:12:43 +01:00
zwitschi a51dae2c33 White the Joke Shop canopy signature band to match the reference
Full build / Full desktop build + optional release (push) Skipped
Full build / Import + headless tests (push) Successful in 45s
2026-11-03 20:07:01 +01:00
zwitschi 6824dd76a1 Close stale TODO items: camera height and local-frame provenance
Full build / Import + headless tests (push) Successful in 41s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 20:04:22 +01:00
zwitschi fde4aa4d0a Record the two-builder distinction in MEMORY
Full build / Import + headless tests (push) Successful in 43s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 20:03:15 +01:00
zwitschi ebb36cf0cb Correct face/head review: library characters already carry the 0.9.4 sculpt; close hands/grip review
Full build / Import + headless tests (push) Successful in 42s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 20:03:06 +01:00
zwitschi 724e8b183f Add tracked AI skills for Blender assets and release QA
Full build / Import + headless tests (push) Successful in 40s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 19:53:32 +01:00
zwitschi e4e1566e55 Organize tools and move Python tests into tools/tests
Full build / Import + headless tests (push) Successful in 38s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 19:45:00 +01:00
zwitschi 0aacee6518 Compact MEMORY.md: drop CHANGELOG/DONE duplication
Full build / Import + headless tests (push) Successful in 44s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 19:40:50 +01:00
zwitschi 215b843b67 Write the face/head concrete edits and close the review
Full build / Import + headless tests (push) Successful in 46s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 19:27:31 +01:00
zwitschi 53d9dc3f78 Record the cloth/hair decision: simulation stays out of scope
Full build / Import + headless tests (push) Successful in 42s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 19:26:50 +01:00
zwitschi 98f2f95f07 Close the UV/texel decision: accept the neutral runtime-tinted maps
Full build / Import + headless tests (push) Successful in 54s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 19:26:30 +01:00
zwitschi a677a95d13 Narrow the pose-harness root cause: skinned mesh ignores its Rig parent
Full build / Import + headless tests (push) Successful in 40s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 19:26:07 +01:00
zwitschi 1afd97c72d Complete the Comedy Store block reference collection (hotel + hillside)
Full build / Import + headless tests (push) Successful in 47s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 19:18:43 +01:00
zwitschi 6ca8bcf034 Decouple AGENTS.md from specific tracks: keep only process, action and tracking guidance
Full build / Full desktop build + optional release (push) Skipped
Full build / Import + headless tests (push) Successful in 46s
2026-11-03 19:16:57 +01:00
zwitschi 13eb4e0c87 Make the merged 3D + local map track coherent: rename, combined scope/exit, re-mark collection state
Full build / Import + headless tests (push) Successful in 39s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 19:13:21 +01:00
zwitschi 8fac1b47cf Merge local map tasks into the 3D review track
Full build / Import + headless tests (push) Successful in 40s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 18:41:21 +01:00
zwitschi b79e30e9df Render the TV Studio as the Masonic Temple facade (Jimmy Kimmel starting point)
Full build / Import + headless tests (push) Successful in 38s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 18:35:15 +01:00
zwitschi 1e761e5a76 Anchor Jimmy Kimmel Live entrance concepts and mark the building as the starting point
Full build / Import + headless tests (push) Successful in 45s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 18:28:31 +01:00
zwitschi 3eb2ae5e3c Collect Jimmy Kimmel Live and Hollywood block references; skip AVIF frames in the contact sheet
Full build / Import + headless tests (push) Successful in 41s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 18:24:35 +01:00
zwitschi 888897cac9 Add three multi-model Comedy Store scenes and plan the map recreation
Full build / Import + headless tests (push) Successful in 45s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 18:04:09 +01:00
zwitschi 988d431da8 Generate multi-model anchored concepts, drop old Comedy Store refs, and trim the concept gallery
Full build / Import + headless tests (push) Successful in 41s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 17:49:48 +01:00
zwitschi 87e1c9e7a5 Harden the DDG collector with token-bucket pacing and prefer the ddgs package
Full build / Import + headless tests (push) Successful in 40s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 17:32:39 +01:00
zwitschi 480a1ba05f Document the local-only reference collector
Full build / Import + headless tests (push) Successful in 41s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 17:12:32 +01:00
zwitschi 43c17ce3c0 Add the local-only DuckDuckGo reference collector
Full build / Import + headless tests (push) Successful in 54s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 17:12:18 +01:00
zwitschi 03f4d4bc49 Prioritize local reference collection and record the licence-free local-only override
Full build / Import + headless tests (push) Successful in 46s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 17:04:19 +01:00
zwitschi 15f9117517 Mark the completed maintenance tasks
Full build / Full desktop build + optional release (push) Skipped
Full build / Import + headless tests (push) Successful in 45s
2026-11-03 16:35:33 +01:00
zwitschi 78267918bf Trim MEMORY.md: drop superseded handoffs and release anecdotes, fix stale counts and the sign-in contradiction
Full build / Import + headless tests (push) Successful in 48s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 16:35:19 +01:00
zwitschi ea3860a60c Defer Gaussian splatting and re-plan maintenance
Full build / Import + headless tests (push) Successful in 46s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 16:31:42 +01:00
zwitschi b721f189c5 Record the stucco decision and the recitation-filter workaround
Full build / Import + headless tests (push) Successful in 47s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 16:22:28 +01:00
zwitschi 634b1f75a3 Give the Joke Shop a dark stucco wall and a photo-anchored concept
Full build / Full desktop build + optional release (push) Skipped
Full build / Import + headless tests (push) Successful in 48s
2026-11-03 16:22:20 +01:00
zwitschi 36583921cf Plan the Joke Shop building-appearance pass
Full build / Import + headless tests (push) Successful in 40s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 16:17:57 +01:00
zwitschi 3866b0ae01 Record the completed facade-realism pass
Full build / Full desktop build + optional release (push) Skipped
Full build / Import + headless tests (push) Successful in 47s
2026-11-03 16:15:46 +01:00
zwitschi 8c2761427f Verify the marquee emissive balance and close the facade-realism pass
Full build / Import + headless tests (push) Successful in 43s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 16:15:38 +01:00
zwitschi 2b07913481 Update the facade-realism progress note
Full build / Import + headless tests (push) Successful in 42s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 15:55:10 +01:00
zwitschi 768dd94bfc Balance the event-banner night emissive
Full build / Import + headless tests (push) Successful in 45s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 15:54:58 +01:00
zwitschi f516d3e796 Record the Godot import-cache gotcha and ashlar decision
Full build / Import + headless tests (push) Successful in 41s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 15:40:43 +01:00
zwitschi f95a685934 Use the photo-anchored ashlar limestone on the masonic facade
Full build / Import + headless tests (push) Successful in 49s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 15:40:25 +01:00
zwitschi 05cb6a43cb Link the three-up boards from the venue map docs
Full build / Import + headless tests (push) Successful in 39s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 15:11:09 +01:00
zwitschi 343b3348c2 Add three-up evidence boards for El Capitan and Joke Shop
Full build / Import + headless tests (push) Successful in 45s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 15:09:18 +01:00
zwitschi ad91e71eeb Add the photo-anchored variant pass with night and overcast facade frames
Full build / Import + headless tests (push) Successful in 40s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 15:04:20 +01:00
zwitschi 6e04c59589 Record the reference-anchored generation recipe in memory
Full build / Import + headless tests (push) Successful in 42s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 15:00:00 +01:00
zwitschi e21ff30783 Add reference-anchored concept generation
Full build / Import + headless tests (push) Successful in 49s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 14:59:53 +01:00
zwitschi 5b306b1c52 Add the Commons reference-board research tool
Full build / Import + headless tests (push) Successful in 40s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 14:51:31 +01:00
zwitschi f09a5e7937 Plan recent-photo tooling and reference-anchored generation
Full build / Import + headless tests (push) Successful in 41s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 14:36:13 +01:00
zwitschi 383f601bc9 Extend the Hollywood board with terrazzo, neighbour and night context
Full build / Import + headless tests (push) Successful in 40s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 14:04:51 +01:00
zwitschi c46db76d85 Record that the TV Studio venue shares the Hollywood block
Full build / Import + headless tests (push) Successful in 43s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 13:49:26 +01:00
zwitschi 1a5f2863b0 Add the licensed Joke Shop reference board
Full build / Import + headless tests (push) Successful in 45s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 13:41:25 +01:00
zwitschi a6fd77068a Add the first licensed Hollywood reference board
Full build / Import + headless tests (push) Successful in 40s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 13:28:05 +01:00
zwitschi 4ed73fcc7b Add the real-location reference folder and provenance sidecar
Full build / Import + headless tests (push) Successful in 43s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 12:42:13 +01:00
zwitschi c0ddce79e8 Record the imagery evidence model
Full build / Import + headless tests (push) Successful in 44s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 12:22:11 +01:00
zwitschi 0c7c9a2b23 Plan reference imagery, generated boards and per-section captures
Full build / Import + headless tests (push) Successful in 40s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 12:21:57 +01:00
zwitschi b94b87d096 Refresh the capture gallery and build captioned visual docs
Full build / Import + headless tests (push) Successful in 41s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 12:08:33 +01:00
zwitschi 5dec59355a Gate library prop collision coverage across venues
Full build / Import + headless tests (push) Successful in 37s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 11:58:00 +01:00
zwitschi fe3ba3054e Gate texel density and review scorecard coverage
Full build / Import + headless tests (push) Successful in 43s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 11:52:19 +01:00
zwitschi 88a0793bba Record the verified pose-capture recipe and the harness defect
Full build / Import + headless tests (push) Successful in 41s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 11:44:55 +01:00
zwitschi 1d4f718376 Narrow the pose-capture discrepancy to the harness and lock bone posing
Full build / Import + headless tests (push) Successful in 45s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 11:24:44 +01:00
zwitschi 7a5b902797 Add a pose review harness and record the blocked pose capture
Full build / Import + headless tests (push) Successful in 43s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 10:59:23 +01:00
zwitschi 2d67e14e52 Measure the 3D library and open the model review scorecard
Full build / Import + headless tests (push) Successful in 43s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 10:39:45 +01:00
zwitschi 2443343f2b adjusted agents instructions, made more precise and incorporate blender skills 2026-11-03 10:38:39 +01:00
zwitschi 3e41cda591 Re-plan the Blender tracks around the local skills and a 3D model review
Full build / Import + headless tests (push) Successful in 43s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 10:19:46 +01:00
zwitschi 84bc4137cb Add local pi agent session data to .gitignore 2026-11-03 10:13:34 +01:00
zwitschi 5dc3ef0f4c Add a Blender GLB intake inspection command
Full build / Full desktop build + optional release (push) Skipped
Full build / Import + headless tests (push) Successful in 44s
2026-11-03 10:08:45 +01:00
zwitschi 6f3facff43 Install the Blender skills pack locally and keep it out of git
Full build / Import + headless tests (push) Successful in 38s
Full build / Full desktop build + optional release (push) Skipped
2026-11-03 10:02:34 +01:00
192 changed files with 7544 additions and 1839 deletions

No files matched your search

View File
Whitespace-only changes.
@@ -0,0 +1,210 @@
---
name: gig-line-blender-asset-contract
description: Use when adding, rebuilding, auditing or fixing any Gig Line Blender-authored character, NPC base, gear, prop or venue geometry. Covers the 13-bone npc_base contract, five tint slots, triangle/vertex budgets, gear attach space, 256² texture/AO rules, headless flatpak Blender commands, and the inspect/audit/fit/proportion/capture gates. Do not use for pure GDScript/UI work or release publishing.
compatibility: Gig Line repository checkout. Godot 4.7.2 on PATH; Blender 5.2 LTS via the org.blender.Blender flatpak for build/bake/render. Audit, fit, inspect and proportion checks are stdlib-only.
metadata:
project: Gig Line
domain: 3d-assets
version: "1.0.0"
triggers: Blender, NPC, character, gear, prop, npc_base, GLB, AO, texel, asset rebuild, fit, audit
---
# Gig Line Blender Asset Contract
Use this skill for any change that touches:
- `assets/models/blender/**`
- `assets/models/generated/npc_base.glb`
- `assets/textures/npc/**`
- `tools/blender_assets.py`, `tools/npc_pipeline.py`, `tools/bake_ao.py`,
`tools/npc_proportions.py` or `tools/npc_baseline.py`
- Blender-authored venue/prop geometry
The project contract and measured gates override any generic Blender advice.
There is **no Blender MCP** in this project. Blender runs headless through the
flatpak CLI; the `blender-skills` pack is optional, local guidance only, and
gitignored.
## Read first
From the repository root, read the relevant sources rather than relying on this
skill alone:
1. `AGENTS.md` — required workflow and verification.
2. `TODO.md` and `MEMORY.md` — current track, claimed tasks, known gotchas.
3. `docs/blender-assets.md` — library contract and command reference.
4. `docs/asset-tooling.md` — exact rebuild/bake/capture commands.
5. `docs/npc-visual-review.md` and `docs/3d-model-review.md` — accepted limits,
scorecards and known blockers.
6. `docs/known-limitations.md` — limits that must not be silently “fixed” into
contract changes.
The contract lives in code and docs, not in this skill. If they disagree, stop
and resolve the source of truth before editing assets.
## Non-negotiable contract
| Area | Rule |
| --- | --- |
| Mesh root | `npc_base` mesh node, skinned under `Rig`; preserve the limb node names. |
| Bones | 13 contract bones: `Head`, `HipL/R`, `KneeL/R`, `ShoulderL/R`, `ElbowL/R`, `HandL/R`, `Spine`, `Neck` (parent/helper bones must not change the contract). |
| Tint slots | `skin`, `cloth`, `pants`, `accessory`, `hair`. |
| Orientation | Front is Blender −Y / Godot +Z; feet grounded near y = 0; metres. |
| Library budget | **8,000 triangles / 8,000 glTF vertices** per character (`CHAR_MAX_TRIS`/`CHAR_MAX_VERTS`). |
| Frozen fallback | `npc_base` keeps **6,000 tris / 4,000 verts**. Do not silently raise or lower it. |
| Gear budget | **1,500 triangles** per gear piece; authored in attach-point space. |
| Prop budget | **4,000 triangles** per prop. |
| Gear attach | Use the catalogued attach points; verify with `fit`. Runtime `GEAR_OFFSETS` (lanyard forward, firefighter helmet up) and `HAND_ITEM_FORWARD` are intentional, not asset-contract changes. |
| Textures | 256² albedo/normal/ORM maps. Cloth and pants use `NPC_FABRIC_UV_SCALE = (4,4,1)` and **skip** baked per-character AO; skin/hair/gear keep baked AO. |
| CI | Offline and skill-free. Committed GLBs/AO/maps must make CI pass without Blender or MCP. |
| Licensing | No new asset source without ADR-0015: CC0, or CC-BY with attribution in `CREDITS.md`; record provenance. |
Do not change the renderer, engine baseline, runtime dependency graph or the
`npc_base` contract as part of an asset pass.
## Workflow
### 1. Preflight and claim
```bash
git status --short
git log --oneline -5
godot --version
flatpak run org.blender.Blender --version | head -3
```
Inspect the current asset and the relevant docs. Claim the TODO item with `[-]`
before starting. Work on one asset family per commit.
### 2. Establish a baseline
Run the checks that do not need Blender first:
```bash
python3 tools/blender_assets.py audit
python3 tools/blender_assets.py fit
python3 tools/blender_assets.py texels
python3 tools/npc_proportions.py report
python3 tools/npc_pipeline.py audit
```
For a specific incoming or existing GLB:
```bash
flatpak run org.blender.Blender --background \
--python "$PWD/tools/blender_assets.py" -- \
inspect --file "$PWD/path/to/asset.glb" --category npc_gear --json
```
Record the before measurements (tris/verts, head/shoulder/hip/leg/arm/foot,
fabric texel density, gear clearance). Do not “improve” an asset without a
measurable target.
### 3. Optional Blender-skill routing
If the local `blender-skills` pack is installed, load `blender-director`, then
only the specialists the task needs:
- character mesh/face/hands: `character-artist`, `retopology`
- rig/weights/pose: `rigging`
- UVs/texel density: `uv-workflow`
- maps/materials: `texture-workflow`, `materials`, `lookdev`
- gear/props: `prop-artist`, `hard-surface`
- budget/LOD/collision: `asset-optimization`, `lod-pipeline`, `collision-proxy`
- final review: `qa-review`
Translate any MCP instruction into a change to `tools/*.py` or a headless CLI
run. Never add an MCP dependency to the build, CI or runtime.
### 4. Build or bake
Characters, gear and library props:
```bash
flatpak run org.blender.Blender --background \
--python "$PWD/tools/blender_assets.py" -- build --only <name>
flatpak run org.blender.Blender --background \
--python "$PWD/tools/bake_ao.py" -- --only <name>
```
NPC base and its material maps:
```bash
python3 tools/npc_pipeline.py prepare # only when fabric tiles change
flatpak run org.blender.Blender --background \
--python "$PWD/tools/npc_pipeline.py" -- build
python3 tools/npc_pipeline.py audit
```
Do not overwrite a review image or a promoted texture pick. Use a new `-vN`
path and document the promotion.
### 5. Import and capture
```bash
godot --headless --path . --import
godot --headless --path . --script res://src/test/test_runner.gd
# neutral baseline: 8 variants x 6 views, raw frames stay in tmp/
godot --path . --script res://src/test/capture_npc_baseline.gd \
-- --out=res://tmp/npc-baseline
# final-context: 96 frames across both venues and day/night
godot --path . --script res://src/test/capture_npc_review.gd \
-- --out=res://tmp/npc-review
```
Compare before/after with `tools/npc_baseline.py compare`; do not replace the
committed baseline sheet until a fix actually lands. See
`references/verification.md` for the full gate matrix.
### 6. Verify and hand off
At minimum:
- `blender_assets.py audit` and `fit` exit 0.
- `npc_proportions.py` passes the stylized guide.
- `npc_pipeline.py audit` passes if the base/textures changed.
- texel density is inside the authored/fabric bands.
- No character exceeds 8,000/8,000; gear/prop caps hold.
- 24-NPC budget and Web/Compatibility path remain green.
- Contract tests, headless suite, capture gates and docs check pass.
- The diff contains only the intended assets, tools, tests and docs.
State in the handoff: files changed, measurements before/after, skills used,
gates run, and any accepted limit.
## Failure playbook
- **`Class "..." hides a global script class`** — a stray `.gd` backup is in the
project. Delete `tmp/*.gd` backups, `rm -rf .godot`, re-import; never keep
`class_name` copies in `tmp/`.
- **Blender cannot see the path** — the flatpak cwd is `/app/blender`; use
absolute paths (`"$PWD/..."`).
- **Empty or stale captures** — close modals/pause, check the capture script's
settle frames, and remove stale output directories before re-running.
- **Pose harness mismatch** — the current `capture_npc_pose.gd` is blocked per
`docs/3d-model-review.md`; do not use its frames as pose evidence until the
recipe is fixed.
- **Asset test fails after import** — re-run audit/fit first, then import; if the
manifest or AO path changed, rebuild the affected asset rather than editing
the manifest by hand.
- **Uncertain about a visual change** — produce a labelled before/after sheet and
ask for review; do not hide a regression behind a budget claim.
## Bundled references
- [`references/asset-contract.md`](references/asset-contract.md) — full contract,
inventory, file locations and provenance rules.
- [`references/verification.md`](references/verification.md) — command matrix,
capture gates, expected results and acceptance criteria.
## Do not
- Add an MCP server, Blender dependency or API call to the build/runtime.
- Change the bone/tint/contract to make a generic asset fit.
- Rewrite committed baselines or overwrite existing images.
- Commit `.blend` sources, raw captures or generated AI inputs.
- Treat an asset audit as a substitute for visual review at portrait and crowd
distance.
@@ -0,0 +1,139 @@
# Asset Contract Reference
This is a working summary. The authoritative sources remain
`docs/blender-assets.md`, `docs/asset-tooling.md`, ADR-0013, the tests in
`src/test/tests/` and the constants in `tools/blender_assets.py` /
`tools/npc_pipeline.py`.
## Library inventory
- **Character variants (8):** `npc_casual`, `npc_jacket`, `npc_coat`,
`npc_vest`, `npc_dress`, `npc_hoodie`, `npc_firefighter`, `npc_guard`.
- **Frozen fallback:** `npc_base` / `assets/models/generated/npc_base.glb`.
- **Gear:** 18 attach-space pieces covering head, back, chest and hand items.
- **Library props:** 20 Blender-authored props plus 6 generated props.
- **Venues:** procedural venues in `src/game/world_builder.gd`; Blender venue
geometry follows the same budgets and collision/provenance rules.
## Skeleton and geometry
The contract skeleton has 13 bones:
```text
Head, Spine, Neck,
HipL, HipR,
KneeL, KneeR,
ShoulderL, ShoulderR,
ElbowL, ElbowR,
HandL, HandR
```
Requirements:
- `npc_base` mesh node exists and is skinned under `Rig`.
- Limb node names stay stable for `NpcAvatar` and tests.
- Front is Blender −Y / Godot +Z.
- Feet are grounded at approximately y = 0; no floating origin.
- Units are metres; character height is approximately 1.8 m.
- No zero-area/duplicate degenerate faces in the exported mesh.
- Every character has UVs in [0,1] unless a planned UDIM/atlas change is
explicitly accepted.
## Material slots
Exactly these five tint slots:
```text
skin, cloth, pants, accessory, hair
```
- Neutral albedo is authored in Blender; runtime tinting is authoritative.
- Slot names are contract values; do not rename or add a sixth slot casually.
- The procedural fallback (`NpcAvatar._build_body`) must keep working when the
GLB is missing.
## Budgets
| Asset | Limit |
| --- | --- |
| Library character | 8,000 triangles / 8,000 glTF vertices |
| `npc_base` fallback | 6,000 triangles / 4,000 vertices |
| Gear piece | 1,500 triangles |
| Prop | 4,000 triangles |
| Library prop/venue total | must stay inside the venue tests and library budget |
`CHAR_MAX_TRIS`, `CHAR_MAX_VERTS`, `GEAR_MAX_TRIS`, `PROP_MAX_TRIS` and related
constants live in `tools/blender_assets.py`. The budget is per character, not an
average. Measure after every mesh change. Do not lower the cap to make a diff
pass.
## Gear and hand items
- Gear is authored in the attach-point space documented by `GEAR` /
`GEAR_ATTACH` / `ATTACH_BLENDER`.
- `blender_assets.py fit` measures gear boxes against the character's head band,
clothing radius and back clearance.
- Runtime offsets are intentional:
- `NpcAvatar.GEAR_OFFSETS = {"lanyard": Vector3(0,0,0.04),
"firefighter_helmet": Vector3(0,0.03,0)}`
- `NpcAvatar.HAND_ITEM_FORWARD = Vector3(0,0,0.04)`
- An offset is **not** an authored-asset change; do not bake it into the GLB
without a separate contract decision.
- Open-palm grip (no finger-curl rig) is the accepted stylized limit.
## Textures and AO
- NPC maps are 256² albedo + normal + packed ORM.
- `TEX_SIZE = 256` in `tools/npc_pipeline.py`.
- Fabric UV scale is `Materials.NPC_FABRIC_UV_SCALE = Vector3(4,4,1)`.
- Cloth/pants skip the per-character baked AO; skin/hair/gear keep it. This
avoids the large blotchy magnification that appeared at 256².
- Gear/props may have their own AO maps; `tools/bake_ao.py` writes
`<name>_ao.png` next to the GLB and Godot wires it into the AO channel.
- Never overwrite an existing committed image; use a new `-vN` candidate and
promote only after review.
- Run `python3 tools/asset_pipeline.py audit <path>` and the relevant
`npc_pipeline.py audit` before committing map changes.
## File map
| Path | Role |
| --- | --- |
| `tools/blender_assets.py` | Catalogue, builders, audit/fit/inspect/texels/sheet. |
| `tools/npc_pipeline.py` | `npc_base` builder, texture preparation and audit. |
| `tools/bake_ao.py` | Blender AO bake into `<name>_ao.png`. |
| `tools/npc_proportions.py` | Exported-GLB proportion audit (no Blender). |
| `tools/npc_baseline.py` | Contact sheets/comparisons (no Blender). |
| `assets/models/blender/manifest.json` | Generated asset manifest. |
| `assets/models/blender/**/*.glb` | Committed library assets. |
| `assets/models/generated/npc_base.glb` | Frozen NPC fallback. |
| `assets/textures/npc/*_{albedo,normal,orm}.png` | Committed NPC maps. |
| `src/test/capture_npc_baseline.gd` | 48-frame neutral baseline. |
| `src/test/capture_npc_review.gd` | 96-frame final-context review. |
## Provenance and source rules
- Procedural Blender assets are project-owned.
- External/CC assets need ADR-0015 clearance: CC0 preferred, CC-BY only with
attribution in `CREDITS.md`; no service assets with redistribution limits.
- Editable `.blend` files under `assets/models/blender_src/` are gitignored;
only exported `.glb`, AO maps, manifests and committed preview sheets ship.
- AI-generated source images are development inputs, not shipped assets. Keep
raw generations under gitignored paths until picked, checked and credited.
- Do not copy a downloaded/Street View/AI reference into a committed asset
without the licence and provenance review.
## Verification invariants
The asset pass is not complete unless:
1. `python3 tools/blender_assets.py audit` exits 0.
2. `python3 tools/blender_assets.py fit` exits 0 and the report is reviewed.
3. `python3 tools/npc_proportions.py report` passes the stylized guide.
4. `python3 tools/npc_pipeline.py audit` passes when the base/textures changed.
5. The 48-frame baseline and 96-frame final-context review are captured, with no
blank frames.
6. The 24-NPC budget smoke is inside its frame budget.
7. The full Godot suite and Python tooling tests pass.
8. No runtime contract, renderer or dependency changed except the rebuilt
assets and their generated metadata.
@@ -0,0 +1,123 @@
# Verification Matrix
Run from the repository root. Stop and fix the first failure before continuing.
## Environment
```bash
godot --version
flatpak run org.blender.Blender --version | head -3
git status --short
```
Expected: Godot 4.7.2; Blender 5.2 LTS flatpak; clean or intentionally scoped
working tree. Blender's flatpak cwd is `/app/blender`; all paths passed to
Blender must be absolute.
## Asset checks
| Check | Command | Expected |
| --- | --- | --- |
| Contract audit | `python3 tools/blender_assets.py audit` | exit 0, no `BAD` assets |
| Gear fit | `python3 tools/blender_assets.py fit` | exit 0; review head band/clothing/back clearances |
| Texture/texel density | `python3 tools/blender_assets.py texels` | authored 40–400 px/m; fabric ≥250 px/m |
| NPC base | `python3 tools/npc_pipeline.py audit` | exit 0, contract bones/slots/maps |
| Proportions | `python3 tools/npc_proportions.py report` | all eight inside the stylized guide |
| Single incoming GLB | `flatpak run org.blender.Blender --background --python "$PWD/tools/blender_assets.py" -- inspect --file "$PWD/path.glb" --category <cat> --json` | contract result and measurements |
| Prop audit | `python3 tools/model_pipeline.py audit` | exit 0 when generated props changed |
| Texture audit | `python3 tools/asset_pipeline.py audit assets/textures/ai/game_ready` | exit 0 when textures changed |
## Build/bake
```bash
# one library asset
flatpak run org.blender.Blender --background \
--python "$PWD/tools/blender_assets.py" -- build --only npc_guard
# bake AO for the same asset
flatpak run org.blender.Blender --background \
--python "$PWD/tools/bake_ao.py" -- --only npc_guard
# NPC base material maps/base
python3 tools/npc_pipeline.py prepare
flatpak run org.blender.Blender --background \
--python "$PWD/tools/npc_pipeline.py" -- build
python3 tools/npc_pipeline.py audit
```
Only run `prepare` when AI fabric inputs changed. Do not run a full library
rebuild just to hide a small diff; build the affected asset and its AO map.
## Import and tests
```bash
godot --headless --path . --import
godot --headless --path . --script res://src/test/test_runner.gd
python3 -m unittest discover -s tools/tests -t tools -p 'test_*.py'
python3 tools/check_docs.py
```
Expected: Godot suite passes; Python tooling suite passes; docs check OK. The
project uses its own headless runner, not GUT.
## Capture gates
```bash
# neutral studio baseline: 48 frames (8 characters x 6 views)
godot --path . --script res://src/test/capture_npc_baseline.gd \
-- --out=res://tmp/npc-baseline-after
# final-context: 96 frames (8 models x 3 distances x 2 venues x day/night)
godot --path . --script res://src/test/capture_npc_review.gd \
-- --out=res://tmp/npc-review-after
# optional hand close-up: 8 frames
godot --path . --script res://src/test/capture_npc_baseline.gd \
-- --out=res://tmp/npc-hands --view=hand
```
Raw frames stay under `tmp/` and are never committed. Compare with:
```bash
python3 tools/npc_baseline.py compare \
--before tmp/npc-baseline --after tmp/npc-baseline-after \
--out docs/blender_previews/sheet_npc_baseline_compare-<topic>.jpg
```
Do not replace the committed baseline sheet until the change is accepted.
## Budget/performance
```bash
godot --headless --path . --script res://src/test/smoke_npc_budget.gd
```
Expected report: 24 avatars / 168 meshes / 131,616 triangles (current baseline)
inside the 50 ms budget. Record the actual frame time; do not copy an old number
without measuring.
## Visual review criteria
For each changed variant, inspect at least:
- 2 m portrait: eyes, mouth, ears, neck/shoulder, hair/headgear clearance.
- 4.2 m conversation: hands, gear contact, clothing silhouette.
- 8 m crowd: readable silhouette and LOD/impostor swap.
- Day and night/LATE final-context frames.
- Front, three-quarter and profile for a shape change.
Accepted stylized limits are in `docs/npc-visual-review.md` and
`docs/known-limitations.md`. Do not turn an accepted limit into an unreviewed
contract change.
## Final diff review
```bash
git diff --check
git status --short
git diff --stat
```
Check that only intended `.glb`, AO/maps, manifest, tests and docs changed. If a
`.blend`, raw capture, generated AI input or temporary sheet is staged, stop and
remove it. Commit one coherent asset family per commit.
+254
View File
@@ -0,0 +1,254 @@
---
name: gig-line-release-qa
description: Use when preparing, validating, tagging or publishing a Gig Line release or release candidate, or when running the full screenshot, screen-design and realism QA gates. Covers version/changelog discipline, smoke and tooling matrices, clean-worktree builds, checksums, Web/HQ verification, publish rollback and post-release records. Do not use for ordinary asset edits or feature work.
compatibility: Gig Line repository checkout with Godot 4.7.2 on PATH and Python 3 + Pillow. Release export needs installed Godot export templates; publishing needs Gitea credentials and is intentionally CI/tag-driven.
metadata:
project: Gig Line
domain: release-qa
version: "1.0.0"
triggers: release, tag, version bump, changelog, build releases, publish, screenshots, screen design, realism judge, release candidate, deployment
---
# Gig Line Release and Visual QA
Use this skill for version bumps, release candidates, tags, artifact builds,
publishing, and the full visual/QA gate. For a Blender/asset rebuild, use
`gig-line-blender-asset-contract` first.
## Read first
1. `AGENTS.md` — release procedure and verification rules.
2. `TODO.md` — current milestone, blockers and release exit criteria.
3. `docs/RELEASING.md` — build/publish commands, artifact list, macOS policy.
4. `docs/smoke-checklist.md` — manual QA matrix.
5. `docs/development-status.md`, `CHANGELOG.md`, `README.md` — current claims.
6. `MEMORY.md` — release gotchas, especially the clean-worktree rule.
A release is not just a tag. It includes a version bump, changelog, clean build,
artifact/checksum verification, CI publication, and post-release records.
## Hard rules
- **Do not tag while the TODO still lists unresolved release blockers.** Check
external playtest, legal/AI provenance, signing and target-hardware items.
- **Never reuse a tag.** If a published version needs a fix, bump the patch and
create a new tag.
- **Build from a clean checkout or detached worktree.** A normal working tree can
pack ignored `tmp/` and `build/` content into exports, inflating a ~160 MB
package to 1.6–3.1 GB.
- A tag push triggers CI checks/build/publish. Do not upload manually unless CI is
unavailable and you have followed the same preflight.
- Do not commit generated realism runs, raw captures, API keys, or build artifacts.
- The vision judge is an optional development aid with external API cost, never a
hard CI gate.
- Keep `project.godot`, changelog, tag and release asset version equal.
## Release workflow
### 1. Scope and version
Choose the semantic increment from `AGENTS.md`:
- MAJOR: incompatible/removed behavior, save/config contract or core-pillar
replacement.
- MINOR: new user-facing feature/venue.
- PATCH: fixes and polish.
Update:
1. `project.godot` `config/version`.
2. `CHANGELOG.md` with a dated entry.
3. `README.md`, `PLAN.md`, `docs/architecture.md`,
`docs/development-status.md`, `TODO.md`/`DONE.md` and `MEMORY.md` as needed.
For a release candidate, use a prerelease version only if the project policy
allows it and never present it as the final release.
### 2. Preflight
```bash
git status --short
git log --oneline -5
git tag -l "v<version>"
rg -n 'config/version' project.godot
```
Expected: only intended release changes; tag does not exist; version matches the
changelog and planned artifacts.
### 3. Automated checks
```bash
godot --headless --path . --script res://src/test/test_runner.gd
python3 -m unittest discover -s tools/tests -t tools -p 'test_*.py'
python3 tools/check_docs.py
python3 tools/blender_assets.py audit
python3 tools/blender_assets.py fit
python3 tools/npc_proportions.py report
python3 tools/npc_pipeline.py audit
```
Then run the smoke matrix, using isolated user-data directories for
tutorial/campaign:
```bash
for s in smoke_audio smoke_crowd smoke_emergency smoke_npc_budget \
smoke_plan_verbs smoke_scenario_content smoke_session_shell \
smoke_timeline smoke_ui_flows; do
godot --headless --path . --script res://src/test/$s.gd || exit 1
done
XDG_DATA_HOME=/tmp/gig-line-campaign godot --path . --fixed-fps 60 \
--script res://src/test/smoke_campaign.gd
XDG_DATA_HOME=/tmp/gig-line-tutorial godot --path . --fixed-fps 60 \
--script res://src/test/smoke_tutorial.gd -- --tutorial
godot --path . --script res://src/test/smoke_movement.gd
godot --path . --script res://src/test/smoke_props.gd
godot --path . --script res://src/test/smoke_focus_radial.gd
```
Use a fresh `$XDG_DATA_HOME` for campaign/tutorial and check the exit code, not
just the log.
### 4. Visual and judge gates
```bash
./tools/check_screenshots.sh
python3 tools/screen_designs.py compare
python3 tools/screen_designs.py judge --model auto # optional, record model/verdicts
```
For realism/venue work:
```bash
godot --path . --script res://src/test/capture_realism.gd \
-- --out=res://docs/screens/realism/<run>/after
python3 tools/scene_concepts.py realism --run docs/screens/realism/<run> \
--judge --model <pinned-model>
```
Requirements:
- Gallery: 21 good / 0 bad; screen judge has no unexplained `diff`.
- Realism runs stay under `docs/screens/realism/` (gitignored); only decisions and
committed sheets/docs are tracked.
- Record judge model, run count/attempts, spend if exposed, and verdicts.
- Review every `review` verdict; turn layout regressions into fixes or documented
known limitations.
### 5. Clean build
Commit the release preparation first, then build the committed tree in a clean
worktree:
```bash
git worktree add --detach /tmp/gig-line-release HEAD
cd /tmp/gig-line-release
./tools/build_releases.sh
```
Verify artifact names/sizes and checksums:
```bash
ls -lh build/gig-line-*<version>*
PUBLISH_DRY_RUN=1 ./tools/publish_release.sh <version>
sha256sum -c build/SHA256SUMS-<version>.txt
```
Check package contents:
```bash
unzip -l build/gig-line-web-<version>.zip | head
unzip -l build/gig-line-desktop-hq-<version>.zip | head
unzip -p build/gig-line-desktop-hq-<version>.zip override.cfg
```
Check the runnable Linux and HQ packages:
```bash
./build/gig-line-linux-<version>.x86_64 --headless --quit-after 60
unzip -q build/gig-line-desktop-hq-<version>.zip -d /tmp/gig-line-hq
/tmp/gig-line-hq/gig-line-linux-<version>.x86_64 --headless --quit-after 60
```
Check Web static serving with a local HTTP server and `curl` for `index.html`,
`index.wasm`, `index.pck` and the player docs. Windows/macOS/AppImage/installer
checks require the target matrix; if unavailable, record that explicitly.
Remove the worktree after verification:
```bash
git worktree remove --force /tmp/gig-line-release
```
### 6. Tag and publish
Only after every gate is green:
```bash
git add -A
git commit -m "Release <version> <topic>"
git tag -a "v<version>" -m "Gig Line <version>"
git push origin main "v<version>"
```
CI builds and publishes on the tag. Verify:
- Tag commit equals the release commit.
- CI checks/build job succeeded.
- Release page has the expected 7 assets (Linux, Windows, macOS, NSIS setup,
AppImage, Web, Desktop HQ).
- Asset names and download links point at the released version.
`tools/publish_release.sh` preflights artifact size/free space, writes SHA-256
checksums, rolls back newly uploaded assets/release on failure, and supports
opt-in retention:
```bash
RETAIN_RELEASES=7 ./tools/publish_release.sh <version>
```
The default `RETAIN_RELEASES=0` never prunes.
### 7. Post-release record
Update `README.md`, `docs/development-status.md`, `MEMORY.md`, `CHANGELOG.md`,
`TODO.md`/`DONE.md` and the release page with the built/CI result. Commit the
release record and push. Record any skipped check and the reason; never leave a
tag with unreported missing verification.
## Known gotchas
- **Dirty build inflation:** always use the clean worktree above.
- **`Class ... hides a global script class`:** remove stray `.gd` backups in
`tmp/`, delete `.godot`, re-import.
- **Screenshot staging:** `capture_ui_states.gd` needs its settle frames and
staged state; do not capture a paused frame or a stale modal.
- **Judge keys:** OpenRouter calls need `.env`/`OPENROUTER_API_KEY`; never commit
the key or generated review folders.
- **Tag builds publish automatically:** do not run a second manual publish that
duplicates assets; use the existing release if re-running.
- **macOS is unsigned unless policy changes:** record quarantine instructions and
do not claim notarization.
- **Release blockers are real:** external playtest, legal/storefront approval,
AI-provider rights and target-hardware checks cannot be replaced by green unit
tests.
## Bundled references
- [`references/release-runbook.md`](references/release-runbook.md) — version,
build, tag, CI, publish and rollback sequence.
- [`references/qa-gates.md`](references/qa-gates.md) — full command matrix,
expected results and evidence to record.
## Completion checklist
- [ ] Version/changelog/docs/tag match.
- [ ] No unresolved release blockers for a final tag.
- [ ] Godot, Python, smokes, asset and docs gates pass.
- [ ] Gallery and optional judges reviewed with evidence.
- [ ] Clean worktree build and checksums verified.
- [ ] Linux/HQ/Web checks recorded; unavailable platforms noted.
- [ ] Tag pushed; CI/publish succeeded; seven assets verified.
- [ ] Release record and durable docs committed.
@@ -0,0 +1,171 @@
# QA Gate Matrix
Run from the repository root. Capture the exit code and the useful report line,
not only the final “OK”.
## 1. Source and docs
```bash
git status --short
git log --oneline -5
python3 tools/check_docs.py
git diff --check
```
Expected: intended files only; `check_docs: OK`; no whitespace errors.
## 2. Automated suites
```bash
godot --headless --path . --script res://src/test/test_runner.gd
python3 -m unittest discover -s tools/tests -t tools -p 'test_*.py'
```
Expected: the current Godot suite passes (historically 272+ tests) and the
Python tooling suite passes (currently 160 tests). Do not edit expected counts
without inspecting the suite.
## 3. Asset gates
```bash
python3 tools/blender_assets.py audit
python3 tools/blender_assets.py fit
python3 tools/blender_assets.py texels
python3 tools/npc_pipeline.py audit
python3 tools/npc_proportions.py report
```
Expected: exit 0, no `BAD` assets, all eight characters inside the stylized
proportion guide, no budget/contract regression.
Optional texture/model audits when those assets changed:
```bash
python3 tools/asset_pipeline.py audit assets/textures/ai/game_ready
python3 tools/model_pipeline.py audit
```
## 4. Smoke matrix
Headless:
```bash
for s in smoke_audio smoke_crowd smoke_emergency smoke_npc_budget \
smoke_plan_verbs smoke_scenario_content smoke_session_shell \
smoke_timeline smoke_ui_flows; do
echo "== $s"
godot --headless --path . --script res://src/test/$s.gd || exit 1
done
```
Isolated data:
```bash
rm -rf /tmp/gig-line-release-campaign /tmp/gig-line-release-tutorial
XDG_DATA_HOME=/tmp/gig-line-release-campaign godot --path . --fixed-fps 60 \
--script res://src/test/smoke_campaign.gd
XDG_DATA_HOME=/tmp/gig-line-release-tutorial godot --path . --fixed-fps 60 \
--script res://src/test/smoke_tutorial.gd -- --tutorial
```
Windowed input/UI:
```bash
godot --path . --script res://src/test/smoke_movement.gd
godot --path . --script res://src/test/smoke_props.gd
godot --path . --script res://src/test/smoke_focus_radial.gd
```
Expected: 14 smokes green. `smoke_npc_budget` should print the current mesh,
triangle and frame-time evidence; the 50 ms budget is a safety ceiling.
## 5. Screenshot and design gates
```bash
./tools/check_screenshots.sh
python3 tools/screen_designs.py compare
```
Expected: 21 good / 0 bad; no unexplained compare output. The judge is optional:
```bash
python3 tools/screen_designs.py judge --model auto
```
Record model, confidence/verdict summary, `diff` count and any manual review.
`docs/screen-design-report.md` is the durable record.
## 6. Realism judge (when visual assets/lighting changed)
```bash
godot --path . --script res://src/test/capture_realism.gd \
-- --out=res://docs/screens/realism/<run>/after
python3 tools/scene_concepts.py realism --run docs/screens/realism/<run> \
--judge --model <pinned-model>
```
Expected: a complete set of required stage captures, no stale pauses/modals, and
a report under the gitignored run directory. Record:
- pinned model/fallbacks
- shots attempted/completed
- spend if the tool exposes it
- mean score and Pillow gap
- every `review` verdict and disposition
Do not commit the run. Commit only the decision/report summary and any durable
comparison sheet explicitly intended for review.
## 7. Package checks
Use the clean worktree from `release-runbook.md`.
```bash
PUBLISH_DRY_RUN=1 ./tools/publish_release.sh <version>
sha256sum -c build/SHA256SUMS-<version>.txt
unzip -l build/gig-line-web-<version>.zip
unzip -l build/gig-line-desktop-hq-<version>.zip
unzip -p build/gig-line-desktop-hq-<version>.zip override.cfg
./build/gig-line-linux-<version>.x86_64 --headless --quit-after 60
```
Expected:
- names match the version;
- Linux/Windows/macOS/Web/HQ present locally;
- Web contains HTML/wasm/pck and docs;
- HQ contains `override.cfg`, executables and docs;
- Linux/HQ start without a script error.
Windows installer/AppImage and macOS launch require CI or the target matrix. If
not available, mark them as unverified rather than passing them by analogy.
## 8. Release verification
After the tag push:
- CI checks job succeeded;
- CI build job succeeded;
- release page has seven assets;
- each artifact name includes the released version;
- the tag points at the release commit;
- README/changelog/status and release notes agree.
## Evidence summary template
```text
Release: vX.Y.Z (commit)
Godot: pass (N/N)
Python tooling: pass (N/N)
Smokes: 14/14
Assets: audit/fit/proportions/npc audit pass
Budget: 24 NPCs, N meshes, N triangles, N ms
Gallery: 21 good / 0 bad
Screen judge: N/N match, N review, N diff
Realism: model, attempts, mean, gap, review dispositions
Build: clean worktree, artifact sizes/checksums
Launch: Linux/HQ/Web checks; unverified platforms
CI/release: run id, seven assets
Skipped checks + reason:
Known limitations:
```
@@ -0,0 +1,171 @@
# Release Runbook
Authoritative source: `AGENTS.md` (Release Procedure), `docs/RELEASING.md`.
This runbook is the operational checklist; if it conflicts with those, they win.
## 0. Decide the release
Determine whether this is a major, minor, patch, or release-candidate checkpoint.
Do not assign a version to an unversioned development track until its scope is
accepted into a release.
Check the current release constraints in `TODO.md`:
- external playtest evidence
- legal/AI-provider/storefront review
- macOS signing/notarization policy
- target hardware matrix
- any manual QA gaps
If a final release would ship with unresolved blockers, prepare an RC or stop;
do not create a final tag.
## 1. Prepare the version
Files to update:
| File | Change |
| --- | --- |
| `project.godot` | `config/version="X.Y.Z"` |
| `CHANGELOG.md` | dated `## [X.Y.Z] — YYYY-MM-DD` entry |
| `README.md` | latest/current version and summary |
| `PLAN.md` / `docs/architecture.md` | current version reference |
| `docs/development-status.md` | shipped capability/release result |
| `TODO.md` / `DONE.md` | close/move milestone when complete |
| `MEMORY.md` | release state and gotchas |
Then commit the preparation before building.
## 2. Run gates
Use `qa-gates.md` as the command matrix. The minimum release gate is:
- Godot suite
- Python tooling tests
- documentation gate
- asset audits/fit/proportions
- 24-NPC budget
- 14 smoke scripts
- screenshot compare
- optional screen/realism judge with recorded model/attempts
- clean build and artifact checks
Any skipped check must be written into `MEMORY.md` or `TODO.md` with a reason.
## 3. Build in a clean worktree
Why: Godot can pack ignored `tmp/` captures and `build/` outputs into the export.
A dirty build can produce 1.6–3.1 GB artifacts instead of ~160–240 MB.
```bash
git worktree add --detach /tmp/gig-line-release HEAD
cd /tmp/gig-line-release
./tools/build_releases.sh
```
Expected local artifacts:
```text
build/gig-line-linux-<version>.x86_64
build/gig-line-windows-<version>.exe
build/gig-line-macos-<version>.zip
build/gig-line-web-<version>.zip
build/gig-line-desktop-hq-<version>.zip
```
CI additionally produces the NSIS setup and AppImage, for seven release assets.
## 4. Preflight and checksum
```bash
PUBLISH_DRY_RUN=1 ./tools/publish_release.sh <version>
sha256sum -c build/SHA256SUMS-<version>.txt
```
`publish_release.sh` checks non-empty artifacts and local free space before any
API call. It writes checksums under `build/` and does not upload them by default.
Inspect packages:
```bash
unzip -l build/gig-line-web-<version>.zip | head -20
unzip -l build/gig-line-desktop-hq-<version>.zip | head -20
unzip -p build/gig-line-desktop-hq-<version>.zip override.cfg
```
Web must contain `index.html`, `index.wasm`, `index.pck`, and player docs.
Desktop HQ must contain the Linux/Windows executables, `override.cfg`,
`README.txt`, `CREDITS.md`, `PRIVACY.md`, `accessibility.md` and
`known-limitations.md`.
## 5. Runtime launch smoke
```bash
./build/gig-line-linux-<version>.x86_64 --headless --quit-after 60
unzip -q build/gig-line-desktop-hq-<version>.zip -d /tmp/gig-line-hq
/tmp/gig-line-hq/gig-line-linux-<version>.x86_64 --headless --quit-after 60
```
For Web, serve `build/web` and check HTTP 200 for `index.html`, `index.wasm`,
`index.pck` and docs. Do not claim browser interaction from a curl check.
Remove the temporary worktree after checks:
```bash
git worktree remove --force /tmp/gig-line-release
```
## 6. Tag and CI
From the real repository, on the release commit:
```bash
git tag -a "v<version>" -m "Gig Line <version>"
git push origin main "v<version>"
```
The tag triggers `.gitea/workflows/build.yml`: checks, export, installer,
AppImage, release publish. Verify the run and assets:
- check job success
- build job success
- seven assets present
- tag/version/artifact names equal
- download links respond
Do not reuse a published tag. If a fix is needed, bump patch and repeat.
## 7. Manual publish fallback
Only if CI cannot publish:
```bash
RETAIN_RELEASES=7 ./tools/publish_release.sh <version>
```
The script reuses or creates the release, uploads present artifacts, verifies the
asset count, and rolls back newly uploaded assets/new release on failure. The
default retention is `0` (no deletion). Never delete older releases implicitly.
## 8. Post-release record
Commit a release record that includes:
- tag and commit
- CI run/result
- seven assets
- checksums or size evidence
- skipped checks
- known limitations
- release URL
Update `DONE.md`/`TODO.md` and `MEMORY.md`; keep the changelog and README
consistent. Push the record commit.
## Versioning pitfalls
- A `vX.Y.Z` tag is immutable in practice; do not move/replace it.
- A release candidate is not a final release. Do not label it as such in the
README or release page if blockers remain.
- `config/version` must match the tag and artifact filenames.
- The clean-worktree build is a release requirement, not an optimization.
+18
View File
@@ -58,6 +58,20 @@ assets/models/generated/npc_base_*_normal.png
# Local AppImage extraction # Local AppImage extraction
squashfs-root/ squashfs-root/
# Local agent skills. The third-party Blender pack is installed per machine and
# stays ignored; the two project-authored skills are tracked so the workflow can
# be shared and reviewed.
.agents/
!.agents/
.agents/*
!.agents/.gdignore
!.agents/skills/
.agents/skills/*
!.agents/skills/gig-line-blender-asset-contract/
!.agents/skills/gig-line-blender-asset-contract/**
!.agents/skills/gig-line-release-qa/
!.agents/skills/gig-line-release-qa/**
# Blender asset library: per-asset Cycles renders are local review output (the # Blender asset library: per-asset Cycles renders are local review output (the
# committed review artefacts are docs/blender_previews/sheet_*.jpg), and Godot # committed review artefacts are docs/blender_previews/sheet_*.jpg), and Godot
# extracts the GLB-embedded textures next to the models on import. # extracts the GLB-embedded textures next to the models on import.
@@ -74,3 +88,7 @@ assets/models/blender_src/*.blend
assets/textures/ai/game_ready/v2/* assets/textures/ai/game_ready/v2/*
!assets/textures/ai/game_ready/v2/picks/ !assets/textures/ai/game_ready/v2/picks/
docs/screens/realism/ docs/screens/realism/
## Local pi agent session data
pi-session-*.html
pi-session-*.jsonl
+113 -30
View File
@@ -28,7 +28,7 @@ The project should be developed in small, reviewable steps. Agents must keep pla
`TODO.md` is the priority source. The active order is: `TODO.md` is the priority source. The active order is:
1. unversioned development tracks (currently character development and local map development); 1. unversioned development tracks;
2. versioned release milestones, in version order; 2. versioned release milestones, in version order;
3. future/unversioned candidates and deferred work. 3. future/unversioned candidates and deferred work.
@@ -36,6 +36,76 @@ Do not assign a version number to an unversioned track until its scope is accept
release. When a version is assigned, it must be the next semantic version that matches the release. When a version is assigned, it must be the next semantic version that matches the
scope (major/minor/patch), not a placeholder. scope (major/minor/patch), not a placeholder.
## Local Blender skills (development aid)
The MIT `blender-skills` pack is installed locally at `.agents/skills/blender-skills/`
(94 skills plus a shared `references/` folder). It is **gitignored on purpose**: it is not
game content, not part of the build, tests, CI or release packages, and every contributor
may or may not have it. The agent runtime (Pi) gates project `.agents/skills` behind project
trust, so the trust prompt must be accepted before the skills load; `/skill:blender-director`
forces one.
Use them when a task touches `tools/blender_assets.py`, `tools/npc_pipeline.py`,
`tools/bake_ao.py`, `assets/models/blender/**`, or Blender-authored venue/prop geometry.
### Project-authored skills (tracked)
Two project skills are committed under `.agents/skills/` and are guidance for
any agent, not only Pi:
- `gig-line-blender-asset-contract` — the NPC/gear/prop contract, build order,
headless Blender commands, failure playbook and verification gates.
- `gig-line-release-qa` — the test/smoke matrix, visual judges, clean-worktree
build, checksum/tag/publish sequence and release records.
They are not runtime dependencies and do not move tool implementations into
`.agents/`. The third-party `blender-skills` pack stays local/gitignored.
### Routing
Start with `blender-director` for anything multi-discipline, then load only the
specialists the task needs:
| Work | Skills |
| --- | --- |
| Plan/route a Blender task, reference photo match | `blender-director` |
| Character mesh, face, hands, proportions | `character-artist`, `character-archetypes`, `retopology` |
| Skeleton, weights, pose/contract rigging | `rigging` |
| UV layout, texel density, UDIM | `uv-workflow` |
| Bakery, atlas, normal/AO/ORM maps | `texture-workflow` |
| PBR materials and shading | `materials` |
| Screenshot-driven material/light iteration | `lookdev` |
| Triangle/vertex budgets, naming, scene hygiene | `asset-optimization` |
| LOD tiers and impostors | `lod-pipeline` |
| Collision shapes and proxies | `collision-proxy` |
| GLB export for Godot | `godot-export`, `export-pipeline` |
| Gear, props, street furniture | `prop-artist`, `hard-surface` |
| Trees, hedges, foliage cards | `vegetation-artist` |
| Facades, venues, modular kits, dressing | `environment-artist`, `archviz`, `set-dressing`, `geometry-nodes` |
| Lighting, framing, final render/composite | `lighting`, `camera-cinematography`, `rendering`, `compositing` |
| Style direction (stylized / low-poly / realistic) | `stylized-style`, `lowpoly-style`, `realistic-style` |
| Ship/no-ship review | `qa-review` |
### Project rules that override a skill
1. **The project contract wins.** `npc_base` mesh node, the 13 contract bones at their rest
positions, five tint slots, front on Blender −Y / Godot +Z, grounded feet, 8,000
triangles / 8,000 glTF vertices per character, 1,500 per gear, 4,000 per prop. A skill
may recommend another topology, naming or budget scheme; do not adopt it unless the
change is explicitly planned and the contract, tests and docs are updated together.
2. **There is no Blender MCP here.** The skills assume MCP tools; this project runs Blender
as headless flatpak scripts (`tools/blender_assets.py`, `tools/npc_pipeline.py`). Translate
MCP steps into script changes or CLI runs. Never add an MCP dependency to the build, CI or
runtime.
3. **CI stays offline and skill-free.** Skills are local guidance only; every gate must still
work from a fresh checkout with committed `.glb`/`.png`/`.tres` files and Godot.
4. **No new asset source without the licence gate.** Skills may suggest reference packs or
generated meshes; ADR-0015 (CC0, or CC-BY with attribution in `CREDITS.md`) and the
provenance rules in `docs/npc-model-sourcing.md` still apply.
5. **Evidence, not vibes.** After a skill-informed change, run `blender_assets.py inspect`,
`audit` and `fit` plus the relevant capture/smoke gates, and say in the handoff which
skills informed the change and what the measurements were.
## Required Workflow ## Required Workflow
### 1. Start by Inspecting the Repository ### 1. Start by Inspecting the Repository
@@ -63,8 +133,8 @@ All planned implementation work must be represented in `TODO.md`.
- Order level-2 sections by current priority: unversioned development tracks first, then - Order level-2 sections by current priority: unversioned development tracks first, then
versioned release milestones in version order, then future/deferred work. Do not assign a versioned release milestones in version order, then future/deferred work. Do not assign a
version number to an unversioned track until it is scheduled for a release. version number to an unversioned track until it is scheduled for a release.
- Use level-3 headings (`###`) for workstreams inside a milestone (for example, `0.8.1 - Use level-3 headings (`###`) for workstreams inside a milestone. Keep the hierarchy to three
First-shift tutorial`). Keep the hierarchy to three levels: milestone → workstream → checkbox. levels: milestone → workstream → checkbox.
- Use checkbox items for each concrete task, normally under a level-3 workstream. Direct - Use checkbox items for each concrete task, normally under a level-3 workstream. Direct
checkboxes under a level-2 section are acceptable for small, single-workstream sections. checkboxes under a level-2 section are acceptable for small, single-workstream sections.
- Keep tasks small enough to complete and review independently. - Keep tasks small enough to complete and review independently.
@@ -83,29 +153,30 @@ Recommended format:
```md ```md
# TODO # TODO
## Milestone 0.8.0 — First hour and content depth ## Milestone X.Y.Z — goal and exit criterion
### 0.8.1 First-shift tutorial ### Workstream A
- [x] Write the tutorial beat sheet. - [x] Completed task.
- [-] Implement the tutorial state machine. (claimed; implementation/verification in progress) - [-] Task in progress. (claimed; implementation/verification in progress)
- [ ] Add the tutorial smoke test. - [ ] Open task.
### 0.8.2 Campaign shell ### Workstream B
- [ ] Define campaign data. - [ ] Another task.
- [ ] Persist campaign progress.
**Exit:** a first-time player completes a shift without external documentation. **Exit:** a verifiable statement of what "done" means for the milestone.
## Documentation ## Theme
- [ ] Document the test procedure in `README.md`. - [ ] A small housekeeping task with no milestone.
``` ```
Recommended `DONE.md` format: a `# DONE` heading, followed by each moved level-2 section
unchanged, with a completion date line under each section heading.
Order the actual file as described in "Priority and Versioning": unversioned development tracks Order the actual file as described in "Priority and Versioning": unversioned development tracks
first (for example character and local-map development), then versioned milestones in version first, then versioned milestones in version order, then future/deferred work.
order, then future/deferred work.
### 3. Move Completed Sections to `DONE.md` ### 3. Move Completed Sections to `DONE.md`
@@ -194,12 +265,12 @@ Update `README.md` whenever setup instructions, commands, project structure, or
The root-level `CHANGELOG.md` records the user-facing changes for every release. It exists so players and contributors can see what changed between versions without reading the commit log. The root-level `CHANGELOG.md` records the user-facing changes for every release. It exists so players and contributors can see what changed between versions without reading the commit log.
- Add an entry for every patch, minor, and major version change. - Add an entry for every patch, minor, and major version change.
- Follow Semantic Versioning (`major.minor.patch`): bump major for breaking or vision-level changes, minor for new features, and patch for fixes and small polish. - Follow Semantic Versioning (`major.minor.patch`): bump major only for changes that remove or break an existing player-facing feature, save format, or config contract, or that replace a system listed as a core pillar in PLAN.md; bump minor for new user-facing features; bump patch for fixes and small polish.
- A version increment is not complete until its `CHANGELOG.md` entry, `config/version` update and - A version increment is not complete until its `CHANGELOG.md` entry, `config/version` update and
matching local release build have all been produced and verified. matching local release build have all been produced and verified.
- Group each entry under `Added`, `Changed`, `Fixed`, and `Removed` headings, and date every entry. - Group each entry under `Added`, `Changed`, `Fixed`, and `Removed` headings, and date every entry.
- Describe changes in user-facing terms, not as raw commit messages. - Describe changes in user-facing terms, not as raw commit messages.
- Add the entry when its work ships. If the version number is not yet known, record it under `Unreleased` and move it into a numbered version when the version is tagged. - Add the entry when its work ships. If the version number is not yet known, record it under `Unreleased` as a staging entry; moving it into a numbered version is a version increment and is complete only when the `config/version` update and matching local release build have also been produced and verified (see "Commit, Build and Version Discipline").
When a full executable level-2 milestone/theme in `TODO.md` is implemented, completed, and moved to `DONE.md`: When a full executable level-2 milestone/theme in `TODO.md` is implemented, completed, and moved to `DONE.md`:
@@ -223,13 +294,10 @@ For each task:
8. Commit each coherent, verified change as it is completed. Do not wait until a whole 8. Commit each coherent, verified change as it is completed. Do not wait until a whole
milestone is finished; keep commits small and descriptive and push them when the branch is milestone is finished; keep commits small and descriptive and push them when the branch is
shareable. shareable.
9. On every major, minor or patch version increment: update `config/version`, add the 9. If the change is a release (a major, minor, or patch version increment), follow the Release
`CHANGELOG.md` entry, run the local release build (`tools/build_releases.sh`), verify the Procedure in "Commit, Build and Version Discipline".
artifacts and checksums, then commit, tag and push the version. 10. Push committed changes to the shared repository if applicable.
10. If a level-2 milestone from `TODO.md` has been fully completed, ensure its `CHANGELOG.md` 11. Note the new version, build artifacts or tag in the relevant documentation and handoff
entry and matching build are in place, then create the next semantic version or tag.
11. Push committed changes to the shared repository if applicable.
12. Note the new version, build artifacts or tag in the relevant documentation and handoff
summary. summary.
Avoid unrelated refactors unless they are required for the task or explicitly approved. Avoid unrelated refactors unless they are required for the task or explicitly approved.
@@ -240,12 +308,23 @@ Avoid unrelated refactors unless they are required for the task or explicitly ap
milestone or release is finished. Keep the working tree clean between tasks where possible. milestone or release is finished. Keep the working tree clean between tasks where possible.
- **Push regularly.** Push shareable commits to the shared repository; do not accumulate a long - **Push regularly.** Push shareable commits to the shared repository; do not accumulate a long
local-only history. local-only history.
- **Build every version.** Major, minor and patch increments each require a local release build - **Build every version.** Every major, minor and patch increment follows the Release Procedure
and artifact/checksum verification before tagging. A changelog entry alone is not a release. below; a changelog entry alone is not a release.
- **CI is a second gate, not a substitute.** Tag builds remain automated, but the local build is - **CI is a second gate, not a substitute.** Tag builds remain automated, but the local build is
the required pre-tag check for every version. the required pre-tag check for every version.
- **Unversioned tracks stay unversioned.** Character, map and other development tracks do not get - **Unversioned tracks stay unversioned.** A development track does not get a placeholder
a placeholder version; the version is assigned when the work is scoped into a release. version; the version is assigned when the work is scoped into a release.
**Release Procedure** — follow these steps in order for every major, minor, or patch version
increment:
1. Update `config/version`.
2. Write the `CHANGELOG.md` entry for the version.
3. Run the local release build (`tools/build_releases.sh`).
4. Verify the build artifacts and checksums.
5. Commit the changes.
6. Tag the version.
7. Push the commit and tag.
## Collaboration Rules ## Collaboration Rules
@@ -256,7 +335,7 @@ Avoid unrelated refactors unless they are required for the task or explicitly ap
- Keep documentation synchronized with the implementation. - Keep documentation synchronized with the implementation.
- Mention files changed and checks run in handoff summaries. - Mention files changed and checks run in handoff summaries.
- Commit coherent increments as you go; do not wait until the end of a milestone. - Commit coherent increments as you go; do not wait until the end of a milestone.
- Run a release build whenever a major, minor or patch version is incremented. - Follow the Release Procedure in "Commit, Build and Version Discipline" whenever a major, minor or patch version is incremented.
- Leave follow-up work as checkbox items in `TODO.md` rather than hiding it in prose. - Leave follow-up work as checkbox items in `TODO.md` rather than hiding it in prose.
- If blocked, document the blocker in `MEMORY.md` and add a corresponding task to `TODO.md`. - If blocked, document the blocker in `MEMORY.md` and add a corresponding task to `TODO.md`.
- Avoid overwriting another contributor’s work; inspect recent changes before editing shared files. - Avoid overwriting another contributor’s work; inspect recent changes before editing shared files.
@@ -268,6 +347,10 @@ Before handing off work, an agent must run every check below that applies to the
- Run automated tests. - Run automated tests.
- Run formatting, linting, or type checks. - Run formatting, linting, or type checks.
- Start the game or application and perform a basic smoke test. - Start the game or application and perform a basic smoke test.
- For 3D/Blender changes: `blender_assets.py inspect`, `audit` and `fit`, the relevant capture
gate, and a note of which local skills informed the change.
- If the local Blender skills are not installed, state "no local skills used" in the handoff
and list the skill-free checks that were run instead.
- Check that documentation and task status reflect the actual state. - Check that documentation and task status reflect the actual state.
- Review the final diff for accidental changes or unfinished markers. - Review the final diff for accidental changes or unfinished markers.
+24
View File
@@ -4,6 +4,30 @@ All notable user-facing changes to Gig Line. The format follows
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and versions use [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and versions use
Semantic Versioning. Semantic Versioning.
## [0.9.8] — 2026-11-04
### Fixed
- Characters no longer detach at the wrist: the wrist and hand now track the same
bone, the hand was raised to meet the forearm, and the sleeve cuff follows the
hand instead of the elbow.
- Seated and walking poses no longer collapse the hip/thigh or pinch the knee:
the thigh and shin are rigid to their bones with a short blend at the knee.
## [0.9.7] — 2026-11-04
### Added
- Character development: a more realistic face on all eight library characters
(higher head subdivision, brow ridge, both eyelids, fuller lower lip) and four
crowd-variety characters (`npc_crowd_a`–`d`) with deterministic per-role pools
so the routine crowd no longer clones a single look.
### Fixed
- The NPC pose harness now captures seated, walking and idle deformation (the
harness froze the avatar's process so the FSM could no longer revert the pose).
## [0.10.0-rc.1] — 2026-11-03 ## [0.10.0-rc.1] — 2026-11-03
### Changed ### Changed
+21
View File
@@ -45,6 +45,27 @@ stylized reconstruction. The Joke Shop is a fictional stand-in for the real
Sunset Strip block; the game does not claim endorsement by, or an exact replica Sunset Strip block; the game does not claim endorsement by, or an exact replica
of, any real venue or tenant. of, any real venue or tenant.
### Development-only reference images
The venue reference boards under `docs/screens/refs/` are development documentation and are not
bundled with the game or its release packages. Files under CC BY are attributed here as well as in
their folder sidecar:
- `docs/screens/refs/hollywood/el-capitan-facade-day-wikimedia-2009-10-27.jpg` — "woo (Irvine, CA,
USA)", CC BY 2.0, via Wikimedia Commons.
- `docs/screens/refs/hollywood/el-capitan-theatre-blade-sign-day-wikimedia-2008-10.jpg` — Andreas
Praefcke, CC BY 3.0, via Wikimedia Commons.
- `docs/screens/refs/hollywood/premiere-staging-street-day-wikimedia-2006-02-12.jpg` — John
Barreiros, CC BY 2.0, via Wikimedia Commons.
- Public-domain files in the same folder: Charles W. Beam (1922) and Gary Minnaert (2006).
- `docs/screens/refs/hollywood/el-capitan-theatre-marquee-neighbour-day-wikimedia-2009-07-11.jpg` —
Alan Light, CC BY 2.0, via Wikimedia Commons.
- `docs/screens/refs/hollywood/hollywood-boulevard-night-context-ccbysa.jpg` — Downtowngal,
CC BY-SA 3.0, via Wikimedia Commons; used unmodified for colour/lighting study only, no derivative
asset is made from it.
- CC0 files in the Hollywood folder need no attribution: Luijtenphotos (2019) and Benoît Prieur
(2022).
## AI-assisted images ## AI-assisted images
Surface textures, skyline panoramas, UI art and concept references were produced Surface textures, skyline panoramas, UI art and concept references were produced
+119 -9
View File
@@ -1109,7 +1109,6 @@ Completed 2026-11-01. The follow-ups left over after the texture/skyline adoptio
Completed 2026-11-01. Completed 2026-11-01.
### Storage restructure ### Storage restructure
- [x] Decide the canonical runtime image root (`assets/images/` for UI/scene art): recorded in - [x] Decide the canonical runtime image root (`assets/images/` for UI/scene art): recorded in
@@ -1119,21 +1118,18 @@ Completed 2026-11-01.
- [x] Re-run `godot --headless --path . --import` to regenerate `.import` sidecars after any move. - [x] Re-run `godot --headless --path . --import` to regenerate `.import` sidecars after any move.
- [x] Confirm `.gitignore` still excludes development-only outputs (concepts, Blender sources, raw AI fabrics) under the new layout; Blender `.blend` sources are now untracked and ignored. - [x] Confirm `.gitignore` still excludes development-only outputs (concepts, Blender sources, raw AI fabrics) under the new layout; Blender `.blend` sources are now untracked and ignored.
### Documentation path updates ### Documentation path updates
- [x] Update `README.md` paths (screen-designs section, confirmed-assets links, the `assets/images/scenes` resize example). - [x] Update `README.md` paths (screen-designs section, confirmed-assets links, the `assets/images/scenes` resize example).
- [x] Update `docs/architecture.md`, `PLAN.md`, and ADR references: docs/screens/designs/ is now explicitly the reference-only snapshot; runtime art lives in assets/images/ (ADR-0014). - [x] Update `docs/architecture.md`, `PLAN.md`, and ADR references: docs/screens/designs/ is now explicitly the reference-only snapshot; runtime art lives in assets/images/ (ADR-0014).
- [x] Update `tools/screen_designs.py` docstrings and mark the old paths in `DONE.md` as historical. - [x] Update `tools/screen_designs.py` docstrings and mark the old paths in `DONE.md` as historical.
### Code path updates ### Code path updates
- [x] Point `tools/screen_designs.py generate` at the new design output path and keep `compare`/`judge` reading the right locations. - [x] Point `tools/screen_designs.py generate` at the new design output path and keep `compare`/`judge` reading the right locations.
- [x] Update GDScript `preload()` paths if game textures move (no runtime material/model textures moved; UI art added under assets/images/). - [x] Update GDScript `preload()` paths if game textures move (no runtime material/model textures moved; UI art added under assets/images/).
- [x] Update capture output directories if captures relocate (none did; QA captures stay in docs/screenshots/). - [x] Update capture output directories if captures relocate (none did; QA captures stay in docs/screenshots/).
### Load proposed interfaces + scene art from disk ### Load proposed interfaces + scene art from disk
- [x] Add a central UI/scene art loader (e.g. `src/game/ui/art.gd`) that loads the mockup-derived images from the new runtime root, with a procedural fallback when a file is missing. - [x] Add a central UI/scene art loader (e.g. `src/game/ui/art.gd`) that loads the mockup-derived images from the new runtime root, with a procedural fallback when a file is missing.
@@ -1144,19 +1140,16 @@ Completed 2026-11-01.
- [x] Wire the wand popup to `wand_screening` art. - [x] Wire the wand popup to `wand_screening` art.
- [x] Style the radial menu and finish the remaining HUD chrome against their reference images. - [x] Style the radial menu and finish the remaining HUD chrome against their reference images.
### Verify against the mockups ### Verify against the mockups
- [x] Regenerate the staged captures and run `screen_designs.py compare` (11 good, 0 bad; verified in a clean HEAD worktree). - [x] Regenerate the staged captures and run `screen_designs.py compare` (11 good, 0 bad; verified in a clean HEAD worktree).
- [x] Run `screen_designs.py judge` and clear every `diff` verdict (7 match, 4 review, 0 diff). - [x] Run `screen_designs.py judge` and clear every `diff` verdict (7 match, 4 review, 0 diff).
- [x] Add the capture + compare step as a repeatable smoke so drift is caught early (`tools/check_screenshots.sh`). - [x] Add the capture + compare step as a repeatable smoke so drift is caught early (`tools/check_screenshots.sh`).
## Fix mouse movement bug ## Fix mouse movement bug
- [x] Investigate why mouse input is not being captured or processed correctly in the game window (fixed: `_start_shift()` now calls `_refresh_freeze()`). - [x] Investigate why mouse input is not being captured or processed correctly in the game window (fixed: `_start_shift()` now calls `_refresh_freeze()`).
## Improve in-game pop-ups ## Improve in-game pop-ups
- [x] Improve the visual appearance of in-game pop-ups (start/pause/settings/review/radio/wand/inspection art, buttons, palette, icons, text). - [x] Improve the visual appearance of in-game pop-ups (start/pause/settings/review/radio/wand/inspection art, buttons, palette, icons, text).
@@ -1943,7 +1936,6 @@ Compatibility/Web parity, deterministic assets and offline CI.
carry the texture results; the 0.9.5 section moved to `DONE.md` after the carry the texture results; the 0.9.5 section moved to `DONE.md` after the
release build.) release build.)
Completed 2026-11-02: all 0.9.5 texture and material checks are closed. The NPC Completed 2026-11-02: all 0.9.5 texture and material checks are closed. The NPC
base and eight library characters use 256² maps, cloth/pants use the 4× fabric base and eight library characters use 256² maps, cloth/pants use the 4× fabric
weave without baked-AO blotches, the Walk of Fame band uses the paver/terrazzo weave without baked-AO blotches, the Walk of Fame band uses the paver/terrazzo
@@ -2022,7 +2014,6 @@ target paths and leave a clean release-candidate handoff.
- [x] Exit: combined build is functionally green, visually reviewed, performance - [x] Exit: combined build is functionally green, visually reviewed, performance
measured and ready for the 0.10.0 content-lock/playtest phase. measured and ready for the 0.10.0 content-lock/playtest phase.
Completed 2026-11-03: the 0.9.6 integration checkpoint is closed. The current Completed 2026-11-03: the 0.9.6 integration checkpoint is closed. The current
asset set re-imported and passed `blender_assets.py audit`/`fit` and asset set re-imported and passed `blender_assets.py audit`/`fit` and
`npc_pipeline.py audit`; the full suite is 263/263 with 101/101 Python tests and `npc_pipeline.py audit`; the full suite is 263/263 with 101/101 Python tests and
@@ -2033,3 +2024,122 @@ with a 0.291 Pillow gap. A clean worktree built Linux/Windows/macOS/Web/HQ at
161.5/197.1/148.0/97.8/241.5 MB; the Web zip and HQ override were checked and 161.5/197.1/148.0/97.8/241.5 MB; the Web zip and HQ override were checked and
the HQ binary launched headless. Tagged `v0.9.6`; Gitea run 1296 passed checks the HQ binary launched headless. Tagged `v0.9.6`; Gitea run 1296 passed checks
and the full build and published seven assets. and the full build and published seven assets.
## Character development
Completed 2026-11-04. The procedural crowd-variety roster (four new variants, per-role pools)
shipped with the realistic face; the external-asset intake and the MakeHuman body pipeline were
promoted to the active **MakeHuman character pipeline** track in `TODO.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 and local map 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
- [x] 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`.)
- [x] 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 and `MEMORY.md`.)
- [x] 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 in `CREDITS.md`.)
- [x] Decide whether the external preview sheet stays local under `tmp/` or is committed with
the required CC-BY attribution. (Committed as
`docs/blender_previews/sheet_npc_sources_research.jpg` with Cesium CC-BY attribution;
the project-owned crowd prototype sheet is also committed.)
### Intake and validation
- [x] Add a Blender `inspect` path 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; `--json` and `--category` supported.
Seven synthetic contract tests added; all 46 library GLBs inspect clean. `audit` remains
the final gate.)
- [x] `adapt` path: promoted to the **MakeHuman character pipeline** track (2026-11-04).: scale/ground, weld seams, decimate, map the
five tint slots, and either rebuild the contract armature or record an explicit second-rig
contract. Use `retopology`/`rigging`/`uv-workflow` guidance 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.
- [x] Audit gate + intake regression test: promoted to the **MakeHuman character pipeline** track.
- [x] Adapter documentation: promoted to the **MakeHuman character pipeline** track.
### Quaternius prototype
- [x] 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`.)
- [x] Measure the prototype against the `npc_casual` controls: 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.)
- [x] 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
- [x] Approve four crowd-variety looks (build, head silhouette, hair/beard, outer layer and
accessory; no clothing that labels the NPC's behaviour). (`npc_crowd_a` bun/slim/sunglasses,
`npc_crowd_b` bald/broad/beard/shoulder bag, `npc_crowd_c` coat/umbrella, `npc_crowd_d`
hood/cup; prototype sheet committed.)
- [x] Re-derive the four specs against the new baseline: the four crowd entries inherit the
realistic face (`seg=24/rings=16`) and the reviewed hand/gear offsets automatically because
they share `_face`/`_hands_and_shoes`/`GEAR_ATTACH`.
- [x] Generate the four variants: built via `blender_assets.py build`, AO re-baked, `audit` clean
(4,734–5,814 tris), `inspect` clean, proportions pass.
- [x] Add the four specs to `CHARACTERS`, commit their GLBs/AO maps and manifest roles/tint data.
(Note: this adds ~2 MB to the next release build via `export_filter=all_resources` — accepted
for the crowd-variety roster.)
- [x] Per-role pools: `character_model_for()` now picks from `CHARACTER_POOLS` by seed — the
routine crowd roles gain the crowd variants (tourist → casual/crowd_a/crowd_d,
confused_visitor → casual/crowd_b, intoxicated → casual/crowd_c) while the special roles
keep their existing alternation (guest ⅓ jacket, trespasser/threat ½ hoodie). The test
now checks seed-stability plus that every pool entry resolves to a committed GLB
(277/277).
- [x] Gear fit + inspect for the four new variants: `fit` is clean (sunglasses band=inside,
shoulder bag clear; cup/umbrella are hand gear with the forward offset), `inspect` clean,
proportions pass.
- [x] Crowd-variety reference: five licence-cleared Commons photos fetched to
`tmp/research/crowd-variety/`; the AI proposal set stays the next step for detail.
- [x] Baseline + portrait rows: the four variants are in `capture_npc_baseline.gd` and
`sheet_npc_baseline.jpg` (12 variants × 6 views); review-doc rows added.
### QA and release
- [x] Gates with the expanded library: 24-NPC budget smoke 152,464 tris / 168 meshes / 6.94 ms
(under 50 ms), portrait baseline 12 variants × 6 views, `fit` clean, Godot 277/277, Python
160/160. No release build is created for this unversioned track.
- [x] Docs: `docs/development-status.md`, `docs/3d-model-review.md` and the baseline sheet updated;
`CREDITS.md` needs no change (the crowd variants are procedural, no new source). Accepted
visual limits: the crowd accessories (umbrella canopy, cup, sunglasses, beard) read at
full-body distance but not in the head-only portrait framing.
- [x] Exit: the 12-character library passes contract audit, portrait/gear acceptance, the 24-NPC
budget and licence/provenance review; the runtime contract (13 bones, five tint slots,
`npc_base` fallback) is unchanged.
### Deferred MakeHuman local pipeline
- [x] 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.)
- [x] Body-shape diversity decision (2026-11-04, owner): **yes** — use MakeHuman for the next
character pass. Promoted to the **MakeHuman character pipeline** track.
+169 -922
View File
File diff suppressed because it is too large. Load diff
+2 -2
View File
@@ -144,7 +144,7 @@ Joke Shop escalation follows the common ladder: direction, explanation, repeat r
### Hollywood Boulevard Late Night TV Studio ### Hollywood Boulevard Late Night TV Studio
A busy studio entrance with audience members, production staff, performers, guests, deliveries, celebrity arrivals, tourists, influencers, and the same range of street behavior as the building scenario. A busy studio entrance at the same real El Capitan Entertainment Centre block as the Hollywood day shift, restaged for a late-night arrival: the same stone facade and steps with a bulb-lit canopy, a black car at the kerb and a barrier line. It has audience members, production staff, performers, guests, deliveries, celebrity arrivals, tourists, influencers, and the same range of street behavior as the building scenario.
Staff and guests are recognized or present a wristband, credential, ticket, guest-list confirmation, or other approved marker. The player keeps the steps clear, protects arrivals and equipment, manages filming boundaries, watches for tailgating, and calls for help only when there is immediate danger. Staff and guests are recognized or present a wristband, credential, ticket, guest-list confirmation, or other approved marker. The player keeps the steps clear, protects arrivals and equipment, manages filming boundaries, watches for tailgating, and calls for help only when there is immediate danger.
@@ -170,7 +170,7 @@ The action wheel prioritizes de-escalation: Stop, Look, Point, No, Ask, Inspect,
The visual direction is readable stylized realism: The visual direction is readable stylized realism:
- **Character direction:** 8 skinned NPC variants, 18 gear pieces and 20 street/venue props, with four crowd-variety variants prototyped. The generator-first expansion is the active character track ([ADR-0015](docs/adr/0015-npc-model-variety-sourcing.md)); Quaternius is a reference and MakeHuman is deferred to a local pipeline. - **Character direction:** 8 skinned NPC variants, 18 gear pieces and 20 street/venue props, with four crowd-variety variants prototyped. The generator-first expansion is the active character track ([ADR-0015](docs/adr/0015-npc-model-variety-sourcing.md)); Quaternius is a reference and MakeHuman is deferred to a local pipeline.
- **Realism pass:** AI-assisted per-phase skyline panoramas, v2 surface tiles with normal maps, wet asphalt at night, a warm day haze, phase-specific sun/exposure/fog, a visible flashlight beam, and denser foliage. - **Realism pass:** AI-assisted per-phase skyline panoramas, v2 surface tiles with normal maps, wet asphalt at night, a warm day haze, phase-specific sun/exposure/fog, a tight flashlight spot (no beam geometry), and denser foliage.
- **Local map direction:** the venues are currently stylized reconstructions. The local-map track evaluates licensed OpenStreetMap/3D building data, licensed reference photography, AI-assisted composition and Gaussian splatting as a development tool; online data and splat rendering are not runtime dependencies. - **Local map direction:** the venues are currently stylized reconstructions. The local-map track evaluates licensed OpenStreetMap/3D building data, licensed reference photography, AI-assisted composition and Gaussian splatting as a development tool; online data and splat rendering are not runtime dependencies.
- **References and QA:** runtime UI art lives in `assets/images/ui/`; reference/art-direction sets live in `docs/screens/designs/` and `docs/screens/concepts/`; captures live in `docs/screenshots/`; realism runs live in `docs/screens/realism/`. `screen_designs.py compare/judge` and `tools/check_screenshots.sh` guard drift. - **References and QA:** runtime UI art lives in `assets/images/ui/`; reference/art-direction sets live in `docs/screens/designs/` and `docs/screens/concepts/`; captures live in `docs/screenshots/`; realism runs live in `docs/screens/realism/`. `screen_designs.py compare/judge` and `tools/check_screenshots.sh` guard drift.
- **Storage convention:** see [ADR-0014](docs/adr/0014-runtime-image-root.md). Never overwrite an existing image; new outputs get a new path or `-vN` suffix. - **Storage convention:** see [ADR-0014](docs/adr/0014-runtime-image-root.md). Never overwrite an existing image; new outputs get a new path or `-vN` suffix.
+58 -17
View File
@@ -10,27 +10,12 @@ The central design goal is simple:
The active planning order lives in [`TODO.md`](TODO.md) and [`AGENTS.md`](AGENTS.md): The active planning order lives in [`TODO.md`](TODO.md) and [`AGENTS.md`](AGENTS.md):
1. **Character development** — crowd, age, build, hair and outfit variety on the owned procedural library, keeping the frozen NPC contract. Source evaluation and the licence decision are in [`docs/npc-model-sourcing.md`](docs/npc-model-sourcing.md). 1. **3D model and local map re-evaluation** — score every shipped asset, then evaluate licensed OpenStreetMap/3D data, reference-derived photoreal facades, AI-assisted composition and a Gaussian-splatting development evaluation.
2. **Local map development** — licensed OpenStreetMap/3D data, reference-derived photoreal facades, AI-assisted composition and a Gaussian-splatting development evaluation. 2. **Character development** — crowd, age, build, hair and outfit variety on the owned procedural library, keeping the frozen NPC contract. Source evaluation and the licence decision are in [`docs/npc-model-sourcing.md`](docs/npc-model-sourcing.md).
3. **Versioned release hardening** — the 0.10.0 release candidate and later semantic versions follow the unversioned development tracks. 3. **Versioned release hardening** — the 0.10.0 release candidate and later semantic versions follow the unversioned development tracks.
Versions are assigned only when a track's scope is accepted into a release. Every major, minor and patch version requires a changelog entry, a local release build and artifact verification before tagging. Versions are assigned only when a track's scope is accepted into a release. Every major, minor and patch version requires a changelog entry, a local release build and artifact verification before tagging.
## Screenshots
| | |
| --- | --- |
| ![Venue overview: the El Capitan Entertainment Centre facade with six Ionic columns, red banners and stone steps](docs/screenshots/01-venue-overview.png) | ![Targeting an approaching NPC with the interaction HUD](docs/screenshots/02-targeting-npc.png) |
| ![Access inspection: wristband/credential check with allow/deny prompt](docs/screenshots/03-access-inspection.png) | ![Radio report form: emergency dispatch panel](docs/screenshots/04-radio-report.png) |
| ![Late night: street lamps lit, marquee glowing, dark Hollywood Boulevard](docs/screenshots/05-late-night-avenue.png) | ![Night shift: guard flashlight cutting through the dark](docs/screenshots/06-night-flashlight.png) |
| ![Wand screening at The Joke Shop: false alarm on keys](docs/screenshots/07-wand-screening.png) | ![Escalation HUD at L3 with body camera armed and reaction log](docs/screenshots/08-escalation-hud.png) |
| ![Body-camera timeline: formal warning, body camera on, blocking](docs/screenshots/09-body-camera-timeline.png) | ![Prop gallery: the six generated street-furniture models on a studio backdrop](docs/screenshots/10-prop-gallery.png) |
| ![Precision walk at the venue steps with the HUD chip visible](docs/screenshots/11-precision-walk.png) | ![The Joke Shop: a black Sunset Strip club under its signature canopy at night](docs/screenshots/12-joke-shop.png) |
| ![Late-night TV studio arrival: stone facade, bulb canopy, black car and barriers](docs/screenshots/13-studio-arrival.png) | |
*Screenshots are generated by [`src/test/capture_screenshots.gd`](src/test/capture_screenshots.gd) and [`src/test/capture_prop_gallery.gd`](src/test/capture_prop_gallery.gd) from the current build — day, late-night, wand screening, escalation, shift-review timeline,
precision walk, the Joke Shop's Sunset Strip frontage, the TV Studio arrival, and the prop lineup.*
## ⬇️ Downloads ## ⬇️ Downloads
| Platform | Package | | Platform | Package |
@@ -70,6 +55,59 @@ If you are here to develop or test locally instead of downloading, jump to
The project is under active development. The design and architecture are documented, and a playable prototype vertical slice exists (Godot 4 + GDScript): a stylized El Capitan Entertainment Centre block, a first-person guard, simulated NPCs with intents and reactions, the six-level escalation model, access inspection and admission decisions, radio calls with credibility checks, reputation, crowd mood, and an end-of-shift review. The project is under active development. The design and architecture are documented, and a playable prototype vertical slice exists (Godot 4 + GDScript): a stylized El Capitan Entertainment Centre block, a first-person guard, simulated NPCs with intents and reactions, the six-level escalation model, access inspection and admission decisions, radio calls with credibility checks, reputation, crowd mood, and an end-of-shift review.
## Screenshots
Every capture is rendered from the current build by [`tools/check_screenshots.sh`](tools/check_screenshots.sh)
(21 captures, compared against the runtime art). The full gallery, including every UI state, is in
[`docs/screenshots/`](docs/screenshots/README.md).
### Venues
| | |
| --- | --- |
| ![Hollywood Boulevard day shift](docs/screenshots/01-venue-overview.png) | **Hollywood Boulevard — day.** The El Capitan Entertainment Centre block: six Ionic columns, Masonic parapet, event banners, eight stone steps and the Walk of Fame terrazzo. |
| ![Hollywood Boulevard at night](docs/screenshots/05-late-night-avenue.png) | **Hollywood Boulevard — late.** Sconces pool on the limestone, street lamps light the boulevard and the skyline fades into night haze. |
| ![Flashlight on the entrance at night](docs/screenshots/06-night-flashlight.png) | **Night patrol.** A tight flashlight spot picks out the door and the person in front of it; movement and awareness change at night. |
| ![The Joke Shop at night](docs/screenshots/12-joke-shop.png) | **The Joke Shop.** A black Sunset Strip club under its signature-covered canopy, circular blade sign, red curtains and the dry hillside behind. |
| ![Late-night TV studio arrival](docs/screenshots/13-studio-arrival.png) | **TV Studio arrival.** Stone facade, bulb canopy, black car and crowd barriers for a late celebrity arrival. |
### Interaction and systems
| | |
| --- | --- |
| ![Targeting an NPC](docs/screenshots/02-targeting-npc.png) | **Focus and targeting.** The cone focus ring, name tag and target chip; `Tab`/wheel cycles nearby people without aiming. |
| ![Access inspection](docs/screenshots/03-access-inspection.png) | **Access inspection.** A venue-correct wristband check with evidence shown before the admit/refuse decision. |
| ![Radio report](docs/screenshots/04-radio-report.png) | **Radio report.** Security assistance with location, behaviour and what was actually seen. |
| ![Wand screening](docs/screenshots/07-wand-screening.png) | **Wand screening.** A false alarm on keys: ask the guest to identify the item before choosing a response. |
| ![Escalation HUD](docs/screenshots/08-escalation-hud.png) | **Escalation.** Level 3 blocking with the shape meter, body camera armed and the reaction log. |
| ![Body-camera timeline](docs/screenshots/09-body-camera-timeline.png) | **Body-camera timeline.** Every recorded event, step by step, in the shift review. |
| ![Precision walk](docs/screenshots/11-precision-walk.png) | **Precision walk.** Half-speed close work on the steps, with the HUD state chip visible. |
### Shell and UI
| | |
| --- | --- |
| ![Start menu](docs/screenshots/14-start-menu.png) | **Venue menu.** Day and night rows for Hollywood, the Joke Shop and the TV Studio, campaign continue and review links. |
| ![Settings](docs/screenshots/16-settings-panel.png) | **Settings.** Difficulty, volumes, HUD scale, reduce motion, captions and key/button remapping, all persisted. |
| ![Shift review](docs/screenshots/17-shift-review.png) | **Shift review.** Grade, policy outcome, incidents, responder results and campaign Continue. |
| ![Action wheel](docs/screenshots/19-radial-menu.png) | **Action wheel.** De-escalation first: stop, look, point, no, ask, inspect, warn, block, reason, recognize, radio. |
### 3D asset progress
The character, gear and prop libraries are authored procedurally in Blender and audited before use;
the sheets below track their visual progress.
| | |
| --- | --- |
| ![Eight NPC characters](docs/blender_previews/sheet_npc.jpg) | **Character library.** Eight skinned variants (4.5–5.5k triangles each) with five tint slots, attach-point gear and baked maps. |
| ![Prop library](docs/blender_previews/sheet_props.jpg) | **Street and venue props.** Twenty library props with colliders, navigation avoidance and colour atlases. |
| ![Neutral NPC baseline](docs/blender_previews/sheet_npc_baseline.jpg) | **Neutral baseline.** 8 characters × 6 views (front, three-quarter, profile, back, full body, crowd) used for the 0.9.4 pass and the current re-evaluation. |
| ![Texture refinement comparison](docs/blender_previews/sheet_texture_refinement_0.9.5.jpg) | **Texture refinement.** 128 → 256 px NPC maps and a 4× fabric weave, shown before/after on the same camera. |
| ![Crowd-variety prototypes](docs/blender_previews/sheet_npc_crowd_prototypes.jpg) | **Crowd variety prototypes.** Four approved looks (bun/slim, bald/broad, coat/umbrella, hood/cup) queued for the roster build. |
More sheets and the review criteria are in [`docs/blender_previews/`](docs/blender_previews/README.md)
and [`docs/3d-model-review.md`](docs/3d-model-review.md).
## Game Overview ## Game Overview
A typical shift lasts 10–15 minutes: watch the entrance and sidewalk, judge why A typical shift lasts 10–15 minutes: watch the entrance and sidewalk, judge why
@@ -131,6 +169,9 @@ Full setup, every run/test/smoke command, and the controls table are in
- [`docs/joke-shop-map.md`](docs/joke-shop-map.md) — Real-site references, game mapping and limitations for the Joke Shop / Sunset Strip venue. - [`docs/joke-shop-map.md`](docs/joke-shop-map.md) — Real-site references, game mapping and limitations for the Joke Shop / Sunset Strip venue.
- [`docs/tutorial.md`](docs/tutorial.md) — First-shift tutorial beats and rules. - [`docs/tutorial.md`](docs/tutorial.md) — First-shift tutorial beats and rules.
- [`docs/asset-tooling.md`](docs/asset-tooling.md) — Asset pipelines, model tools, and screenshot gates. - [`docs/asset-tooling.md`](docs/asset-tooling.md) — Asset pipelines, model tools, and screenshot gates.
- [`tools/README.md`](tools/README.md) — Tool inventory, categories, test commands and AI-skill evaluation.
- [`.agents/skills/gig-line-blender-asset-contract`](.agents/skills/gig-line-blender-asset-contract/SKILL.md) — tracked AI skill for Blender/NPC/gear asset work.
- [`.agents/skills/gig-line-release-qa`](.agents/skills/gig-line-release-qa/SKILL.md) — tracked AI skill for release and visual-QA work.
- [`docs/getting-started.md`](docs/getting-started.md) — Setup, run/test commands, and controls. - [`docs/getting-started.md`](docs/getting-started.md) — Setup, run/test commands, and controls.
- [`docs/development-status.md`](docs/development-status.md) — Implemented features and what's next. - [`docs/development-status.md`](docs/development-status.md) — Implemented features and what's next.
- [`docs/accessibility.md`](docs/accessibility.md) — Accessibility features, known gaps and statement. - [`docs/accessibility.md`](docs/accessibility.md) — Accessibility features, known gaps and statement.
+815 -272
View File
File diff suppressed because it is too large. Load diff
+197 -55
View File
@@ -48,28 +48,6 @@
"triangles": 380, "triangles": 380,
"vertices": 408 "vertices": 408
}, },
"beanie": {
"attach": "head",
"bounds_godot": {
"max": [
0.193,
0.215,
0.183
],
"min": [
-0.193,
0.014,
-0.203
]
},
"category": "npc_gear",
"materials": [
"plastic_grey"
],
"path": "assets/models/blender/npc_gear/beanie.glb",
"triangles": 460,
"vertices": 403
},
"bench": { "bench": {
"bounds_godot": { "bounds_godot": {
"max": [ "max": [
@@ -96,14 +74,14 @@
"bollard": { "bollard": {
"bounds_godot": { "bounds_godot": {
"max": [ "max": [
0.105, 0.125,
0.975, 0.975,
0.105 0.125
], ],
"min": [ "min": [
-0.105, -0.125,
0, 0,
-0.105 -0.125
] ]
}, },
"category": "props", "category": "props",
@@ -114,7 +92,7 @@
"path": "assets/models/blender/props/bollard.glb", "path": "assets/models/blender/props/bollard.glb",
"replaces": "generated/bollard.glb", "replaces": "generated/bollard.glb",
"triangles": 138, "triangles": 138,
"vertices": 225 "vertices": 221
}, },
"camera": { "camera": {
"attach": "hand", "attach": "hand",
@@ -262,14 +240,14 @@
"fire_hydrant": { "fire_hydrant": {
"bounds_godot": { "bounds_godot": {
"max": [ "max": [
0.24, 0.265,
0.76, 0.815,
0.19 0.235
], ],
"min": [ "min": [
-0.24, -0.265,
0, 0,
-0.19 -0.235
] ]
}, },
"category": "props", "category": "props",
@@ -279,8 +257,8 @@
], ],
"path": "assets/models/blender/props/fire_hydrant.glb", "path": "assets/models/blender/props/fire_hydrant.glb",
"replaces": "generated/fire_hydrant.glb", "replaces": "generated/fire_hydrant.glb",
"triangles": 466, "triangles": 610,
"vertices": 725 "vertices": 902
}, },
"firefighter_helmet": { "firefighter_helmet": {
"attach": "head", "attach": "head",
@@ -439,14 +417,15 @@
"category": "props", "category": "props",
"materials": [ "materials": [
"news_blue", "news_blue",
"dark_metal",
"glass", "glass",
"paper", "paper",
"steel" "steel"
], ],
"path": "assets/models/blender/props/newspaper_box.glb", "path": "assets/models/blender/props/newspaper_box.glb",
"replaces": "generated/newspaper_box.glb", "replaces": "generated/newspaper_box.glb",
"triangles": 244, "triangles": 300,
"vertices": 528 "vertices": 648
}, },
"npc_casual": { "npc_casual": {
"bounds_godot": { "bounds_godot": {
@@ -487,8 +466,8 @@
"accessory", "accessory",
"hair" "hair"
], ],
"triangles": 4482, "triangles": 5034,
"vertices": 4260 "vertices": 4607
}, },
"npc_coat": { "npc_coat": {
"bounds_godot": { "bounds_godot": {
@@ -528,8 +507,168 @@
"accessory", "accessory",
"hair" "hair"
], ],
"triangles": 5474, "triangles": 6046,
"vertices": 5264 "vertices": 5645
},
"npc_crowd_a": {
"bounds_godot": {
"max": [
0.288,
1.825,
0.189
],
"min": [
-0.288,
0,
-0.195
]
},
"category": "npc",
"layer": "none",
"materials": [
"skin",
"cloth",
"pants",
"accessory",
"eye_white",
"hair",
"rubber"
],
"mesh_node": "npc_base",
"path": "assets/models/blender/npc/npc_crowd_a.glb",
"roles": [
"tourist",
"guest"
],
"tint_slots": [
"skin",
"cloth",
"pants",
"accessory",
"hair"
],
"triangles": 5284,
"vertices": 4908
},
"npc_crowd_b": {
"bounds_godot": {
"max": [
0.358,
1.809,
0.189
],
"min": [
-0.358,
0,
-0.155
]
},
"category": "npc",
"layer": "none",
"materials": [
"skin",
"cloth",
"pants",
"accessory",
"eye_white",
"hair",
"rubber"
],
"mesh_node": "npc_base",
"path": "assets/models/blender/npc/npc_crowd_b.glb",
"roles": [
"confused_visitor",
"guest"
],
"tint_slots": [
"skin",
"cloth",
"pants",
"accessory",
"hair"
],
"triangles": 4812,
"vertices": 4550
},
"npc_crowd_c": {
"bounds_godot": {
"max": [
0.332,
1.824,
0.189
],
"min": [
-0.332,
0,
-0.18
]
},
"category": "npc",
"layer": "coat",
"materials": [
"skin",
"cloth",
"pants",
"accessory",
"eye_white",
"hair",
"rubber"
],
"mesh_node": "npc_base",
"path": "assets/models/blender/npc/npc_crowd_c.glb",
"roles": [
"intoxicated",
"guest"
],
"tint_slots": [
"skin",
"cloth",
"pants",
"accessory",
"hair"
],
"triangles": 5690,
"vertices": 5510
},
"npc_crowd_d": {
"bounds_godot": {
"max": [
0.293,
1.856,
0.189
],
"min": [
-0.293,
0,
-0.225
]
},
"category": "npc",
"layer": "hood",
"materials": [
"skin",
"cloth",
"pants",
"accessory",
"eye_white",
"hair",
"rubber"
],
"mesh_node": "npc_base",
"path": "assets/models/blender/npc/npc_crowd_d.glb",
"roles": [
"tourist",
"guest"
],
"tint_slots": [
"skin",
"cloth",
"pants",
"accessory",
"hair"
],
"triangles": 5810,
"vertices": 5444
}, },
"npc_dress": { "npc_dress": {
"bounds_godot": { "bounds_godot": {
@@ -567,8 +706,8 @@
"accessory", "accessory",
"hair" "hair"
], ],
"triangles": 4900, "triangles": 5540,
"vertices": 4719 "vertices": 5073
}, },
"npc_firefighter": { "npc_firefighter": {
"bounds_godot": { "bounds_godot": {
@@ -608,8 +747,8 @@
"accessory", "accessory",
"hair" "hair"
], ],
"triangles": 5344, "triangles": 5888,
"vertices": 5494 "vertices": 5785
}, },
"npc_guard": { "npc_guard": {
"bounds_godot": { "bounds_godot": {
@@ -652,8 +791,8 @@
"accessory", "accessory",
"hair" "hair"
], ],
"triangles": 5046, "triangles": 5670,
"vertices": 5096 "vertices": 5671
}, },
"npc_hoodie": { "npc_hoodie": {
"bounds_godot": { "bounds_godot": {
@@ -693,8 +832,8 @@
"accessory", "accessory",
"hair" "hair"
], ],
"triangles": 5304, "triangles": 5864,
"vertices": 4950 "vertices": 5325
}, },
"npc_jacket": { "npc_jacket": {
"bounds_godot": { "bounds_godot": {
@@ -734,8 +873,8 @@
"accessory", "accessory",
"hair" "hair"
], ],
"triangles": 4872, "triangles": 5432,
"vertices": 4661 "vertices": 5225
}, },
"npc_vest": { "npc_vest": {
"bounds_godot": { "bounds_godot": {
@@ -775,8 +914,8 @@
"accessory", "accessory",
"hair" "hair"
], ],
"triangles": 4980, "triangles": 5532,
"vertices": 4879 "vertices": 5195
}, },
"palm_tree": { "palm_tree": {
"bounds_godot": { "bounds_godot": {
@@ -794,7 +933,8 @@
"category": "props", "category": "props",
"materials": [ "materials": [
"palm_bark", "palm_bark",
"palm_leaf" "palm_leaf",
"palm_leaf_dark"
], ],
"path": "assets/models/blender/props/palm_tree.glb", "path": "assets/models/blender/props/palm_tree.glb",
"triangles": 400, "triangles": 400,
@@ -840,7 +980,8 @@
"materials": [ "materials": [
"stone_pot", "stone_pot",
"soil", "soil",
"foliage" "foliage",
"foliage_dark"
], ],
"path": "assets/models/blender/props/planter_box.glb", "path": "assets/models/blender/props/planter_box.glb",
"replaces": "generated/planter_box.glb", "replaces": "generated/planter_box.glb",
@@ -913,7 +1054,8 @@
"category": "props", "category": "props",
"materials": [ "materials": [
"stone_pot", "stone_pot",
"foliage" "foliage",
"foliage_dark"
], ],
"path": "assets/models/blender/props/round_planter.glb", "path": "assets/models/blender/props/round_planter.glb",
"triangles": 1240, "triangles": 1240,
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 922 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 639 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 501 KiB

+299
View File
@@ -0,0 +1,299 @@
# 3D model review (2026-11-03)
Status: **baseline measured; scorecard open.** This is the working document for the unversioned
`3D model re-evaluation` track in [`TODO.md`](../TODO.md). It records what was measured, what the
Blender skill guidance says the targets are, the ranked candidate gaps, and the decisions that
still need the project owner. Nothing here re-opens the accepted 0.9.4 limits by itself.
Related documents: [`npc-visual-review.md`](npc-visual-review.md) (accepted 0.9.4 limits and
before/after sheets), [`npc-proportion-audit.md`](npc-proportion-audit.md) (proportion guide),
[`blender-assets.md`](blender-assets.md) (asset contract), [`asset-tooling.md`](asset-tooling.md)
(commands).
## Method and skill routing
The review is screenshot- and measurement-backed, following `qa-review` (screenshot set, defect
severity, explicit verdict) rather than an opinion pass:
| Family | Skills loaded | Criteria taken from them |
| --- | --- | --- |
| Routing and pipeline | `blender-director` | Plan → blockout → detail → validate → export; MCP steps translated to headless flatpak runs |
| Characters | `character-artist`, `retopology`, `rigging` | Eye/mouth/jaw/shoulder loops, quad-dominant deformation surfaces, 3-loop joints, no triangles on primary deformers |
| UVs and textures | `uv-workflow`, `texture-workflow`, `materials` | Texel-density tiers (hero 512–1024, standard 256–512, background 128–256 px/m), consistent density, no overlapping UVs |
| Budgets and structure | `asset-optimization`, `lod-pipeline` | Triangle/vertex budgets, naming, LOD tiers |
| Props, gear, foliage | `prop-artist`, `hard-surface`, `vegetation-artist` | Silhouette read, bevel/chamfer language, collision proxies, carded foliage |
| Look and verdict | `lookdev`, `qa-review` | Day/night beauty captures, ship / ship-with-notes / no-ship verdict |
Project contract and gates stay authoritative; see `AGENTS.md` §Local Blender skills. The skills
assume Blender MCP, which this project does not use: everything below came from the headless
`tools/blender_assets.py` / `tools/npc_pipeline.py` pipelines plus the Godot capture harnesses.
## What was captured and measured (2026-11-03)
| Evidence | Command | Result |
| --- | --- | --- |
| Contract audit | `python3 tools/blender_assets.py audit --json` | 46/46 assets clean; library 59,012 tris |
| Imported-GLB inspection | `blender_assets.py inspect` (all 46) | All clean; transforms applied, helpers ignored |
| Gear fit | `python3 tools/blender_assets.py fit --json` | Head width 0.315 m on all eight; clothing radius 0.190–0.260 m |
| Proportions | `python3 tools/npc_proportions.py report --json` | All eight inside the stylized guide |
| Texel density | `python3 tools/blender_assets.py texels --json` | New measurement, table below |
| Neutral baseline | `capture_npc_baseline.gd` → `tmp/model-baseline` (48 frames) + `npc_baseline.py sheet` | 48 frames, none blank; sheet in `tmp/` only |
| Final context | `capture_npc_review.gd` → `tmp/model-review` (96 frames) | 96 frames, none blank; raw frames stay local |
| Performance | `smoke_npc_budget.gd` | 24 avatars, 168 meshes, 152,464 tris, 6.94 ms of 50 ms |
Raw captures and JSON stay in the gitignored `tmp/`; committed review images remain the
`docs/blender_previews/sheet_*.jpg` set from 0.9.4/0.9.5 until a fix actually lands.
## Character measurements
Contract numbers from `audit` + `inspect`; density from `texels` (256² slot maps, authored and
with the runtime 4× fabric repeat).
| Character | Tris / verts | Height / feet | Materials | Authored td (px/m) | Fabric effective (px/m) | Verdict |
| --- | --- | --- | --- | --- | --- | --- |
| `npc_casual` | 5,038 / 4,756 | 1.824 / +0.000 | 7 | 106.8–122.2 | 429–440 | Contract pass; face prototype |
| `npc_jacket` | 5,428 / 5,071 | 1.824 / +0.000 | 7 | 100.3–113.7 | 409–413 | Contract pass; face prototype |
| `npc_coat` | 6,030 / 5,802 | 1.824 / +0.000 | 7 | 75.3–81.4 | 307–310 | Contract pass; face prototype |
| `npc_vest` | 5,536 / 5,375 | 1.819 / +0.000 | 9 | 85.5–99.3 | 362–366 | Contract pass; face prototype |
| `npc_dress` | 5,456 / 5,128 | 1.825 / +0.000 | 7 | 81.9–89.0 | 338–339 | Contract pass; face prototype |
| `npc_hoodie` | 5,860 / 5,492 | 1.856 / +0.000 | 7 | 89.5–98.6 | 359–364 | Contract pass; face prototype |
| `npc_firefighter` | 5,900 / 5,902 | 1.819 / +0.000 | 9 | 64.0–75.1 | 287–290 | Contract pass; face prototype (helmet shadow hides the lower lip) |
| `npc_guard` | 5,602 / 5,684 | 1.819 / +0.000 | 11 | 90.0–100.8 | 374–374 | Contract pass; face prototype |
| `npc_crowd_a` | 5,200 / 4,734 | 1.825 / +0.000 | 7 | 107–120 | 431–435 | Contract pass; crowd prototype |
| `npc_crowd_b` | 4,734 / 4,353 | 1.809 / +0.000 | 7 | 107–118 | 434–439 | Contract pass; crowd prototype |
| `npc_crowd_c` | 5,674 / 5,440 | 1.824 / +0.000 | 7 | 76–83 | 317 | Contract pass; crowd prototype |
| `npc_crowd_d` | 5,814 / 5,300 | 1.856 / +0.000 | 7 | 92–106 | 377–381 | Contract pass; crowd prototype |
| `npc_base` (fallback) | 1,204 / 2,488 | 1.836 / +0.000 | 5 | 70.1–72.9 | 4× on fabric | Contract pass; far below its 6,000/4,000 cap |
Blender-side `inspect` counts can differ by ±1 vertex from the glTF accessor count in `audit`
(normal-split rounding); both are recorded and neither changes a verdict.
Readings:
- Every character is inside 8,000/8,000 with the farthest at 5,474 tris (68% of budget) and 5,494
verts (69%), so there is headroom for targeted topology detail without a cap change.
- Surface area tracks clothing volume: the firefighter coat is the largest body (4.28 m²) and has
the lowest authored density; `npc_casual` is the smallest (2.44 m²) and the highest.
- **Authored density (64–122 px/m) sits below the skill's background tier (128–256 px/m).** The
runtime tint controls most of the look: `skin`, `hair`, `accessory` and the fixed detail slots
are neutral maps tinted at runtime, not painted skin, so density mostly controls subtle
weave/noise. Fabric is effective 287–440 px/m (standard tier) because of the 4× repeat. This is
a recorded note, not a defect, until a portrait shows texture starvation.
- Material counts 7–11 per character are fixed detail slots (eyes, rubber, hivis, reflective,
leather, metal), not extra tint slots.
## Scorecard skeleton
Verdicts use `qa-review` semantics: **P0** (blocker: wrong scale, broken normals, budget fail),
**P1** (major: silhouette/readability), **P2** (minor), **accept** (recorded limit). `—` means not
yet reviewed; this document is the place to fill it.
### Characters
| Character | Silhouette | Face @1.85 m | Hands/grip | Weights/pose | Cloth/hair | LOD | Verdict |
| --- | --- | --- | --- | --- | --- | --- | --- |
| *(pose captured 2026-11-04: see "Pose evidence" below)* | | | | | | | |
| `npc_casual` | accept (0.9.4) | accept (face prototype) | accept (open palm) | fixed (wrist/hand + hip/knee) | accept | accept (two-quad impostor) | pending owner |
| `npc_jacket` | accept | accept (face prototype) | accept | fixed (wrist/hand + hip/knee) | accept | accept | pending owner |
| `npc_coat` | accept | accept (face prototype) | accept | fixed (wrist/hand + hip/knee) | accept (hem 0.76 stride) | accept | pending owner |
| `npc_vest` | accept | accept (face prototype) | accept | fixed (wrist/hand + hip/knee) | accept | accept | pending owner |
| `npc_dress` | accept; performer props dominate | accept (face prototype) | accept | fixed (wrist/hand + hip/knee) | accept | accept | pending owner |
| `npc_hoodie` | accept (hooded criterion) | accept (lower face only) | accept | fixed (wrist/hand + hip/knee) | accept | accept | pending owner |
| `npc_firefighter` | accept | accept (face prototype) | accept | fixed (wrist/hand + hip/knee) | accept | accept | pending owner |
| `npc_guard` | accept | accept (face prototype) | accept | fixed (wrist/hand + hip/knee) | accept | accept | pending owner |
| `npc_crowd_a` | accept | accept (face prototype) | accept | fixed (wrist/hand + hip/knee) | accept | accept | crowd prototype |
| `npc_crowd_b` | accept | accept (face prototype) | accept | fixed (wrist/hand + hip/knee) | accept (beard) | accept | crowd prototype |
| `npc_crowd_c` | accept | accept (face prototype) | accept | fixed (wrist/hand + hip/knee) | accept (coat hem) | accept | crowd prototype |
| `npc_crowd_d` | accept | accept (face prototype) | accept | fixed (wrist/hand + hip/knee) | accept | accept | crowd prototype |
### Gear (18)
| Gear | Attach | Tris | Verdict |
| --- | --- | --- | --- |
| `cap` | head | 328 | — (fit measured, visual pending) |
| `hood` | head | 804 | — |
| `sunglasses` | head | 164 | accept (0.9.4 clearance) |
| `firefighter_helmet` | head | 672 | accept (0.9.4 + 3 cm runtime offset) |
| `backpack` | back | 380 | accept (0.9.4 strap refit) |
| `shoulder_bag` | back | 188 | — |
| `scba_tank` | back | 362 | — |
| `lanyard` | chest | 100 | accept (0.9.4 + 4 cm runtime offset) |
| `phone` | hand | 96 | accept (forward offset) |
| `cup` | hand | 188 | accept |
| `clipboard` | hand | 84 | accept |
| `umbrella` | hand | 134 | accept |
| `camera` | hand | 318 | accept |
| `protest_sign` | hand | 92 | accept (performer/protester read) |
| `flashlight` | hand | 168 | accept |
| `wand` | hand | 244 | accept |
| `radio` | hand | 220 | accept |
Gear total: 5,002 tris across 18 pieces (all far below the 1,500-per-piece cap).
`blender_assets.py fit` readings (2026-11-03): `shoulder_bag` is clear on both `npc_coat` and
`npc_dress` (the only back-gear clearance the fit test asserts); `sunglasses` sits inside the
head band at 0.64× head width. Three caveats worth recording, none of which changes a verdict:
`backpack` (npc_casual) and `scba_tank` (npc_firefighter) report `CLIP` because back gear is
measured against the **hip/skirt** radius, which is wider than the upper back where the bags
actually sit; `cap` and `firefighter_helmet` report `band=OUTSIDE` because they sit on the crown
above the 1.55–1.81 face/head band (expected); and the `lanyard` clip is corrected at runtime by
`GEAR_OFFSETS` (+4 cm forward). The unused `beanie` was retired on 2026-11-03 (removed from
`GEAR`, its builder, `npc_avatar.gd` and the manifest).
### Props (20 library + 6 generated fallbacks)
Library total 13,608 tris; `marquee` (2,804) and `street_tree` (2,592) are the two heaviest and are
the first candidates for a `vegetation-artist`/lookdev pass.
| Prop | Tris | Verdict |
| --- | --- | --- |
| `bollard` | 138 | accept (2026-11-03 flared base collar) |
| `bench` | 560 | — |
| `trash_bin` | 228 | — |
| `planter_box` | 1,324 | — |
| `newspaper_box` | 300 | accept (2026-11-03 recessed slot + door seam) |
| `fire_hydrant` | 610 | accept (2026-11-03 rebuild: bolted flange, bonnet cap nut, larger side + front outlets) |
| `street_lamp` | 428 | — |
| `street_tree` | 2,592 | P1 candidate (flat-shaded clumps) |
| `palm_tree` | 400 | P1 candidate (same foliage language) |
| `round_planter` | 1,240 | — |
| `a_frame_sign` | 212 | — |
| `wall_lantern` | 180 | — |
| `traffic_cone` | 210 | — |
| `crowd_barrier` | 388 | — |
| `stanchion` | 434 | — |
| `handrail` | 268 | — |
| `security_podium` | 184 | — |
| `double_door` | 380 | — |
| `marquee` | 2,804 | — (emissive check pending) |
| `sedan` | 928 | — |
Vision review 2026-11-03 (`tools/describe_image.py` on the prop gallery): `bench` and `trash_bin`
are ship-ready (minor chamfer polish only); `bollard` passes but leans on its reflective band
(add a base collar); `planter_box`/`round_planter` fail on the foliage — the `_shrub()` clumps
read as rocks, not plants (same foliage language gap, gated on the owner); `newspaper_box` is
borderline (the slot is a flat decal, wants a recessed inset + door seam); `fire_hydrant` is now
rebuilt (see row). No prop floats or sinks; shadow direction is consistent.
Generated fallbacks (`assets/models/generated/`): bench, bollard, fire_hydrant, newspaper_box,
planter_box, trash_bin. They are only used when the library prop is missing, so they are audited
for presence, not re-reviewed for art quality.
### Venues
| Venue | Measured (map-budget test) | Status |
| --- | --- | --- |
| Hollywood Boulevard | 58,884 tris / 409 meshes | shape-language review pending |
| The Joke Shop | 26,828 tris / 580 meshes | facade review landed: 6.0 m low hall, white signature band, tied-back curtains, west hotel tower; remaining gap = rounded west corner |
| TV Studio | — | shape-language review pending |
## Pose evidence (fixed 2026-11-04)
The weights/pose column can now be filled. The root cause was the harness: it never disabled the
avatar's `_physics_process`, so `_advance_fsm` + `_move_toward_target` reset `arrived`/velocity
every tick and `theater_pose()` reverted to idle. `capture_npc_pose.gd` now calls
`set_physics_process(false)`/`set_process(false)` after staging, and the pose sticks (sit vs idle
diff 5.63, walk vs idle 2.29, vision-judged as crouched). The earlier "moving the `Rig` child does
not render" probe was a red herring: it set the position in `_shoot()` in the same frame as
`root.get_texture().get_image()`.
`src/test/capture_npc_pose.gd` stages idle / walk-contact / walk-pass / seated for all twelve
variants (full-body + shoulder views).
| Check | Result |
| --- | --- |
| Pose reaches proxies | Seated pose logs `rig_y=-0.339`, `leg0=-1.357` |
| Pose reaches skeleton bones | `HipL`/`KneeL` bone rotations differ from rest; headless test `test_pose_reaches_the_skeleton_bones` locks it (suite 273/273) |
| Idle restores rest | Same test asserts the hip returns to its rest orientation |
| Skinning bound | One `Skeleton3D`, mesh bound to it (`same=true`); hiding `npc_base` removes the body |
| Bone rotations deform the mesh | Direct writes change rendered pixels: Spine 1,719 / HipL 1,052 / KneeL 810 / ElbowL 745 / Head 671 / ShoulderL 640 sampled pixels |
| Bone translation deforms the mesh | A +0.5 m Head offset moves the head in frame |
| Standalone window probes render the pose | Three variants (avatar under `root`, under a `Node3D` stage, created mid-`_process`) render the seated crouch (diff ~2,200-2,360 samples) |
| Offscreen capture renders the pose | A `SubViewport` + `RenderingServer.force_draw()` probe renders the crouch reliably (diff 602 at +2/+6/+12 frames), including a re-created second avatar |
| The harness renders the pose | **No** in its current form: same stage, same pose, rest frames. One ordering (`_frame_view()` immediately before `force_draw()`) produced posed walk frames once, then regressed to rest/garbage on the next run |
The rig, the animation math and the offscreen render path are all sound. A 2026-11-03 re-attempt
with the recipe (SubViewport + `force_draw()` + `force_update_all_bone_transforms()` + disabled
process/physics) still produced byte-identical rest frames, and a decisive probe narrowed the
failure further: teleporting the **avatar** changes the render (diff 10), but moving the **`Rig`
child** (the GLB model's parent) does not (diff 0). The skinned mesh therefore does not follow its
`Rig` Node3D transform, so the rig lowering never reaches the rendered model — the defect is
upstream of camera/`force_draw()` ordering. Next attempt must answer why the skinned model ignores
the `Rig` node, or stage poses via the known-good `capture_npc_review.gd` fallback.
Working recipe (verified by the probes; keep it when rebuilding):
1. Create a `SubViewport` (1280x720, `own_world_3d = true`, `UPDATE_ALWAYS`) in `_initialize`.
2. Build the studio (environment, key/fill light, ground, camera) and one avatar inside it.
3. Wait 2-3 frames so the skinned mesh binds.
4. Apply the pose with `_animate()` ticks, with the avatar's process/physics disabled.
5. Call `RenderingServer.force_draw()`, then `viewport.get_texture().get_image()`.
6. Free the avatar and repeat for the next pose; a re-created avatar also rendered correctly in a probe.
## Ranked candidate gaps
Ordered by expected player-visible gain per unit of work. None is approved for fixing yet; the
owner review decides.
1. **Face plane structure at portrait distance (P1, all eight).** The neutral sheet shows flat,
faceted cheek/brow planes and slit-like eyes at 1.85 m. `character-artist`/`retopology` guidance
asks for concentric eye loops and a 3-loop mouth. This is the largest readability gap and also
the most expensive (head rebuild + re-UV + re-AO per variant). Needs a targeted single-variant
prototype before committing to eight.
The eight library characters already carry the 0.9.4 face detail in
`tools/blender_assets.py._face()`: sculpted chin plate + cheekbones (`_shape_head_mesh`),
socketed sclera + thin upper lid, nose bridge/tip/wings, a rounded mouth and ear concha
(the plain sphere head in `tools/npc_pipeline.py` is the frozen `npc_base` fallback only).
So this gap is a readability/scale question on the existing sculpt — the head is
`seg=18/rings=12` with small offsets — not missing geometry. Concrete next step, if funded:
a single-variant `npc_casual` prototype that raises head subdivision and deepens the
cheek/brow offsets, then re-bakes AO and captures the portrait before touching the other seven.
**Prototype landed 2026-11-03/04:** `npc_casual` now has `seg=24/rings=16` (smoother), a subtle
brow ridge, a fuller lower lip and both eyelids (upper + lower); recessed creases (nasolabial,
temple, chin cleft) were rejected because they bake as dark AO patches. Vision-reviewed: the new
face reads cleaner and more realistic than the old (set-in eyes, brow break, lip volume, no
faceting); tris 4,482 → 5,038 (still under 8,000). The other seven variants keep the old face
until this prototype is approved.
2. **No pose/weight evidence (unknown).** Idle, walk, sit, block and turn deformation has never been
captured as a review set, so shoulder/hip/neck collapse is unmeasured. Cheap to add and it
gates any claim that the rig is acceptable.
3. **Foliage language (P1, `street_tree`, `palm_tree`, `planter_box`, `round_planter`).** Flat-shaded
clumps against an otherwise readable set, already deferred once. `vegetation-artist` carded
clusters would fix it inside the existing triangle budget.
4. **Texel density below the background tier (note).** 64–122 px/m authored vs the skill's 128–256
background tier. Fabric is already standard-tier at runtime. Decide: accept because the maps are
neutral tinted detail, or raise only `skin`/`hair` to 512² for portrait distance.
5. **`npc_firefighter` density floor (P2).** 64 px/m with the largest coat area; split the coat UV
shell or raise the map size before the next character pass, whichever the density decision says.
6. **Hands at conversation distance (accept, revisit only if face work opens the budget).** Open
palm with `HAND_ITEM_FORWARD`; no finger bones exist, so a curl rig is a contract decision, not
a modelling tidy-up.
7. **Gear never reviewed as silhouette language (P2).** 18 pieces pass fit/contract but have no
prop-artist verdict (the unused `beanie` was retired 2026-11-03).
8. **Venue shape language (P2).** Hollywood and the Joke Shop have budget data but no
`environment-artist`/`archviz` review; the TV Studio has no recorded map-budget number in this
document yet.
## qa-review sign-off (2026-11-04)
All eight library characters **ship with notes**. Face realism landed on all eight (`seg=24/rings=16`,
brow ridge, both eyelids, fuller lower lip), hands/grip and cloth/hair are accepted as recorded, gear
fit is measured with its caveats, and the props are reviewed (hydrant/bollard/newspaper_box rebuilt,
foliage two-toned). The only unresolved column is **weights/pose** (blocked on the capture harness),
and the full carded-cluster foliage pass is the one remaining owner-gated P1. No P0 remains.
## Decisions needed from the owner
- Accept the measured texel density as a stylized limitation, or fund a skin/hair resolution pass.
- Approve or reject a single-variant face/eye-loop prototype (and pick which variant to prototype
on) before any eight-character rebuild.
- Decide whether the pose/weight capture is required before the crowd-variant roster.
- Confirm foliage rebuild priority versus the map track (both touch the same street trees).
## Next actions
Tracked in [`TODO.md`](../TODO.md) `3D model re-evaluation`: the remaining `A. Baseline…` item is
this owner review; `B`/`C`/`D` carry the per-family work, and `E` adds the pose/weight,
collider-coverage and scorecard-coverage gates this document found missing.
+10 -4
View File
@@ -4,8 +4,8 @@ This folder holds the project documentation, visual references and generated QA
## Current priorities ## Current priorities
1. [Character development](../TODO.md#character-development) — crowd, age, build, hair and outfit variety; generator-first, with the frozen NPC contract. 1. [3D model and local map re-evaluation](../TODO.md#3d-model-and-local-map-re-evaluation) — asset scorecard and fixes, plus OpenStreetMap/3D data, licensed reference imagery, photoreal facades, AI-assisted composition and map/Gaussian-splatting evaluation.
2. [Local map development](../TODO.md#local-map-development) — OpenStreetMap/3D data, licensed reference imagery, photoreal facades, AI-assisted composition and Gaussian-splatting evaluation. 2. [Character development](../TODO.md#character-development) — crowd, age, build, hair and outfit variety; generator-first, with the frozen NPC contract.
3. [0.10.0 release candidate](../TODO.md#milestone-0100--release-candidate) — versioned release hardening after the unversioned development tracks. 3. [0.10.0 release candidate](../TODO.md#milestone-0100--release-candidate) — versioned release hardening after the unversioned development tracks.
## Start here ## Start here
@@ -16,11 +16,13 @@ This folder holds the project documentation, visual references and generated QA
- [`architecture.md`](architecture.md) — arc42 system architecture - [`architecture.md`](architecture.md) — arc42 system architecture
- [`getting-started.md`](getting-started.md) — setup, run/test commands and controls - [`getting-started.md`](getting-started.md) — setup, run/test commands and controls
- [`asset-tooling.md`](asset-tooling.md) — image/model pipelines and screenshot gates - [`asset-tooling.md`](asset-tooling.md) — image/model pipelines and screenshot gates
- [`../tools/README.md`](../tools/README.md) — tool inventory, categories and test runner
- [`gameplay.md`](gameplay.md) — controls, venues and escalation - [`gameplay.md`](gameplay.md) — controls, venues and escalation
- [`joke-shop-map.md`](joke-shop-map.md) — Sunset Strip real-site mapping - [`joke-shop-map.md`](joke-shop-map.md) — Sunset Strip real-site mapping
- [`tutorial.md`](tutorial.md) — first-shift tutorial beats - [`tutorial.md`](tutorial.md) — first-shift tutorial beats
- [`npc-visual-review.md`](npc-visual-review.md) — NPC visual baseline, acceptance criteria and ranked gaps - [`npc-visual-review.md`](npc-visual-review.md) — NPC visual baseline, acceptance criteria and ranked gaps
- [`npc-proportion-audit.md`](npc-proportion-audit.md) — NPC proportion ratios and stylized guide results - [`npc-proportion-audit.md`](npc-proportion-audit.md) — NPC proportion ratios and stylized guide results
- [`3d-model-review.md`](3d-model-review.md) — 3D model re-evaluation: measurements, scorecard and ranked gaps
- [`development-status.md`](development-status.md) — implemented features, current gaps and active planning - [`development-status.md`](development-status.md) — implemented features, current gaps and active planning
- [`accessibility.md`](accessibility.md) — accessibility statement and known gaps - [`accessibility.md`](accessibility.md) — accessibility statement and known gaps
- [`known-limitations.md`](known-limitations.md) — release-candidate blockers and accepted limits - [`known-limitations.md`](known-limitations.md) — release-candidate blockers and accepted limits
@@ -41,9 +43,13 @@ This folder holds the project documentation, visual references and generated QA
## Quick preview ## Quick preview
| Reference | Screenshot | | Reference | Capture |
| --- | --- | | --- | --- |
| Venue design | <img src="screens/designs/venue_overview.png" width="320" alt="Venue overview design"> | | Venue design | <img src="screens/designs/venue_overview.png" width="320" alt="Venue overview design"> |
| Current entrance | <img src="screenshots/01-venue-overview.png" width="320" alt="In-game venue overview"> | | Current entrance (day) | <img src="screenshots/01-venue-overview.png" width="320" alt="In-game venue overview"> |
| Current entrance (late) | <img src="screenshots/05-late-night-avenue.png" width="320" alt="Late-night boulevard"> |
| Joke Shop | <img src="screenshots/12-joke-shop.png" width="320" alt="Joke Shop at night"> |
| Character sheet | <img src="blender_previews/sheet_npc.jpg" width="320" alt="NPC character sheet"> | | Character sheet | <img src="blender_previews/sheet_npc.jpg" width="320" alt="NPC character sheet"> |
| Neutral NPC baseline | <img src="blender_previews/sheet_npc_baseline.jpg" width="320" alt="Neutral NPC baseline sheet"> |
| Texture refinement | <img src="blender_previews/sheet_texture_refinement_0.9.5.jpg" width="320" alt="Texture refinement comparison"> |
| Prop sheet | <img src="blender_previews/sheet_props.jpg" width="320" alt="Prop asset sheet"> | | Prop sheet | <img src="blender_previews/sheet_props.jpg" width="320" alt="Prop asset sheet"> |
+2 -2
View File
@@ -175,8 +175,8 @@ Evidence and detailed contracts live in [`blender-assets.md`](blender-assets.md)
### Local map development tooling (planned) ### Local map development tooling (planned)
The current venues are hand-authored procedural reconstructions in The current venues are hand-authored procedural reconstructions in
`src/game/world_builder.gd`. The **Local map development** track in `src/game/world_builder.gd`. The local map workstreams (**H–M**) in
[`TODO.md`](../TODO.md#local-map-development) is unversioned and planned: it will [`TODO.md`](../TODO.md#3d-model-re-evaluation) are unversioned and planned: they will
test whether licensed data and reference photography can replace or supplement the test whether licensed data and reference photography can replace or supplement the
stylized geometry without moving map data, AI composition or splat rendering into stylized geometry without moving map data, AI composition or splat rendering into
the runtime. the runtime.
+181 -3
View File
@@ -38,7 +38,7 @@ Audit accepts image files or directories. `--role auto` infers common roles from
```bash ```bash
python3 tools/asset_pipeline.py audit assets/textures python3 tools/asset_pipeline.py audit assets/textures
python3 tools/asset_pipeline.py audit assets/images/scenes --role background --json python3 tools/asset_pipeline.py audit assets/images/scenes --role background --json
python3 -m unittest discover -s tools -p 'test_*.py' python3 -m unittest discover -s tools/tests -t tools -p 'test_*.py'
``` ```
The audit classifies measurable fit issues as `good` or `bad` based on role-specific dimensions, aspect ratio, alpha requirements, and tile-edge continuity. It lists perspective/projection as a visual review item because image semantics cannot be judged reliably by these deterministic checks. The audit classifies measurable fit issues as `good` or `bad` based on role-specific dimensions, aspect ratio, alpha requirements, and tile-edge continuity. It lists perspective/projection as a visual review item because image semantics cannot be judged reliably by these deterministic checks.
@@ -143,13 +143,165 @@ flatpak run org.blender.Blender --background --python "$PWD/tools/blender_assets
flatpak run org.blender.Blender --background --python "$PWD/tools/blender_assets.py" -- render flatpak run org.blender.Blender --background --python "$PWD/tools/blender_assets.py" -- render
python3 tools/blender_assets.py sheet # docs/blender_previews/sheet_*.jpg python3 tools/blender_assets.py sheet # docs/blender_previews/sheet_*.jpg
python3 tools/blender_assets.py audit # no Blender needed python3 tools/blender_assets.py audit # no Blender needed
python3 tools/blender_assets.py fit # gear-vs-body fit report
python3 tools/blender_assets.py texels # per-slot texel density (px/m) of the characters
godot --headless --path . --import godot --headless --path . --import
``` ```
### Intake inspection (`inspect`)
`audit` reads accessor-local bounds and ignores node transforms, so it is the right
release gate but a poor first look at a downloaded or newly authored GLB. `inspect`
imports the file into Blender, clears parents and applies object transforms, then
reports what the scene actually contains:
```bash
# one asset, a batch, or an external download; repeat --file as needed
flatpak run org.blender.Blender --background \
--python "$PWD/tools/blender_assets.py" -- inspect \
--file "$PWD/assets/models/blender/npc/npc_casual.glb" \
--file "$PWD/tmp/downloads/SomeCharacter.glb"
# machine-readable, for intake scripts (write to a file: Blender prints a banner first)
... -- inspect --file "$PWD/tmp/x.glb" --json --out "$PWD/tmp/x.json"
# force a contract family instead of inferring it from the path
... -- inspect --file "$PWD/tmp/x.glb" --category npc
```
It prints triangles (with the category budget), raw and seam-split vertex counts,
Godot-space bounds with height/feet for characters, whether transforms had to be
applied, mesh nodes and armatures, bone names, materials, UV layers, skinning and
animation count. Hard contract failures (`issues`) fail the command; advisory
findings (`warnings`) do not. The category is inferred from the path:
`blender/npc` → `npc`, `blender/npc_gear` → `npc_gear`, `blender/props` and
`generated` → `props`, anything else → `external` (measured but with no project
budget or rig contract).
Caveats:
- The glTF importer adds a bone-display mesh (`Icosphere`, used as
`pose_bone.custom_shape`). `inspect` excludes custom-shape helpers so they never
pollute bounds or the unskinned list.
- Bounds and bone rests are converted from Blender Z-up to Godot Y-up (`x, z, -y`),
matching the contract bands and the audit's coordinate space.
### Intake adaptation (`adapt`)
`adapt` is the mechanical first half of an external-mesh intake (MakeHuman,
MPFB, downloaded GLB): import, apply transforms, ground the feet, weld seam
splits, decimate to the character budget, and export a GLB. It does **not** map
the five tint slots or rebuild the 13-bone `npc_base` armature — those stay a
manual `retopology`/`rigging` step with a recorded second-rig contract if the
source rig cannot be retargeted:
```bash
flatpak run org.blender.Blender --background \
--python "$PWD/tools/blender_assets.py" -- adapt \
--file "$PWD/tmp/npc-research/makehuman_base.glb" \
--out "$PWD/tmp/npc-research/makehuman_adapted.glb" \
--target-tris 8000
# prints: adapted makehuman_adapted.glb: 36972 -> 8000 tris (bones=N, meshes=1)
```
Run `inspect` on the adapted GLB before and after, and keep the procedural
generator as the fallback until a MakeHuman variant passes `audit`/`fit` and the
24-NPC budget.
- Numbers are Blender-side measurements. Triangles match `audit` on project assets; the seam-split
vertex count can differ by ±1 because the importer rounds normals. `audit` stays the single final
gate: it is stdlib-only, runs in CI, and matches what the engine imports.
- `inspect` never writes or adapts the file; scale/grounding/weld/retarget work is the
separate (not yet built) `adapt` step.
- `--json` also captures the importer's INFO log in `stats.import_log` instead of printing it.
Blender still prints its own version banner before the script runs, so intake scripts should use
`--json --out <file>` rather than parsing stdout.
### Reference-anchored concept generation
`tools/scene_concepts.py generate --reference <photo>` anchors a concept frame on a real
photograph: the photo is sent to the OpenRouter multimodal chat endpoint as a base64 data URL
(`generate_textures.generate_image(reference_path=...)`) with a prompt suffix that pins the
photographed geometry (column rhythm, band heights, signage placement, camera angle) while the
prompt restages lighting, weather and people.
Licence gate: the reference must be listed in its `docs/screens/refs/<venue>/SIDECAR.md` row
(which also supplies the licence and Commons page for provenance). A photo from anywhere else
requires `--reference-unchecked`, which records `unchecked` in the provenance. Each anchored
generation writes a `.refgen.json` sidecar next to the frame (`model`, reference file/licence/page,
geometry suffix) so a concept frame can always be traced back to its evidence photo. Where a
generated frame and its reference photo disagree, the photo wins for shape.
### Photo-anchored variant pass
`tools/scene_concepts.py anchor --reference <photo> --context "..." --treatments day,night,weathered
--out-dir docs/screens/concepts/<block>` generates several restaged conditions (day, night,
weathered) of one reference photo's framing, each with its `.refgen.json` provenance sidecar, so a
concept board stays comparable with its photo board. The reference passes the same SIDECAR licence
gate as `--reference` on `generate`.
### Local-only reference collection (`refcollect`)
`tools/refcollect.py` downloads images from DuckDuckGo image search into `tmp/research/<slug>/` for
development reference only. It applies **no licence gate** (rows are marked `local_only` /
`unchecked-local`); everything it fetches must never be committed or promoted into
[`screens/refs/`](screens/refs/README.md) without the normal sidecar licence + privacy gate. This
is the owner-authorised local-only override (TODO.md §3D model re-evaluation → A).
```bash
python3 tools/refcollect.py search "Comedy Store Sunset Boulevard" --slug comedy-store --limit 20
python3 tools/refcollect.py sheet --slug comedy-store # local contact sheet (never committed)
```
Requires `pip install duckduckgo-search` (renamed `ddgs` upstream). DuckDuckGo rate-limits by IP
(HTTP 202), so every request — the search itself and each image download — passes through a shared
token bucket (`--rate`, default 0.5 req/s, and `--burst`, default 3) and a polite retry routine:
transient statuses (408/425/429/5xx/52x) and network errors back off exponentially with full
jitter, `Retry-After` is honoured, permanent failures fail fast, and the loop gives up after six
attempts. Requests carry a full, coherent Firefox header set (`--user-agent` overrides the UA
string); the UA alone is no longer enough to look like a browser.
### Reference-board research (`refboard`)
`tools/refboard.py` searches, fetches and documents Wikimedia Commons photos of a real location for
the [`screens/refs/`](screens/refs/README.md) boards. It is stdlib-only and never commits anything
itself: downloads land in `tmp/`, and moving a file into a board folder is a deliberate manual step
that goes through the sidecar licence gate.
```bash
# search: keyword, geosearch (the reliable "photos of this exact place"), or category
python3 tools/refboard.py search --source geo "34.10118|-118.34009" --limit 60 --months 12
python3 tools/refboard.py search "El Capitan Entertainment Centre" --source search
python3 tools/refboard.py search "Hollywood Masonic Temple" --source category --json
# fetch the usable rows into tmp/ (review-only rows need --include-review)
python3 tools/refboard.py search ... --json > /tmp/manifest.json
python3 tools/refboard.py fetch --from /tmp/manifest.json --dir tmp/research/<block> --max 12
# emit SIDECAR + README table rows from the fetched manifest
python3 tools/refboard.py rows --from tmp/research/<block>/meta.json
```
Licence gate: `Public domain`, `CC0` and `CC BY` are committable with attribution; `CC BY-SA` rows
are flagged `review` and stay research-only until the share-alike decision is written into the
sidecar (`--allow-ccbysa` marks them committable after that review); anything else is skipped.
`--months 12` flags recent captures so a "current reality" photo can be distinguished from the
older geometry evidence. Network gotchas baked in: a descriptive User-Agent, batched `titles=`
metadata queries and ~3 s download spacing to avoid Commons HTTP 429s.
### Texel density (`texels`)
`texel_density()` and the `texels` command compute `resolution * sqrt(UV area / world area)` per
material slot straight from the GLB, so the number does not depend on island packing. The NPC slot
maps are 256², and cloth/pants are reported twice: authored density and effective density with the
runtime 4× repeat from `Materials.NPC_FABRIC_UV_SCALE`. Current values and interpretation are in
[`3d-model-review.md`](3d-model-review.md).
```bash
python3 tools/blender_assets.py texels # all eight characters
python3 tools/blender_assets.py texels --json # machine-readable
python3 tools/blender_assets.py texels --only npc_coat
```
## Local map development (planned) ## Local map development (planned)
The **Local map development** track in [`TODO.md`](../TODO.md#local-map-development) The local map workstreams (**H–M**) in [`TODO.md`](../TODO.md#3d-model-re-evaluation)
is not implemented yet; there are no map-generation commands to run. The planned are not implemented yet; there are no map-generation commands to run. The planned
pipeline will evaluate: pipeline will evaluate:
- offline OpenStreetMap extracts for footprints and licence-compatible 3D building - offline OpenStreetMap extracts for footprints and licence-compatible 3D building
@@ -225,6 +377,16 @@ and ranks them by advertised token/image price. The run falls through the list
on provider/model errors and aborts on an invalid key. Use on provider/model errors and aborts on an invalid key. Use
`GIG_LINE_JUDGE_MODEL` or `--model <id>` for a pinned comparison. `GIG_LINE_JUDGE_MODEL` or `--model <id>` for a pinned comparison.
For an open-ended review of a single capture/reference (no structured verdict),
`tools/describe_image.py` sends the image plus a question to a vision model and
prints the answer. It is how the 2026-11-03 re-evaluation read the local-only
reference frames and the prop/venue captures:
```bash
python3 tools/describe_image.py docs/screenshots/12-joke-shop.png \
--question "Do the red curtain bays read as tied-back fabric or flat slabs?"
```
`capture_npc_review.gd` is the pre-build NPC gate: it stages all eight `capture_npc_review.gd` is the pre-build NPC gate: it stages all eight
library character models at portrait, conversation and crowd distance on both library character models at portrait, conversation and crowd distance on both
promoted maps in day and night lighting, with the normal crowd hidden. It uses promoted maps in day and night lighting, with the normal crowd hidden. It uses
@@ -247,6 +409,22 @@ height/head/shoulder/hip/torso/leg/arm/foot guide; the current results are in
[`npc-proportion-audit.md`](npc-proportion-audit.md). It reads the exported GLBs [`npc-proportion-audit.md`](npc-proportion-audit.md). It reads the exported GLBs
and does not require Blender. and does not require Blender.
`capture_npc_pose.gd` is the pose/deformation harness for the 3D re-evaluation: idle,
walk-contact, walk-pass and seated poses of all eight variants, full-body plus shoulder
close-ups. **It is currently blocked**: the applied pose is visible in the rig and bone values
but not in the captured frames, so do not use its sheets as pose evidence. The reproduction and
what was ruled out are in [`3d-model-review.md`](3d-model-review.md) §"Pose evidence is blocked".
The baseline sheet tool accepts a custom view list, which is also how pose sheets are tiled:
```bash
# baseline set (six views, eight variants)
python3 tools/npc_baseline.py sheet --dir tmp/npc-baseline
# pose set produced by capture_npc_pose.gd
python3 tools/npc_baseline.py sheet --dir tmp/npc-pose \
--views idle,walk_contact,walk_pass,sit --out tmp/npc-pose/sheet_pose.jpg
```
`capture_npc_baseline.gd` is the 0.9.4 neutral baseline: eight characters × `capture_npc_baseline.gd` is the 0.9.4 neutral baseline: eight characters ×
front/three-quarter/profile/back/full-body/crowd = 48 frames with a fixed front/three-quarter/profile/back/full-body/crowd = 48 frames with a fixed
camera, studio lighting and no venue/HUD/animation. The raw PNGs stay in camera, studio lighting and no venue/HUD/animation. The raw PNGs stay in
+20 -8
View File
@@ -21,7 +21,7 @@ captures in `docs/screenshots/`.
- **People** (`targeting_npc`, `joke_shop_queue`, `studio_arrival`, - **People** (`targeting_npc`, `joke_shop_queue`, `studio_arrival`,
`crowd_panic`, `responder_arrival`): ordinary adults in sweaters, jackets, `crowd_panic`, `responder_arrival`): ordinary adults in sweaters, jackets,
long coats, hoodies and beanies; a security guard in a dark uniform with a cap long coats and hoodies; a security guard in a dark uniform with a cap
and belt; a firefighter in a dark turnout coat with yellow reflective bands, and belt; a firefighter in a dark turnout coat with yellow reflective bands,
a helmet and an SCBA tank. The current skinned `npc_base` is a set of boxes a helmet and an SCBA tank. The current skinned `npc_base` is a set of boxes
and cylinders with a flat face, so silhouette was the main gap. and cylinders with a flat face, so silhouette was the main gap.
@@ -47,7 +47,11 @@ flatpak run org.blender.Blender --background \
python3 tools/blender_assets.py sheet # -> docs/blender_previews/sheet_<category>.jpg python3 tools/blender_assets.py sheet # -> docs/blender_previews/sheet_<category>.jpg
python3 tools/blender_assets.py audit # stdlib only; exit 1 on any issue python3 tools/blender_assets.py audit # stdlib only; exit 1 on any issue
python3 tools/blender_assets.py fit # head/clothing fit + bag-body clearance, per character python3 tools/blender_assets.py fit # head/clothing fit + bag-body clearance, per character
python3 tools/blender_assets.py texels # 256² slot-map density (authored + 4× fabric), per character
python3 tools/blender_assets.py list python3 tools/blender_assets.py list
# import a GLB, apply node transforms, report geometry/bones/UVs/skinning + contract failures
flatpak run org.blender.Blender --background \
--python "$PWD/tools/blender_assets.py" -- inspect --file "$PWD/tmp/downloads/x.glb"
godot --headless --path . --import # after any rebuild godot --headless --path . --import # after any rebuild
``` ```
@@ -141,7 +145,7 @@ attach point:
| Attach | Godot parent / position | Gear | | Attach | Godot parent / position | Gear |
| --- | --- | --- | | --- | --- | --- |
| `head` | `Rig/Head` marker (0, 1.62, 0) | cap, beanie, hood, sunglasses, firefighter_helmet | | `head` | `Rig/Head` marker (0, 1.62, 0) | cap, hood, sunglasses, firefighter_helmet |
| `back` | `Rig` at (0, 1.10, 0), spine centre; items sit behind the body (Blender +Y = Godot −Z) | backpack, shoulder_bag, scba_tank | | `back` | `Rig` at (0, 1.10, 0), spine centre; items sit behind the body (Blender +Y = Godot −Z) | backpack, shoulder_bag, scba_tank |
| `chest` | `Rig` at (0, 1.30, 0), sternum | lanyard | | `chest` | `Rig` at (0, 1.30, 0), sternum | lanyard |
| `hand` | Hand proxy (±0.27, 0.78, 0.02); grip 5 cm below the origin | phone, cup, clipboard, umbrella, camera, protest_sign, flashlight, wand, radio | | `hand` | Hand proxy (±0.27, 0.78, 0.02); grip 5 cm below the origin | phone, cup, clipboard, umbrella, camera, protest_sign, flashlight, wand, radio |
@@ -184,13 +188,19 @@ carry baked AO and the shared neutral material maps described above.
during LOD generation), budgets (library characters 8000/8000, base fallback 6000/4000, gear 1500, props 4000 during LOD generation), budgets (library characters 8000/8000, base fallback 6000/4000, gear 1500, props 4000
triangles), grounding, and an editable `.blend`. For characters it also triangles), grounding, and an editable `.blend`. For characters it also
checks skinning, bones, slots, the `npc_base` mesh node and the height. checks skinning, bones, slots, the `npc_base` mesh node and the height.
- `tools/test_blender_assets.py`: catalogue and contract consistency with - `tools/tests/test_blender_assets.py`: catalogue and contract consistency with
`npc_pipeline.py`, plus a clean audit and full manifest coverage when the `npc_pipeline.py`, plus a clean audit, a texel-density gate (all five slots,
library is built. 40–400 px/m authored, 250 px/m fabric floor) and full manifest coverage when
the library is built.
- `src/test/tests/test_blender_assets.gd`: every asset imports as a scene - `src/test/tests/test_blender_assets.gd`: every asset imports as a scene
with geometry, characters keep their bones and slots, joints match with geometry, characters keep their bones and slots, joints match
`npc_base`, the bones accept `NpcAvatar`'s pose composition, and props are `npc_base`, the bones accept `NpcAvatar`'s pose composition, and props are
grounded. grounded.
- `tools/test_model_review.py`: every `CHARACTERS`/`GEAR`/`PROPS` entry has a
scorecard row and verdict in `docs/3d-model-review.md` (coverage gate).
- `src/test/tests/test_world.gd`: every library prop that blocks walking has a
`StaticBody3D` + `NavigationObstacle3D`, checked against the catalogue
(collider/proxy gate).
## Known limitations ## Known limitations
@@ -206,6 +216,8 @@ carry baked AO and the shared neutral material maps described above.
stay neutral. stay neutral.
- The 0.9.4 baseline found three P1 portrait issues. The tourist's photo prop - The 0.9.4 baseline found three P1 portrait issues. The tourist's photo prop
now only appears in photo/film poses and the backpack straps were refit as now only appears in photo/film poses and the backpack straps were refit as
flattened chest bands; the face is still shallow/faceted at portrait range. flattened chest bands. The face carries the 0.9.4 sculpt (socketed sclera,
The full ranked list, measurements and before/after sheet are in chin/cheekbone, nose, lips) but its `seg=18/rings=12` head still reads
[`npc-visual-review.md`](npc-visual-review.md). somewhat faceted at portrait range; a subdivision/deeper-sculpt prototype is
gated on the owner scorecard review. The full ranked list and measurements are
in [`npc-visual-review.md`](npc-visual-review.md).
+28 -68
View File
@@ -1,71 +1,31 @@
# Blender Previews # Blender previews
Committed contact sheets and local Blender renders for the character, gear and prop library. Individual PNGs are development previews and are gitignored; the sheets are tracked. Committed contact sheets for the character, gear and prop library. Per-asset Cycles renders
(`*.png`) are local development output and gitignored; the sheets below are the review artefacts
and are built with `blender_assets.py render` + `sheet`, `npc_baseline.py sheet/compare`, or the
capture harnesses.
## Image previews | Sheet | What it records |
| Preview | File |
| --- | --- | | --- | --- |
| <img src="a_frame_sign.png" width="280" alt="a_frame_sign.png"> | [`a_frame_sign.png`](a_frame_sign.png) | | [![sheet_npc.jpg](sheet_npc.jpg)](sheet_npc.jpg) <br> `sheet_npc.jpg` | Eight skinned character variants (casual, jacket, coat, hi-vis vest, dress, hoodie, firefighter, guard) with their gear attach points. |
| <img src="backpack.png" width="280" alt="backpack.png"> | [`backpack.png`](backpack.png) | | [![sheet_npc_baseline.jpg](sheet_npc_baseline.jpg)](sheet_npc_baseline.jpg) <br> `sheet_npc_baseline.jpg` | Neutral studio baseline: 8 characters x front, three-quarter, profile, back, full body and crowd views. |
| <img src="beanie.png" width="280" alt="beanie.png"> | [`beanie.png`](beanie.png) | | [![sheet_npc_baseline_compare-body.jpg](sheet_npc_baseline_compare-body.jpg)](sheet_npc_baseline_compare-body.jpg) <br> `sheet_npc_baseline_compare-body.jpg` | Neck/shoulder transition: fuller neck base and a lower shoulder root. |
| <img src="bench.png" width="280" alt="bench.png"> | [`bench.png`](bench.png) | | [![sheet_npc_baseline_compare-face-detail.jpg](sheet_npc_baseline_compare-face-detail.jpg)](sheet_npc_baseline_compare-face-detail.jpg) <br> `sheet_npc_baseline_compare-face-detail.jpg` | Face detail: nose ala wings, a single rounded mouth and a darker ear concha. |
| <img src="bollard.png" width="280" alt="bollard.png"> | [`bollard.png`](bollard.png) | | [![sheet_npc_baseline_compare-face.jpg](sheet_npc_baseline_compare-face.jpg)](sheet_npc_baseline_compare-face.jpg) <br> `sheet_npc_baseline_compare-face.jpg` | Face-depth pass: recessed sclera, upper lid and sculpted chin/cheek planes. |
| <img src="camera.png" width="280" alt="camera.png"> | [`camera.png`](camera.png) | | [![sheet_npc_baseline_compare-p1.jpg](sheet_npc_baseline_compare-p1.jpg)](sheet_npc_baseline_compare-p1.jpg) <br> `sheet_npc_baseline_compare-p1.jpg` | 0.9.4 P1 pass: tourist photo-prop visibility and the refit backpack straps. |
| <img src="cap.png" width="280" alt="cap.png"> | [`cap.png`](cap.png) | | [![sheet_npc_baseline_compare-shoes.jpg](sheet_npc_baseline_compare-shoes.jpg)](sheet_npc_baseline_compare-shoes.jpg) <br> `sheet_npc_baseline_compare-shoes.jpg` | Footwear: rounded toe/heel caps on shoes and responder boots. |
| <img src="clipboard.png" width="280" alt="clipboard.png"> | [`clipboard.png`](clipboard.png) | | [![sheet_npc_baseline_compare-tex256.jpg](sheet_npc_baseline_compare-tex256.jpg)](sheet_npc_baseline_compare-tex256.jpg) <br> `sheet_npc_baseline_compare-tex256.jpg` | 128 -> 256 px NPC slot maps on the same camera. |
| <img src="crowd_barrier.png" width="280" alt="crowd_barrier.png"> | [`crowd_barrier.png`](crowd_barrier.png) | | [![sheet_npc_baseline_compare-texuv.jpg](sheet_npc_baseline_compare-texuv.jpg)](sheet_npc_baseline_compare-texuv.jpg) <br> `sheet_npc_baseline_compare-texuv.jpg` | 4x fabric weave with the baked per-character AO removed. |
| <img src="cup.png" width="280" alt="cup.png"> | [`cup.png`](cup.png) | | [![sheet_npc_baseline_compare-torso.jpg](sheet_npc_baseline_compare-torso.jpg)](sheet_npc_baseline_compare-torso.jpg) <br> `sheet_npc_baseline_compare-torso.jpg` | Torso/hip taper without changing the skeleton or build multipliers. |
| <img src="double_door.png" width="280" alt="double_door.png"> | [`double_door.png`](double_door.png) | | [![sheet_npc_crowd_prototypes.jpg](sheet_npc_crowd_prototypes.jpg)](sheet_npc_crowd_prototypes.jpg) <br> `sheet_npc_crowd_prototypes.jpg` | Four approved crowd-variety looks queued for the 12-character roster. |
| <img src="fire_hydrant.png" width="280" alt="fire_hydrant.png"> | [`fire_hydrant.png`](fire_hydrant.png) | | [![sheet_npc_gear.jpg](sheet_npc_gear.jpg)](sheet_npc_gear.jpg) <br> `sheet_npc_gear.jpg` | Eighteen gear pieces authored in attach space: caps, hood, helmet, bags, tanks, lanyards and handheld items. |
| <img src="firefighter_helmet.png" width="280" alt="firefighter_helmet.png"> | [`firefighter_helmet.png`](firefighter_helmet.png) | | [![sheet_npc_hands_compare.jpg](sheet_npc_hands_compare.jpg)](sheet_npc_hands_compare.jpg) <br> `sheet_npc_hands_compare.jpg` | Hand pass: wider palms, segmented fingers and a separate thumb. |
| <img src="flashlight.png" width="280" alt="flashlight.png"> | [`flashlight.png`](flashlight.png) | | [![sheet_npc_hands_grip_compare.jpg](sheet_npc_hands_grip_compare.jpg)](sheet_npc_hands_grip_compare.jpg) <br> `sheet_npc_hands_grip_compare.jpg` | Grip pass: the forward hand-item offset that puts props in the palm. |
| <img src="handrail.png" width="280" alt="handrail.png"> | [`handrail.png`](handrail.png) | | [![sheet_npc_sources_research.jpg](sheet_npc_sources_research.jpg)](sheet_npc_sources_research.jpg) <br> `sheet_npc_sources_research.jpg` | External character-source evaluation (CC0/CC-BY) for the roster research. |
| <img src="hood.png" width="280" alt="hood.png"> | [`hood.png`](hood.png) | | [![sheet_props.jpg](sheet_props.jpg)](sheet_props.jpg) <br> `sheet_props.jpg` | Twenty street and venue props with baked maps, ground contact and collider footprints. |
| <img src="lanyard.png" width="280" alt="lanyard.png"> | [`lanyard.png`](lanyard.png) | | [![sheet_texture_refinement_0.9.5.jpg](sheet_texture_refinement_0.9.5.jpg)](sheet_texture_refinement_0.9.5.jpg) <br> `sheet_texture_refinement_0.9.5.jpg` | 0.9.5 texture refinement before/after: pavers, awning stripes and NPC fabric. |
| <img src="marquee.png" width="280" alt="marquee.png"> | [`marquee.png`](marquee.png) |
| <img src="newspaper_box.png" width="280" alt="newspaper_box.png"> | [`newspaper_box.png`](newspaper_box.png) | The acceptance criteria for these sheets are in [`../npc-visual-review.md`](../npc-visual-review.md),
| <img src="npc_casual.png" width="280" alt="npc_casual.png"> | [`npc_casual.png`](npc_casual.png) | the measurements in [`../npc-proportion-audit.md`](../npc-proportion-audit.md) and
| <img src="npc_coat.png" width="280" alt="npc_coat.png"> | [`npc_coat.png`](npc_coat.png) | [`../3d-model-review.md`](../3d-model-review.md), and the asset contract in
| <img src="npc_dress.png" width="280" alt="npc_dress.png"> | [`npc_dress.png`](npc_dress.png) | [`../blender-assets.md`](../blender-assets.md).
| <img src="npc_firefighter.png" width="280" alt="npc_firefighter.png"> | [`npc_firefighter.png`](npc_firefighter.png) |
| <img src="npc_guard.png" width="280" alt="npc_guard.png"> | [`npc_guard.png`](npc_guard.png) |
| <img src="npc_hoodie.png" width="280" alt="npc_hoodie.png"> | [`npc_hoodie.png`](npc_hoodie.png) |
| <img src="npc_jacket.png" width="280" alt="npc_jacket.png"> | [`npc_jacket.png`](npc_jacket.png) |
| <img src="npc_vest.png" width="280" alt="npc_vest.png"> | [`npc_vest.png`](npc_vest.png) |
| <img src="palm_tree.png" width="280" alt="palm_tree.png"> | [`palm_tree.png`](palm_tree.png) |
| <img src="phone.png" width="280" alt="phone.png"> | [`phone.png`](phone.png) |
| <img src="planter_box.png" width="280" alt="planter_box.png"> | [`planter_box.png`](planter_box.png) |
| <img src="protest_sign.png" width="280" alt="protest_sign.png"> | [`protest_sign.png`](protest_sign.png) |
| <img src="radio.png" width="280" alt="radio.png"> | [`radio.png`](radio.png) |
| <img src="round_planter.png" width="280" alt="round_planter.png"> | [`round_planter.png`](round_planter.png) |
| <img src="scba_tank.png" width="280" alt="scba_tank.png"> | [`scba_tank.png`](scba_tank.png) |
| <img src="security_podium.png" width="280" alt="security_podium.png"> | [`security_podium.png`](security_podium.png) |
| <img src="sedan.png" width="280" alt="sedan.png"> | [`sedan.png`](sedan.png) |
| <img src="sheet_npc.jpg" width="280" alt="sheet_npc.jpg"> | [`sheet_npc.jpg`](sheet_npc.jpg) |
| <img src="sheet_npc_sources_research.jpg" width="280" alt="sheet_npc_sources_research.jpg"> | [`sheet_npc_sources_research.jpg`](sheet_npc_sources_research.jpg) |
| <img src="sheet_npc_crowd_prototypes.jpg" width="280" alt="sheet_npc_crowd_prototypes.jpg"> | [`sheet_npc_crowd_prototypes.jpg`](sheet_npc_crowd_prototypes.jpg) |
| <img src="sheet_npc_baseline.jpg" width="280" alt="sheet_npc_baseline.jpg"> | [`sheet_npc_baseline.jpg`](sheet_npc_baseline.jpg) |
| <img src="sheet_npc_baseline_compare-p1.jpg" width="280" alt="sheet_npc_baseline_compare-p1.jpg"> | [`sheet_npc_baseline_compare-p1.jpg`](sheet_npc_baseline_compare-p1.jpg) |
| <img src="sheet_npc_baseline_compare-body.jpg" width="280" alt="sheet_npc_baseline_compare-body.jpg"> | [`sheet_npc_baseline_compare-body.jpg`](sheet_npc_baseline_compare-body.jpg) |
| <img src="sheet_npc_baseline_compare-face.jpg" width="280" alt="sheet_npc_baseline_compare-face.jpg"> | [`sheet_npc_baseline_compare-face.jpg`](sheet_npc_baseline_compare-face.jpg) |
| <img src="sheet_npc_baseline_compare-torso.jpg" width="280" alt="sheet_npc_baseline_compare-torso.jpg"> | [`sheet_npc_baseline_compare-torso.jpg`](sheet_npc_baseline_compare-torso.jpg) |
| <img src="sheet_npc_baseline_compare-face-detail.jpg" width="280" alt="sheet_npc_baseline_compare-face-detail.jpg"> | [`sheet_npc_baseline_compare-face-detail.jpg`](sheet_npc_baseline_compare-face-detail.jpg) |
| <img src="sheet_npc_hands_compare.jpg" width="280" alt="sheet_npc_hands_compare.jpg"> | [`sheet_npc_hands_compare.jpg`](sheet_npc_hands_compare.jpg) |
| <img src="sheet_npc_hands_grip_compare.jpg" width="280" alt="sheet_npc_hands_grip_compare.jpg"> | [`sheet_npc_hands_grip_compare.jpg`](sheet_npc_hands_grip_compare.jpg) |
| <img src="sheet_npc_baseline_compare-shoes.jpg" width="280" alt="sheet_npc_baseline_compare-shoes.jpg"> | [`sheet_npc_baseline_compare-shoes.jpg`](sheet_npc_baseline_compare-shoes.jpg) |
| <img src="sheet_npc_baseline_compare-tex256.jpg" width="280" alt="sheet_npc_baseline_compare-tex256.jpg"> | [`sheet_npc_baseline_compare-tex256.jpg`](sheet_npc_baseline_compare-tex256.jpg) |
| <img src="sheet_npc_baseline_compare-texuv.jpg" width="280" alt="sheet_npc_baseline_compare-texuv.jpg"> | [`sheet_npc_baseline_compare-texuv.jpg`](sheet_npc_baseline_compare-texuv.jpg) |
| <img src="sheet_texture_refinement_0.9.5.jpg" width="280" alt="sheet_texture_refinement_0.9.5.jpg"> | [`sheet_texture_refinement_0.9.5.jpg`](sheet_texture_refinement_0.9.5.jpg) |
| <img src="sheet_npc_gear.jpg" width="280" alt="sheet_npc_gear.jpg"> | [`sheet_npc_gear.jpg`](sheet_npc_gear.jpg) |
| <img src="sheet_props.jpg" width="280" alt="sheet_props.jpg"> | [`sheet_props.jpg`](sheet_props.jpg) |
| <img src="shoulder_bag.png" width="280" alt="shoulder_bag.png"> | [`shoulder_bag.png`](shoulder_bag.png) |
| <img src="stanchion.png" width="280" alt="stanchion.png"> | [`stanchion.png`](stanchion.png) |
| <img src="street_lamp.png" width="280" alt="street_lamp.png"> | [`street_lamp.png`](street_lamp.png) |
| <img src="street_tree.png" width="280" alt="street_tree.png"> | [`street_tree.png`](street_tree.png) |
| <img src="sunglasses.png" width="280" alt="sunglasses.png"> | [`sunglasses.png`](sunglasses.png) |
| <img src="traffic_cone.png" width="280" alt="traffic_cone.png"> | [`traffic_cone.png`](traffic_cone.png) |
| <img src="trash_bin.png" width="280" alt="trash_bin.png"> | [`trash_bin.png`](trash_bin.png) |
| <img src="umbrella.png" width="280" alt="umbrella.png"> | [`umbrella.png`](umbrella.png) |
| <img src="wall_lantern.png" width="280" alt="wall_lantern.png"> | [`wall_lantern.png`](wall_lantern.png) |
| <img src="wand.png" width="280" alt="wand.png"> | [`wand.png`](wand.png) |
Binary file not shown.

Before

Width:  |  Height:  |  Size: 268 KiB

After

Width:  |  Height:  |  Size: 405 KiB

+15 -8
View File
@@ -1,15 +1,18 @@
# Development Status # Development Status
Current planning priorities are the unversioned **Character development** and **Local map Current planning priorities are the unversioned **3D model and local map re-evaluation** and
development** tracks in [`TODO.md`](../TODO.md); neither is part of the implemented list below **Character development** tracks in [`TODO.md`](../TODO.md); none is part of the implemented list
yet. The 0.10.0 release candidate remains the next versioned release. below yet. The re-evaluation scores the existing characters, gear, props and
venues against the locally installed Blender skill guidance before the roster expands. The 0.10.0
release candidate remains the next versioned release.
Implemented so far: Implemented so far:
- 3D re-evaluation — facade and prop pass (unversioned, 2026-11-03): the Masonic/El Capitan facade uses the photo-anchored `limestone_ashlar` field and warm-tinted stone; the TV Studio reuses `masonic_facade` (same Jimmy Kimmel starting point); the Joke Shop canopy signature band is white over black, the red curtain bays are seven tied-back hourglass drapes, and the hall wall uses `dark_stucco`. The `fire_hydrant` was rebuilt with a bolted flange, bonnet cap nut and larger outlets; `bollard` gained a flared base collar and `newspaper_box` a recessed window slot and door seam. A venue light-falloff gate asserts physical attenuation, and `tools/describe_image.py` adds free-form vision review alongside the structured judges. The scorecard, measurements and accepted limits are in [`3d-model-review.md`](3d-model-review.md).
- Godot 4.7.2 project scaffold, input map, procedural world builder (CI/local/release unified) - Godot 4.7.2 project scaffold, input map, procedural world builder (CI/local/release unified)
- Venue-driven simulation core: `ShiftCoordinator`, `VenueScenario`, `EventScheduler`, `NPCController` + FSM, `AccessVerifier`, `EscalationManager`, `RadioSystem`, `IncidentRecorder`, `ReputationEvaluator`, `CrowdSystem` - Venue-driven simulation core: `ShiftCoordinator`, `VenueScenario`, `EventScheduler`, `NPCController` + FSM, `AccessVerifier`, `EscalationManager`, `RadioSystem`, `IncidentRecorder`, `ReputationEvaluator`, `CrowdSystem`
- Three authored scenarios (El Capitan Entertainment Centre / Hollywood Boulevard, The Joke Shop, Late Night TV Studio) with access policies, NPC archetypes, and event pools - Three authored scenarios (El Capitan Entertainment Centre / Hollywood Boulevard, The Joke Shop, Late Night TV Studio) with access policies, NPC archetypes, and event pools
- Headless unit tests: **272 passing** (access rules and venue-correct access loadout, escalation, radio cooldown/battery, NPC reaction determinism, door lock, flashlight perception, persistence round-trip, settings round-trip, input remaps, navmesh, step colliders, skyline alpha, scenario data, full-shift simulation, wand screening, responder dispatch, localization strings, focus cone, action wheel, session shell, PLAN verbs and incident recording, crowd presentation, emergency aftermath, body-camera timeline, NPC theater poses, audio, accessibility, authored scenario content, string formatting, `.tres` venue round-trip, surface materials and environment, focus ranking and outfit/gait helpers, generated prop models, web export preset, prop atlas material, player movement, NPC character layers/LOD/queue, input bindings) - Headless unit tests: **277 passing** (access rules and venue-correct access loadout, escalation, radio cooldown/battery, NPC reaction determinism, door lock, flashlight perception, persistence round-trip, settings round-trip, input remaps, navmesh, step colliders, skyline alpha, scenario data, full-shift simulation, wand screening, responder dispatch, localization strings, focus cone, action wheel, session shell, PLAN verbs and incident recording, crowd presentation, emergency aftermath, body-camera timeline, NPC theater poses, audio, accessibility, authored scenario content, string formatting, `.tres` venue round-trip, surface materials and environment, focus ranking and outfit/gait helpers, generated prop models, web export preset, prop atlas material, player movement, NPC character layers/LOD/queue, input bindings, venue light-falloff gate, prop collider coverage)
- Simulation extras: protester archetype, CALL_SOMEONE reaction, door lock/secure mechanic (visual indicator), flashlight with night perception bonus, LATE shift phase reaching the violent-threat event - Simulation extras: protester archetype, CALL_SOMEONE reaction, door lock/secure mechanic (visual indicator), flashlight with night perception bonus, LATE shift phase reaching the violent-threat event
- First-person prototype with interaction HUD, access inspection, wand screening, radio report form (incl. emergency hold-to-confirm), dispatched responder avatars, aim-free targeting, venue cycling between all three scenarios, color-coded escalation feedback, procedural audio cues, navigation-mesh NPC paths, JSON-backed localized strings, persisted shift history, debug overlay, and shift review - First-person prototype with interaction HUD, access inspection, wand screening, radio report form (incl. emergency hold-to-confirm), dispatched responder avatars, aim-free targeting, venue cycling between all three scenarios, color-coded escalation feedback, procedural audio cues, navigation-mesh NPC paths, JSON-backed localized strings, persisted shift history, debug overlay, and shift review
- Control pass: focus cone on NPC heads with a billboarded blue circle in front of the face and name, action wheel (LMB/Space) with de-escalation-first slices, mouse-look freeze while a panel is open, acceleration-based walking, and named input actions (`action_menu`, `confirm`, `cancel`, `inspect`, `wand`) - Control pass: focus cone on NPC heads with a billboarded blue circle in front of the face and name, action wheel (LMB/Space) with de-escalation-first slices, mouse-look freeze while a panel is open, acceleration-based walking, and named input actions (`action_menu`, `confirm`, `cancel`, `inspect`, `wand`)
@@ -48,7 +51,8 @@ Implemented so far:
- NPC torso/hip transition (0.9.4 work): the pelvis and chest are slightly wider than the waist, giving shirts and jackets a readable taper into the hips without changing the build multipliers or the skeleton. The comparison is `sheet_npc_baseline_compare-torso.jpg`. - NPC torso/hip transition (0.9.4 work): the pelvis and chest are slightly wider than the waist, giving shirts and jackets a readable taper into the hips without changing the build multipliers or the skeleton. The comparison is `sheet_npc_baseline_compare-torso.jpg`.
- Release v0.9.6 (2026-11-03): the tagged commit `4bb2896` passed Gitea Actions run 1296 (checks + full build) and published seven artifacts (Linux, Windows, macOS, NSIS setup, AppImage, Web and Desktop HQ). Release page: <https://git.allucanget.biz/zwitschi/security-game/releases/tag/v0.9.6>. - Release v0.9.6 (2026-11-03): the tagged commit `4bb2896` passed Gitea Actions run 1296 (checks + full build) and published seven artifacts (Linux, Windows, macOS, NSIS setup, AppImage, Web and Desktop HQ). Release page: <https://git.allucanget.biz/zwitschi/security-game/releases/tag/v0.9.6>.
- Release candidate (0.10.0-rc.1, 2026-11-03): clean worktree `a9658ec` built Linux 161.5 MB, Windows 197.2 MB, macOS 148.0 MB, Web 97.8 MB and Desktop HQ 241.6 MB. The Web/HQ archives contain `CREDITS.md`, `PRIVACY.md`, `docs/accessibility.md` and `docs/known-limitations.md`; SHA-256 checksums were generated, the Linux and HQ binaries launched headless, and the Web index/wasm/pck/docs served with HTTP 200. The candidate is not published: external playtest, AI-provider/legal approval, macOS signing and the Windows/macOS target matrix remain open blockers. - Release candidate (0.10.0-rc.1, 2026-11-03): clean worktree `a9658ec` built Linux 161.5 MB, Windows 197.2 MB, macOS 148.0 MB, Web 97.8 MB and Desktop HQ 241.6 MB. The Web/HQ archives contain `CREDITS.md`, `PRIVACY.md`, `docs/accessibility.md` and `docs/known-limitations.md`; SHA-256 checksums were generated, the Linux and HQ binaries launched headless, and the Web index/wasm/pck/docs served with HTTP 200. The candidate is not published: external playtest, AI-provider/legal approval, macOS signing and the Windows/macOS target matrix remain open blockers.
- Save migration and reliability (0.10.0 work): committed 0.8-era settings/campaign/history fixtures and a 0.9.0 checkpoint. The loader default-fills old settings, keeps campaign progress and validates checkpoints for all three venues with an open incident, NPC rows, door, flashlight and body-camera state. Corrupt and partial files fall back to defaults; a blocked atomic replace leaves the prior valid file intact. `_load_json` uses the non-logging JSON parser; save locations and rollback are documented in `getting-started.md`. Suite is 272/272. - Save migration and reliability (0.10.0 work): committed 0.8-era settings/campaign/history fixtures and a 0.9.0 checkpoint. The loader default-fills old settings, keeps campaign progress and validates checkpoints for all three venues with an open incident, NPC rows, door, flashlight and body-camera state. Corrupt and partial files fall back to defaults; a blocked atomic replace leaves the prior valid file intact. `_load_json` uses the non-logging JSON parser; save locations and rollback are documented in `getting-started.md`. Suite is 277/277;
Python tooling is 161/161 after the GLB `inspect` intake coverage.
- Integration checkpoint (0.9.6 work): the clean worktree at `f5b8ef2` rebuilt all five release packages and the Desktop HQ zip without ignored `tmp/`/`build/` content (Linux 161.5 MB, Windows 197.1 MB, macOS 148.0 MB, Web 97.8 MB, HQ 241.5 MB). The Web zip contains `index.html`, `index.wasm` and `index.pck`; the HQ zip contains `override.cfg` and launches headless with the Forward+ override. Current verification: Godot 263/263, Python 101/101, 14 smokes green, 24-NPC budget 6.90 ms / 168 meshes / 131,616 triangles, gallery 21 good / 0 bad, screen judge 21/21 match with 0 review/diff, and a pinned realism judge (`z-ai/glm-5.3-flash`, one pass per shot) at mean overall 2.1 and Pillow gap 0.291. No new gameplay or content changes. - Integration checkpoint (0.9.6 work): the clean worktree at `f5b8ef2` rebuilt all five release packages and the Desktop HQ zip without ignored `tmp/`/`build/` content (Linux 161.5 MB, Windows 197.1 MB, macOS 148.0 MB, Web 97.8 MB, HQ 241.5 MB). The Web zip contains `index.html`, `index.wasm` and `index.pck`; the HQ zip contains `override.cfg` and launches headless with the Forward+ override. Current verification: Godot 263/263, Python 101/101, 14 smokes green, 24-NPC budget 6.90 ms / 168 meshes / 131,616 triangles, gallery 21 good / 0 bad, screen judge 21/21 match with 0 review/diff, and a pinned realism judge (`z-ai/glm-5.3-flash`, one pass per shot) at mean overall 2.1 and Pillow gap 0.291. No new gameplay or content changes.
- Release v0.9.5 (2026-11-02): the tagged commit `4bc6390` passed Gitea Actions run 922 (checks + full build) and published seven artifacts (Linux, Windows, macOS, NSIS setup, AppImage, Web and Desktop HQ). Release page: <https://git.allucanget.biz/zwitschi/security-game/releases/tag/v0.9.5>. - Release v0.9.5 (2026-11-02): the tagged commit `4bc6390` passed Gitea Actions run 922 (checks + full build) and published seven artifacts (Linux, Windows, macOS, NSIS setup, AppImage, Web and Desktop HQ). Release page: <https://git.allucanget.biz/zwitschi/security-game/releases/tag/v0.9.5>.
- Release v0.9.4 (2026-11-02): the tagged commit `a57b86c` passed the Gitea checks and full build and published seven artifacts (Linux, Windows, macOS, NSIS setup, AppImage, Web and Desktop HQ). Release page: <https://git.allucanget.biz/zwitschi/security-game/releases/tag/v0.9.4>. - Release v0.9.4 (2026-11-02): the tagged commit `a57b86c` passed the Gitea checks and full build and published seven artifacts (Linux, Windows, macOS, NSIS setup, AppImage, Web and Desktop HQ). Release page: <https://git.allucanget.biz/zwitschi/security-game/releases/tag/v0.9.4>.
@@ -58,6 +62,8 @@ Implemented so far:
- Texture visual verification (0.9.5 work): the nine-stage realism run used `z-ai/glm-5.3-flash` once per shot; mean `after` scores were overall 1.8, lighting 2.3, materials 1.8, texture detail 1.2, backdrop 2.0 and characters 1.2, with a Pillow metric gap of 0.306. The judge remains an optional review aid, not a CI gate. The committed before/after close-up sheet is [`blender_previews/sheet_texture_refinement_0.9.5.jpg`](blender_previews/sheet_texture_refinement_0.9.5.jpg); it records that the paver/Walk of Fame and NPC fabric repairs are visible, while asphalt, limestone and skyline picks held without a replacement. `tools/check_screenshots.sh` passed 21 good / 0 bad and the screen-design judge passed 21/21 match with 0 review. - Texture visual verification (0.9.5 work): the nine-stage realism run used `z-ai/glm-5.3-flash` once per shot; mean `after` scores were overall 1.8, lighting 2.3, materials 1.8, texture detail 1.2, backdrop 2.0 and characters 1.2, with a Pillow metric gap of 0.306. The judge remains an optional review aid, not a CI gate. The committed before/after close-up sheet is [`blender_previews/sheet_texture_refinement_0.9.5.jpg`](blender_previews/sheet_texture_refinement_0.9.5.jpg); it records that the paver/Walk of Fame and NPC fabric repairs are visible, while asphalt, limestone and skyline picks held without a replacement. `tools/check_screenshots.sh` passed 21 good / 0 bad and the screen-design judge passed 21/21 match with 0 review.
- NPC visual optimization (0.9.4, complete 2026-11-02): all eight variants passed the portrait/readability, proportion, gear, foot/shoe, headgear and final-context gates. The library uses an 8,000-triangle / 8,000-glTF-vertex cap (up from 6,000/5,000; `npc_base` fallback remains 6,000/4,000); current characters measure 4,482–5,474 triangles and 4,260–5,494 vertices. The 48-frame baseline and 96-frame final-context review pass, the hand/gear offset and shoes are in, and the accepted stylized limits are documented in `npc-visual-review.md`. - NPC visual optimization (0.9.4, complete 2026-11-02): all eight variants passed the portrait/readability, proportion, gear, foot/shoe, headgear and final-context gates. The library uses an 8,000-triangle / 8,000-glTF-vertex cap (up from 6,000/5,000; `npc_base` fallback remains 6,000/4,000); current characters measure 4,482–5,474 triangles and 4,260–5,494 vertices. The 48-frame baseline and 96-frame final-context review pass, the hand/gear offset and shoes are in, and the accepted stylized limits are documented in `npc-visual-review.md`.
- NPC face-detail pass (0.9.4 work): ala wings and a smaller nose bridge/tip, one rounded mouth slot, and a darker ear concha; all eight rebuilt. The comparison is `sheet_npc_baseline_compare-face-detail.jpg`. - NPC face-detail pass (0.9.4 work): ala wings and a smaller nose bridge/tip, one rounded mouth slot, and a darker ear concha; all eight rebuilt. The comparison is `sheet_npc_baseline_compare-face-detail.jpg`.
- NPC face realism pass (2026-11-03/04): all eight variants now use the `seg=24/rings=16` head with a subtle brow ridge, a fuller lower lip and both eyelids (recessed creases were rejected because they bake as dark AO patches). Vision-reviewed as cleaner/more realistic than the 0.9.4 face; characters measure 5,038–5,900 tris / 4,756–5,902 verts (still under 8,000). `sheet_npc_baseline.jpg` was refreshed.
- Crowd-variety roster (character development, 2026-11-04): four new variants — `npc_crowd_a` (slim/bun/sunglasses), `npc_crowd_b` (broad/bald/beard/shoulder bag), `npc_crowd_c` (coat/umbrella), `npc_crowd_d` (slim/hood/cup) — built with the realistic face and wired into `CHARACTER_POOLS` so the routine crowd roles (tourist, confused visitor, intoxicated) pick them by seed instead of cloning `npc_casual`. The 24-NPC smoke is now 152,464 tris / 168 meshes / 6.94 ms (under the 50 ms budget).
- NPC headgear clearance (0.9.4 work): the 96-frame final-context review after the face-detail pass confirms the cap, firefighter helmet, hood and sunglasses clear the refined brow and eyes; no gear rebuild was needed. - NPC headgear clearance (0.9.4 work): the 96-frame final-context review after the face-detail pass confirms the cap, firefighter helmet, hood and sunglasses clear the refined brow and eyes; no gear rebuild was needed.
- NPC footwear pass (0.9.4 work): casual shoes gained rounded toe and heel caps; responder/firefighter boots gained matching toe/heel volumes while retaining the black rubber boot language. All eight rebuilt; comparison `sheet_npc_baseline_compare-shoes.jpg`. - NPC footwear pass (0.9.4 work): casual shoes gained rounded toe and heel caps; responder/firefighter boots gained matching toe/heel volumes while retaining the black rubber boot language. All eight rebuilt; comparison `sheet_npc_baseline_compare-shoes.jpg`.
- NPC hand-item grip (0.9.4 work): runtime `HAND_ITEM_FORWARD` moves every hand gear 4 cm forward from the wrist proxy, so phone, cup, clipboard, camera, flashlight, wand and radio sit in the open palm instead of partly inside it. The open-hand/no-finger-rig limit is accepted for this stylized release; the comparison is `sheet_npc_hands_grip_compare.jpg`. - NPC hand-item grip (0.9.4 work): runtime `HAND_ITEM_FORWARD` moves every hand gear 4 cm forward from the wrist proxy, so phone, cup, clipboard, camera, flashlight, wand and radio sit in the open palm instead of partly inside it. The open-hand/no-finger-rig limit is accepted for this stylized release; the comparison is `sheet_npc_hands_grip_compare.jpg`.
@@ -66,7 +72,8 @@ Implemented so far:
- NPC P1 portrait fixes (0.9.4 work): tourists now hide their photo-pose camera bag outside `photo`/`film` poses, removing the duplicate-backpack silhouette; the backpack gear was rebuilt with flattened, forward chest straps and a fresh AO map. The before/after sheet is [`blender_previews/sheet_npc_baseline_compare-p1.jpg`](blender_previews/sheet_npc_baseline_compare-p1.jpg); the remaining face/hand work was closed under the 0.9.4 acceptance limits. - NPC P1 portrait fixes (0.9.4 work): tourists now hide their photo-pose camera bag outside `photo`/`film` poses, removing the duplicate-backpack silhouette; the backpack gear was rebuilt with flattened, forward chest straps and a fresh AO map. The before/after sheet is [`blender_previews/sheet_npc_baseline_compare-p1.jpg`](blender_previews/sheet_npc_baseline_compare-p1.jpg); the remaining face/hand work was closed under the 0.9.4 acceptance limits.
- NPC visual baseline (0.9.4 work): `src/test/capture_npc_baseline.gd` captures all eight library characters from front, three-quarter, profile, back, full-body and crowd views in a neutral studio (48 frames). The criteria, measurements and ranked gaps are in [`npc-visual-review.md`](npc-visual-review.md); the committed sheet is [`blender_previews/sheet_npc_baseline.jpg`](blender_previews/sheet_npc_baseline.jpg). No model changes were made in this baseline step. - NPC visual baseline (0.9.4 work): `src/test/capture_npc_baseline.gd` captures all eight library characters from front, three-quarter, profile, back, full-body and crowd views in a neutral studio (48 frames). The criteria, measurements and ranked gaps are in [`npc-visual-review.md`](npc-visual-review.md); the committed sheet is [`blender_previews/sheet_npc_baseline.jpg`](blender_previews/sheet_npc_baseline.jpg). No model changes were made in this baseline step.
- UI-state capture pass (0.9.3 work): `src/test/capture_ui_states.gd` adds committed captures 14–21 for the start menu, pause, settings, shift review, emergency radio, action wheel, crowd panic and responder arrival. Every one of the 21 catalogue entries now has a current-build capture; `tools/check_screenshots.sh` reports 21 good / 0 bad and the automatic judge reports 21/21 match, 0 diff. Crowd panic and responder arrival are staged presentation frames, not gameplay changes. - UI-state capture pass (0.9.3 work): `src/test/capture_ui_states.gd` adds committed captures 14–21 for the start menu, pause, settings, shift review, emergency radio, action wheel, crowd panic and responder arrival. Every one of the 21 catalogue entries now has a current-build capture; `tools/check_screenshots.sh` reports 21 good / 0 bad and the automatic judge reports 21/21 match, 0 diff. Crowd panic and responder arrival are staged presentation frames, not gameplay changes.
- Realism adoption (post-v0.6.0): v2 per-phase skylines and surface tiles with normal maps, retuned sun/exposure/fog, wet asphalt, denser foliage, a visible additive flashlight beam, and refreshed staging captures. `tools/check_screenshots.sh` is the repeatable capture/compare gate; judge is clean of `diff` verdicts. - Realism adoption (post-v0.6.0): v2 per-phase skylines and surface tiles with normal maps, retuned sun/exposure/fog, wet asphalt, denser foliage, a tight additive flashlight spot with no beam geometry, and refreshed
staging captures. `tools/check_screenshots.sh` is the repeatable capture/compare gate; judge is clean of `diff` verdicts.
- Input/reliability fixes: selecting a venue releases the start-menu input lock and recaptures the mouse; the body-camera overlay no longer covers the shift status. Mouse look now reads at `_input`, restores capture on window focus/click-back, and the HUD is mouse-transparent. Normal radio reports submit on click; emergency calls still require the hold-to-confirm path. - Input/reliability fixes: selecting a venue releases the start-menu input lock and recaptures the mouse; the body-camera overlay no longer covers the shift status. Mouse look now reads at `_input`, restores capture on window focus/click-back, and the HUD is mouse-transparent. Normal radio reports submit on click; emergency calls still require the hold-to-confirm path.
- Production-quality pass (v0.9.0): mixer/accessibility settings, audio volume clamping, 24-NPC budget smoke, shortened coat/dress stride, and a unified Godot 4.7.2 CI/local support baseline with documented upgrade/rollback requirements. - Production-quality pass (v0.9.0): mixer/accessibility settings, audio volume clamping, 24-NPC budget smoke, shortened coat/dress stride, and a unified Godot 4.7.2 CI/local support baseline with documented upgrade/rollback requirements.
- Campaign and first-hour pass (v0.8.0): campaign progression, checkpoint resume, difficulty presets, a searchable Help overlay, recovery events, contextual dialogue, policy/debrief lines and tutorial/replay/skip. Scripted QA bypasses the tutorial unless `--tutorial` is passed. - Campaign and first-hour pass (v0.8.0): campaign progression, checkpoint resume, difficulty presets, a searchable Help overlay, recovery events, contextual dialogue, policy/debrief lines and tutorial/replay/skip. Scripted QA bypasses the tutorial unless `--tutorial` is passed.
@@ -75,8 +82,8 @@ Implemented so far:
- Desktop HQ (v0.7.1): optional Forward+ Windows/Linux zip with volumetric fog, SDFGI and a volumetric flashlight; the default Compatibility/Web builds and headless tests gate the effect off. A/B captures are generated locally under `docs/screens/realism/` (gitignored). - Desktop HQ (v0.7.1): optional Forward+ Windows/Linux zip with volumetric fog, SDFGI and a volumetric flashlight; the default Compatibility/Web builds and headless tests gate the effect off. A/B captures are generated locally under `docs/screens/realism/` (gitignored).
- Hollywood landmark map (map optimization): the default venue is now a stylized reconstruction of 6840 Hollywood Blvd (the 1921 Masonic Temple / El Capitan Entertainment Centre) with a six-column Ionic portico, eight stone steps, Masonic parapet motto and medallions, three red event banners, central and side entrances, the El Capitan Theatre and east retail neighbours, the Ovation Hollywood arcade opposite, the Walk of Fame terrazzo and a four-lane boulevard with red kerb paint. The facade uses the shared limestone/stone material; the whole venue measures **58,884 triangles across 409 meshes** in the map-budget test. The venue menu exposes separate **Day** and **Night** Hollywood rows; the night row resolves to the same scenario with a late-phase offset, so its whole shift stays after dark. Real-site references and the geometry mapping are in [`hollywood-boulevard-map.md`](hollywood-boulevard-map.md). - Hollywood landmark map (map optimization): the default venue is now a stylized reconstruction of 6840 Hollywood Blvd (the 1921 Masonic Temple / El Capitan Entertainment Centre) with a six-column Ionic portico, eight stone steps, Masonic parapet motto and medallions, three red event banners, central and side entrances, the El Capitan Theatre and east retail neighbours, the Ovation Hollywood arcade opposite, the Walk of Fame terrazzo and a four-lane boulevard with red kerb paint. The facade uses the shared limestone/stone material; the whole venue measures **58,884 triangles across 409 meshes** in the map-budget test. The venue menu exposes separate **Day** and **Night** Hollywood rows; the night row resolves to the same scenario with a late-phase offset, so its whole shift stays after dark. Real-site references and the geometry mapping are in [`hollywood-boulevard-map.md`](hollywood-boulevard-map.md).
- Day/night scenery variants (map optimization): the Hollywood row in the venue menu is split into Day and Night entries, with localized names/blurbs. The night entry uses `ShiftCoordinator.phase_offset_s` to start a full-length shift in `LATE` while the clock still starts at 00:00; the scheduler reads the offset time so late-night routine traffic and the late violent-threat event still fire, and the offset round-trips through checkpoints. Three `LATE` routine events keep the night street populated. Local lights were retuned from constant falloff to linear attenuation so sconces pool instead of flooding the stone. - Day/night scenery variants (map optimization): the Hollywood row in the venue menu is split into Day and Night entries, with localized names/blurbs. The night entry uses `ShiftCoordinator.phase_offset_s` to start a full-length shift in `LATE` while the clock still starts at 00:00; the scheduler reads the offset time so late-night routine traffic and the late violent-threat event still fire, and the offset round-trips through checkpoints. Three `LATE` routine events keep the night street populated. Local lights were retuned from constant falloff to linear attenuation so sconces pool instead of flooding the stone.
- Joke Shop / Sunset Strip map (map optimization): the second venue is now a stylized reconstruction of The Comedy Store block at 8433 Sunset Blvd, with a 27 m black hall, signature-covered sloping canopy, circular **THE JOKE SHOP** blade sign, red velvet curtain bays, a west-end entrance, cream and white low-rise neighbours, a dry hillside with stucco houses and palms behind the roofline, and a low retail/billboard frontage across Sunset. The same geometry serves day and late lighting through the phase system. Real-site references and limits are in [`joke-shop-map.md`](joke-shop-map.md); the map measures **22,680 triangles across 454 meshes** in the budget test. - Joke Shop / Sunset Strip map (map optimization): the second venue is now a stylized reconstruction of The Comedy Store block at 8433 Sunset Blvd, with a 27 m black hall, signature-covered sloping canopy, circular **THE JOKE SHOP** blade sign, seven tied-back red velvet curtain drapes, a west-end entrance, cream and white low-rise neighbours, a dry hillside with stucco houses and palms behind the roofline, and a low retail/billboard frontage across Sunset. The same geometry serves day and late lighting through the phase system. Real-site references and limits are in [`joke-shop-map.md`](joke-shop-map.md); the map measures **25,828 triangles across 518 meshes** in the budget test.
- Venue geometry (v0.7.0, Joke Shop frontage superseded by the map-optimization pass): the TV Studio builds a stone facade, bulb canopy, glossy black car and barrier line. `WorldBuilder.VENUE_SPECS` drives facade/street/nav dimensions, and `GameManager` rebuilds only the world container when the venue changes. - Venue geometry (v0.7.0, Joke Shop frontage superseded by the map-optimization pass): the TV Studio is the same El Capitan block restaged for a late-night arrival — a stone facade, bulb canopy, glossy black car and barrier line. `WorldBuilder.VENUE_SPECS` drives facade/street/nav dimensions, and `GameManager` rebuilds only the world container when the venue changes.
- Gear fit (post-v0.6.0): Blender gear is measured against the avatar head/skirt silhouette and the checks run in both the Python tooling and the headless suite. Sunglasses, the shoulder bag and the firefighter helmet were fitted to the new faces; the Influencer portrait and gallery were recaptured with a before/after report. - Gear fit (post-v0.6.0): Blender gear is measured against the avatar head/skirt silhouette and the checks run in both the Python tooling and the headless suite. Sunglasses, the shoulder bag and the firefighter helmet were fitted to the new faces; the Influencer portrait and gallery were recaptured with a before/after report.
- End-to-end interaction pass (0.9.3 work): `smoke_ui_flows.gd` drives inspection allow/deny, normal vs emergency radio, Help filtering, wand allow/deny and review return-to-menu in the real scene; campaign and timeline smokes cover review continue and timeline round-trips. - End-to-end interaction pass (0.9.3 work): `smoke_ui_flows.gd` drives inspection allow/deny, normal vs emergency radio, Help filtering, wand allow/deny and review return-to-menu in the real scene; campaign and timeline smokes cover review continue and timeline round-trips.
- Destructive-action pass (0.9.3 work): reset campaign and tutorial replay share a guarded confirmation dialog (one open instance, one emission, Cancel is inert); emergency send remains hold-to-confirm with no post-submit double-fire. Covered by session/radio tests and recorded in `docs/ui-copy.md`. - Destructive-action pass (0.9.3 work): reset campaign and tutorial replay share a guarded confirmation dialog (one open instance, one emission, Cancel is inert); emergency send remains hold-to-confirm with no post-submit double-fire. Covered by session/radio tests and recorded in `docs/ui-copy.md`.
+2 -2
View File
@@ -29,7 +29,7 @@ offers the same map as **Hollywood Boulevard — Day** and **Hollywood Boulevard
— Night**; the night variant starts directly in the late phase instead of — Night**; the night variant starts directly in the late phase instead of
waiting for the shift clock. waiting for the shift clock.
The original scenario places the guard at the top of the eight stone steps outside the historic Masonic Temple / El Capitan Entertainment Centre on Hollywood Boulevard. Tourists, street performers, influencers, confused visitors, intoxicated pedestrians, trespassers, people experiencing a mental-health crisis, and rare violent threats may approach the entrance. The original scenario — the starting point of the campaign — places the guard at the top of the eight stone steps outside the historic Masonic Temple / El Capitan Entertainment Centre on Hollywood Boulevard, the building that houses the *Jimmy Kimmel Live!* stage and studio. Tourists, street performers, influencers, confused visitors, intoxicated pedestrians, trespassers, people experiencing a mental-health crisis, and rare violent threats may approach the entrance.
Authorized people must either be recognized by the guard or present a valid wristband. Wristbands can have different colors, patterns, dates, or event markings. They may be valid, expired, counterfeit, or missing. Authorized people must either be recognized by the guard or present a valid wristband. Wristbands can have different colors, patterns, dates, or event markings. They may be valid, expired, counterfeit, or missing.
@@ -39,7 +39,7 @@ The Joke Shop is a Sunset Strip comedy club inspired by the real Comedy Store at
### Hollywood Boulevard Late Night TV Studio ### Hollywood Boulevard Late Night TV Studio
This scenario combines the previously defined NPC types with a busy television-studio entrance: a stone facade, a bulb-lit canopy, a glossy black car at the curb, and stanchions/barriers holding the arrival line. The player manages audience members, production staff, performers, guests, deliveries, celebrity arrivals, tourists, street performers, influencers, confused visitors, intoxicated pedestrians, trespassers, people experiencing a mental-health crisis, and rare violent threats. This scenario combines the previously defined NPC types with a busy television-studio entrance: the same El Capitan Entertainment Centre block as the Hollywood day shift, restaged as a late-night studio arrival — the stone facade and steps, a bulb-lit canopy, a glossy black car at the curb, and stanchions/barriers holding the arrival line. The player manages audience members, production staff, performers, guests, deliveries, celebrity arrivals, tourists, street performers, influencers, confused visitors, intoxicated pedestrians, trespassers, people experiencing a mental-health crisis, and rare violent threats.
The studio uses wristbands, credentials, tickets, guest-list confirmation, and personal recognition to authorize entry. Crowd control, filming boundaries, following authorized guests through the door, and counterfeit credentials are key events. The studio uses wristbands, credentials, tickets, guest-list confirmation, and personal recognition to authorize entry. Crowd control, filming boundaries, following authorized guests through the door, and counterfeit credentials are key events.
+41 -1
View File
@@ -11,7 +11,10 @@ eye height, while side streets and interiors are simplified.
- **Coordinates:** 34.10118 N, 118.34009 W (OSM way `424024147`). - **Coordinates:** 34.10118 N, 118.34009 W (OSM way `424024147`).
- **Building:** the 1921 Hollywood Masonic Temple, designed by John C. Austin in - **Building:** the 1921 Hollywood Masonic Temple, designed by John C. Austin in
the Classical Revival style; now the El Capitan Entertainment Centre and the the Classical Revival style; now the El Capitan Entertainment Centre and the
home of *Jimmy Kimmel Live!*. home of *Jimmy Kimmel Live!*. This is the game's **starting point**: the first
shift (Hollywood) and the late-night TV Studio arrival both begin at this
building, where the Kimmel stage and studio occupy the interior behind the
six-column facade.
- **Facade:** a light stone/render Neoclassical front with six oversized Ionic - **Facade:** a light stone/render Neoclassical front with six oversized Ionic
columns, a recessed main entrance reached by eight stone steps, ornamental columns, a recessed main entrance reached by eight stone steps, ornamental
iron door grilles, a continuous crosscut-grille transom, two street-level side iron door grilles, a continuous crosscut-grille transom, two street-level side
@@ -22,6 +25,19 @@ eye height, while side streets and interiors are simplified.
- **Sidewalk:** the Hollywood Walk of Fame terrazzo strip with brass stars runs - **Sidewalk:** the Hollywood Walk of Fame terrazzo strip with brass stars runs
along the kerb; the kerb is painted red in the reference photographs. along the kerb; the kerb is painted red in the reference photographs.
### Late Night TV Studio venue
The game's third venue is **the same block**, not a separate real site. The building houses
*Jimmy Kimmel Live!*, so the "Late Night TV Studio" scenario restages 6840 Hollywood Blvd as a
studio arrival: the same stone facade and steps, plus a bulb-lit canopy, a glossy black car at the
kerb, a barrier/stanchion line and an audience queue. The Kimmel stage/audience and the entrance
marquee are researched as local-only reference sets under
`tmp/research/jimmy-kimmel-stage/` and `tmp/research/jimmy-kimmel-entrance/` (gitignored); the
photo-anchored entrance concepts live in
[`screens/concepts/hollywood_boulevard/README.md`](screens/concepts/hollywood_boulevard/README.md). `VENUE_SPECS["tv_studio"]` is a variant of the
Hollywood spec (30.0 m facade instead of 29.6 m, arrival staging instead of the day-time banners),
and it shares this block's reference board rather than owning one.
## Game mapping ## Game mapping
| Real feature | In-game representation | | Real feature | In-game representation |
@@ -37,6 +53,7 @@ eye height, while side streets and interiors are simplified.
| Ovation Hollywood | `OvationHollywood` arcade with seven arched openings, sign and south sidewalk | | Ovation Hollywood | `OvationHollywood` arcade with seven arched openings, sign and south sidewalk |
| Walk of Fame | `WalkOfFame` dark terrazzo band with ten stars | | Walk of Fame | `WalkOfFame` dark terrazzo band with ten stars |
| Four-lane boulevard | double-yellow centre, broken white lane lines, red kerb paint and crosswalk | | Four-lane boulevard | double-yellow centre, broken white lane lines, red kerb paint and crosswalk |
| TV Studio arrival staging | `VENUE_SPECS["tv_studio"]`: same six-column Masonic facade and eight steps (reuses `masonic_facade`), plus `bulb_canopy`, `sedan`, `handrail` and barrier placements instead of the day-time marquee |
The generated AI references live in The generated AI references live in
[`docs/screens/concepts/hollywood_boulevard/`](screens/concepts/hollywood_boulevard/README.md). [`docs/screens/concepts/hollywood_boulevard/`](screens/concepts/hollywood_boulevard/README.md).
@@ -63,14 +80,37 @@ not texture or geometry sources.
- Local lights use linear attenuation (`omni_attenuation = 1.0`). Godot treats - Local lights use linear attenuation (`omni_attenuation = 1.0`). Godot treats
`0.0` as constant falloff, which previously turned the night facade into a `0.0` as constant falloff, which previously turned the night facade into a
flat yellow wall; the sconces now pool light instead. flat yellow wall; the sconces now pool light instead.
- The masonic facade field uses the `limestone_ashlar` pick: a seamless ashlar
tile generated reference-anchored on the 2009 facade photo (CC BY 2.0),
768 px over ~4.6 m of wall (~167 px/m), so the wall carries course joints and
per-block value variation instead of flat plaster.
- Night balance: the event banners carry a warm self-light and the marquee sign
face + bulbs brighten after dark (registered with `_marquee_emissive`), so the
facade reads as practical-lights-only rather than a flat lit wall. The marquee
canopy stays black metal by design — the fictional "GIG LINE" marquee, not the
red El Capitan Theatre marquee next door.
## References ## References
The committed, license-cleared photo board for this block — with the provenance sidecar and the
decisions each photo informed — is in
[`screens/refs/hollywood/README.md`](screens/refs/hollywood/README.md). The three-up boards
(real photo | generated concept | current capture) live in
[`screens/boards/README.md`](screens/boards/README.md) and make the remaining facade-realism gap
visible: the capture panel still shows flat material bands where the photo has limestone value
variation, joint lines and reveal depth.
- [Hollywood Masonic Temple — Wikipedia](https://en.wikipedia.org/wiki/Hollywood_Masonic_Temple) - [Hollywood Masonic Temple — Wikipedia](https://en.wikipedia.org/wiki/Hollywood_Masonic_Temple)
- [El Capitan Entertainment Centre — OpenStreetMap way 424024147](https://www.openstreetmap.org/way/424024147) - [El Capitan Entertainment Centre — OpenStreetMap way 424024147](https://www.openstreetmap.org/way/424024147)
- [El Capitan Theatre — OpenStreetMap way 424024148](https://www.openstreetmap.org/way/424024148) - [El Capitan Theatre — OpenStreetMap way 424024148](https://www.openstreetmap.org/way/424024148)
- [Ovation Hollywood — OpenStreetMap way 151485232](https://www.openstreetmap.org/way/151485232) - [Ovation Hollywood — OpenStreetMap way 151485232](https://www.openstreetmap.org/way/151485232)
- [Hollywood Masonic Temple facade — Wikimedia Commons](https://commons.wikimedia.org/wiki/File:El_Capitan_Theater_frontal_fachade-The_Masonic_Temple.jpg) - [Hollywood Masonic Temple facade — Wikimedia Commons](https://commons.wikimedia.org/wiki/File:El_Capitan_Theater_frontal_fachade-The_Masonic_Temple.jpg)
- Local frames that changed a decision (gitignored, never committed):
- `tmp/research/elcapitan-2026/` (recent Commons geosearch) → established that no recent photo
frames the El Capitan facade straight-on in daylight, so the 2009 CC BY frame stays the
geometry reference.
- `tmp/research/jimmy-kimmel-entrance/07.jpg` → the photo anchor for the four Jimmy Kimmel
entrance concepts (day/night × gemini/gpt), confirming the starting-point building.
- [Hollywood Masonic Temple and El Capitan Theatre, 2013 — Wikimedia Commons](https://commons.wikimedia.org/wiki/File:Hollywood_Masonic_Temple_2013-10-13_10-02-25.jpg) - [Hollywood Masonic Temple and El Capitan Theatre, 2013 — Wikimedia Commons](https://commons.wikimedia.org/wiki/File:Hollywood_Masonic_Temple_2013-10-13_10-02-25.jpg)
## Verification ## Verification
+39 -12
View File
@@ -27,18 +27,34 @@ signature-covered canopy, with the circular blade sign above the roof, red
curtains along the frontage and the main entrance set toward the west end. The curtains along the frontage and the main entrance set toward the west end. The
hillside houses behind it are part of the silhouette from the sidewalk. hillside houses behind it are part of the silhouette from the sidewalk.
## Measured proportions (vision-extracted from the local frames, 2026-11-03)
`tools/describe_image.py` was used to read the gitignored `tmp/research/comedy-store/` frames
(the harness cannot display images directly). Two frames disagreed on crop-dependent details, so
the ranges below are the reconciled reading; the game spec is a deliberate compression.
| Feature | Reference reading | Game spec | Reconciliation |
| --- | --- | --- | --- |
| Street frontage | ~35–40 m wide, parapet ~5.5–6 m (≈6:1 width:height), rounded corner | 27 m × 6.0 m | Facade height lowered 8.4 → 6.0 m (2026-11-03); width still compressed for the playable block |
| Canopy | ~4–4.5 m projection, tilts forward noticeably | 4.9 m at 11° | Close; the forward pitch is confirmed |
| Fascia band | black, 30–40 cm deep, marquee-bulb string | black `SignatureCanopy` fascia + `CanopySignatures` + bulbs | Matches; signatures now white |
| Circular blade sign | ~3–4 m diameter white disc, red serif wordmark, pole-mounted | 3.9 m white disc, black wordmark, pole | Diameter matches; the game wordmark is black (fictional `THE JOKE SHOP`) |
| Red curtain bays | 3–5 visible depending on frame, floor-length, tied-back mid-bay | 7 tied-back drapes | Count is crop-dependent; 7 is a readable stylization, not a defect |
| Entrance | west end, recessed at the rounded corner | west end at x = -8.8, recessed | Matches |
| Roofline | taller dark mass rises behind the right half | `RoofPlant` box at x = 5.5 | Matches |
## How the map maps to the real site ## How the map maps to the real site
| Real element | Game implementation | | Real element | Game implementation |
| --- | --- | | --- | --- |
| Low black comedy hall | 27 m × 12 m footprint, 8.4 m street wall; matte black concrete surface with a low plinth and parapet | | Low black comedy hall | 27 m × 12 m footprint, 6.0 m street wall; matte black concrete surface with a low plinth and parapet |
| Deep overhanging canopy | 4.9 m sloped slab dropping about 1 m to the outer fascia; the fascia carries white signature lettering and the club name | | Deep overhanging canopy | 4.9 m sloped slab dropping about 1 m to the outer fascia; the fascia carries white signature lettering and the club name |
| Signature-covered front | Two `Label3D` signature bands on the fascia plus a smaller wall panel, so the handwriting reads at gameplay distance without dozens of decals | | Signature-covered front | Two `Label3D` signature bands on the fascia plus a smaller wall panel, so the handwriting reads at gameplay distance without dozens of decals |
| Circular blade sign | 3.9 m white disc with a black rim on a roof pole; `THE JOKE SHOP` lettering faces the street | | Circular blade sign | 3.9 m white disc with a black rim on a roof pole; `THE JOKE SHOP` lettering faces the street |
| Red curtains | Four three-fold velvet bays with tiebacks between the entrance and the east end; a red velvet entrance curtain | | Red curtains | Seven tied-back velvet drapes between the entrance and the east end — each cinched into an hourglass with a scalloped hem and dark recess between bays; a red velvet entrance curtain |
| West-end entrance | Recessed opening at x = -8.8 m with a low step, brass pulls and the door-lock indicator | | West-end entrance | Recessed opening at x = -8.8 m with a low step, brass pulls and the door-lock indicator |
| Warm practicals | Sconces along the wall, canopy downlights, entrance wash and three ground uplights; all off in daylight and switched by `set_night_mode()` | | Warm practicals | Sconces along the wall, canopy downlights, entrance wash and three ground uplights; all off in daylight and switched by `set_night_mode()` |
| Neighbouring low-rise frontage | Cream Mediterranean block west (balconies, red awning) and white commercial block east (ribbon windows, lobby) | | Neighbouring low-rise frontage | Cream Mediterranean block west (balconies, red awning) with a stepped-back 5–6 storey pink hotel tower behind it (`WestHotelTower`, the Ramada Plaza mass); white commercial block east (ribbon windows, lobby) |
| Hillside and houses | Fog-free unshaded 60° ramp behind the rear wall with stucco houses, shrubs and palms; its tint drops to a dark silhouette at night | | Hillside and houses | Fog-free unshaded 60° ramp behind the rear wall with stucco houses, shrubs and palms; its tint drops to a dark silhouette at night |
| Opposite side of Sunset | Low retail row, rooftop billboard, neon and palms as background context beyond the far kerb | | Opposite side of Sunset | Low retail row, rooftop billboard, neon and palms as background context beyond the far kerb |
| Sidewalk furniture | Palms, queue barriers, stanchions, bins, planters, a-frame sign, hydrant and a parked sedan; prop placements pass the shared validator | | Sidewalk furniture | Palms, queue barriers, stanchions, bins, planters, a-frame sign, hydrant and a parked sedan; prop placements pass the shared validator |
@@ -51,7 +67,7 @@ hillside houses behind it are part of the silhouette from the sidewalk.
Hollywood block and a crosswalk in front of the entrance. Hollywood block and a crosswalk in front of the entrance.
- **Playable area:** x = -15…15, z = -0.6…14.0. The guard starts on the west - **Playable area:** x = -15…15, z = -0.6…14.0. The guard starts on the west
side of the entrance at (-4.8, 0.1, 1.4), facing the approach. side of the entrance at (-4.8, 0.1, 1.4), facing the approach.
- **Map budget:** the headless audit measures **22,680 triangles across 454 - **Map budget:** the headless audit measures **25,828 triangles across 518
meshes**, well inside the 150k/700 test budget. meshes**, well inside the 150k/700 test budget.
The same geometry serves the day and late-night looks. There is no second baked The same geometry serves the day and late-night looks. There is no second baked
@@ -65,9 +81,12 @@ just as with the Hollywood day/night rows.
- The 47 m OSM footprint includes rear parcels and does not match the 27 m - The 47 m OSM footprint includes rear parcels and does not match the 27 m
street frontage; the game keeps the frontage proportions rather than the full street frontage; the game keeps the frontage proportions rather than the full
lot. lot.
- Neighbouring businesses are represented by generic low-rise blocks. Their - Neighbouring businesses are represented by generic low-rise blocks (plus the
exact names and current tenants were not verified, so the docs do not claim stepped-back `WestHotelTower` mass behind the west block, standing in for the
them. Ramada Plaza). Their exact names and current tenants were not verified, so the
docs do not claim them.
- The real club's west street corner is rounded (radius ~3–4 m); the game keeps
a hard 90° corner as a stylized-reconstruction simplification.
- The hillside is a background ramp with simplified houses, not a terrain - The hillside is a background ramp with simplified houses, not a terrain
heightfield; it exists to restore the real silhouette above the roofline. heightfield; it exists to restore the real silhouette above the roofline.
- Signage uses the fictional **The Joke Shop** name, not the real Comedy Store - Signage uses the fictional **The Joke Shop** name, not the real Comedy Store
@@ -79,13 +98,21 @@ just as with the Hollywood day/night rows.
## References ## References
The old committed Comedy Store photo board was removed on 2026-11-03 in favour of a local-only
research set under `tmp/research/comedy-store/` (owner override: development reference, never
committed, no licence gate). The three-up board (real photo | generated concept | current capture)
is in [`screens/boards/README.md`](screens/boards/README.md); its photo panel is a historical
public-domain frame, and the current block reference now lives in the gitignored research folder.
- OpenStreetMap way 428854155: <https://www.openstreetmap.org/way/428854155> - OpenStreetMap way 428854155: <https://www.openstreetmap.org/way/428854155>
- Wikimedia Commons photographs used for proportion and material study:
- <https://commons.wikimedia.org/wiki/File:ComedyStore_01.jpg>
- <https://commons.wikimedia.org/wiki/File:ComedyStore_02.jpg>
- <https://commons.wikimedia.org/wiki/File:The_Comedy_Store.jpg>
- <https://commons.wikimedia.org/wiki/File:The_Comedy_Store_West_Hollywood_(51017780551).jpg>
- AI art-direction frames: [`screens/concepts/joke_shop/`](screens/concepts/joke_shop/README.md) - AI art-direction frames: [`screens/concepts/joke_shop/`](screens/concepts/joke_shop/README.md)
- Local frames that changed a decision (gitignored, never committed):
- `tmp/research/comedy-store/` facade/street/strip/visitor frames → the four
`comedy_store_*` photo-anchored concept pairs and the map-recreation plan.
- `tmp/research/comedy-store-hillside/` (public-domain hillside frame) → the photo anchor for
`joke_shop_entrance_day-v2.png` (a less-branded frame that clears the image-recitation filter).
- The hall wall uses the `dark_stucco` pick (1024 px, matte charcoal grain) instead of the grey
paver tile, so the black stucco reads as the real club's flat plaster rather than masonry.
- Verification: `godot --headless --path . --script res://src/test/test_runner.gd` - Verification: `godot --headless --path . --script res://src/test/test_runner.gd`
(`test_joke_shop_uses_the_real_sunset_strip_layout`, (`test_joke_shop_uses_the_real_sunset_strip_layout`,
`test_joke_shop_geometry_stays_inside_the_map_budget`), and `test_joke_shop_geometry_stays_inside_the_map_budget`), and
+27
View File
@@ -199,6 +199,33 @@ not production topology.
MakeHuman is therefore **feasible only as a separate local body-shape pipeline**. MakeHuman is therefore **feasible only as a separate local body-shape pipeline**.
The boundary for that future work is: The boundary for that future work is:
Intake prototype (2026-11-04): `tmp/npc-research/makehuman_intake.py` scales the
CC0 base to 1.82 m, grounds it, triangulates and decimates to **3,790 verts /
6,444 tris**, then exports `tmp/npc-research/makehuman/makehuman_body.glb` (body
only, one neutral material, UVs present, no rig). The body is the input for the
contract-rig/retopology step; the script and mesh stay under `tmp/` and are never
committed.
Retarget prototype (2026-11-04): `tmp/npc-research/makehuman_retarget.py` rotates
the A-pose arms down (−38°/+38°) and scales them **1.63×** to the contract 0.70 m
arm, welds the split vertices, smooth-shades, adds the 13-bone contract armature
with the project's distance-to-bone `_auto_weights`, paints the five slot regions,
renames the mesh to `npc_base`, and exports `makehuman_retargeted.glb` — **6,444 /
8,000 tris, 7,726 / 8,000 verts**, 14 bones, skinned, arm-down, grounded, five
slots, no contract issues. The proportion warp (1.63× arms) is the same class of
issue that blocked Quaternius; here it is accepted, but the vision review shows
it distorts the deltoid/shoulder, the decimated hands are blocky, and the slot
boundaries are rough — refinement work (arm-scale falloff, project head/hands,
weight tuning) is the next step.
The arm-scale falloff (1.0 at the shoulder tapering to 1.63 at the fingertip) was
added, then the arm threshold was raised to x > 0.22 and a rotation falloff was
added — the deltoid/shoulder junction is now smooth (no spiky triangles or
arm/torso gaps). Remaining visual defects: the decimated MakeHuman head reads
dark/featureless, the hands are flat claw-like, and the feet are detached/spiked
— these are fixed by swapping in the project's `_face`/`_hands_and_shoes`/shoe
parts, the next step.
- MPFB/MakeHuman is installed and run by a contributor, never by CI or the game - MPFB/MakeHuman is installed and run by a contributor, never by CI or the game
build. build.
- Generated bodies and intermediate exports stay in `tmp/` (gitignored); the - Generated bodies and intermediate exports stay in `tmp/` (gitignored); the
+9 -1
View File
@@ -13,6 +13,14 @@ the conversation-distance hand pass
[`sheet_npc_hands_compare.jpg`](blender_previews/sheet_npc_hands_compare.jpg), and the [`sheet_npc_hands_compare.jpg`](blender_previews/sheet_npc_hands_compare.jpg), and the
forward-grip pass [`sheet_npc_hands_grip_compare.jpg`](blender_previews/sheet_npc_hands_grip_compare.jpg). forward-grip pass [`sheet_npc_hands_grip_compare.jpg`](blender_previews/sheet_npc_hands_grip_compare.jpg).
The 2026-11-03 skill-guided re-evaluation, its measurements (texel density, budgets, imported
bounds) and the open scorecard live in [`3d-model-review.md`](3d-model-review.md). It does not
change the accepted limits below.
A single-variant face prototype (`npc_casual`) landed 2026-11-03/04: `seg=24/rings=16` head,
subtle brow ridge, fuller lower lip and both eyelids. It reads cleaner than the 0.9.4 face and is
a candidate for the remaining seven once the owner approves (see the review doc).
## What was captured ## What was captured
`src/test/capture_npc_baseline.gd` stages all eight library characters in a `src/test/capture_npc_baseline.gd` stages all eight library characters in a
@@ -74,7 +82,7 @@ pass every applicable item before a library rebuild is accepted.
the head volume has a readable jaw/cheek/chin transition; no face-plane seams, the head volume has a readable jaw/cheek/chin transition; no face-plane seams,
inverted normals or z-fighting. The face direction must remain unambiguous. inverted normals or z-fighting. The face direction must remain unambiguous.
4. **Hair and headgear:** hair covers the scalp without gaps or scalp-through 4. **Hair and headgear:** hair covers the scalp without gaps or scalp-through
seams; fringes, buns and beards keep their silhouette. Caps, beanies, hoods, seams; fringes, buns and beards keep their silhouette. Caps, hoods,
sunglasses and the firefighter helmet clear the brow, eyes and ears. Headgear sunglasses and the firefighter helmet clear the brow, eyes and ears. Headgear
may sit outside the 1.55–1.81 m face band, but its brim must not cover the may sit outside the 1.55–1.81 m face band, but its brim must not cover the
eyes. eyes.
+1
View File
@@ -2,6 +2,7 @@
Visual references and generated QA evidence for Gig Line. Visual references and generated QA evidence for Gig Line.
- [`refs/README.md`](refs/README.md) — licensed real-location photos, provenance sidecars and the licence/privacy rules
- [`concepts/README.md`](concepts/README.md) — AI-assisted realism concept frames - [`concepts/README.md`](concepts/README.md) — AI-assisted realism concept frames
- [`designs/README.md`](designs/README.md) — screen-design mockups - [`designs/README.md`](designs/README.md) — screen-design mockups
- [`../screenshots/README.md`](../screenshots/README.md) — committed game gallery - [`../screenshots/README.md`](../screenshots/README.md) — committed game gallery
+18
View File
@@ -0,0 +1,18 @@
# Three-up boards: photo | concept | capture
Each strip lines up the three image sources for one venue state so the evidence
chain stays visible: the licensed real photo is the **evidence**, the generated
frame is the **proposal** (geometry anchored on the photo; see the
[concepts board](../concepts/README.md) and each frame's `.refgen.json`), and
the game capture is the **proof** of the current build. Where the concept and
the photo disagree, the photo wins for shape; the capture shows the gap the
facade-realism work has to close.
Composed with `tools/three_up.py compose` (labels baked in; the photo panel's
attribution lives in the caption and the [refs sidecars](../refs/README.md)).
| Board | Caption |
| --- | --- |
| ![three-up board: elcapitan day](elcapitan-day-board.jpg) | El Capitan facade, day. Photo: [CC BY 2.0, woo, 2009](https://commons.wikimedia.org/wiki/File:El_Capitan_Theater_frontal_fachade-The_Masonic_Temple.jpg) via `refs/hollywood`. Concept: photo-anchored generation. Capture: current build with the ashlar limestone field (`limestone_ashlar`, anchored on the same photo). |
| ![three-up board: elcapitan night](elcapitan-night-board.jpg) | El Capitan block, night. Photo: CC BY-SA 3.0 (reviewed; redistribution only, no derived assets) via `refs/hollywood`. Concept: photo-anchored night restage. Capture: current build. |
| ![three-up board: jokeshop day](jokeshop-day-board.jpg) | Joke Shop frontage, day. Photo: local-only research frame (`tmp/research/comedy-store`, gitignored). Concept: photo-anchored (gemini + gpt). Capture: current build with the `dark_stucco` wall tile. |
Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

@@ -0,0 +1,7 @@
{
"board": "elcapitan-day-board.jpg",
"caption": "El Capitan facade, day. Photo: CC BY 2.0 2009 via refs/hollywood. Concept: photo-anchored. Capture: ashlar limestone pass (limestone_ashlar, 768 px tile, ~167 px/m).",
"photo": "docs/screens/refs/hollywood/el-capitan-facade-day-wikimedia-2009-10-27.jpg",
"concept": "docs/screens/concepts/hollywood_boulevard/hollywood_boulevard_entrance_day-v2.png",
"capture": "docs/screenshots/01-venue-overview.png"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

@@ -0,0 +1,7 @@
{
"board": "elcapitan-night-board.jpg",
"caption": "El Capitan block, night: CC BY-SA photo (redistribution only) | photo-anchored concept | current capture (banner self-light + facade washes).",
"photo": "docs/screens/refs/hollywood/hollywood-boulevard-night-context-ccbysa.jpg",
"concept": "docs/screens/concepts/hollywood_boulevard/el_capitan_facade_night.png",
"capture": "docs/screenshots/05-late-night-avenue.png"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

@@ -0,0 +1,7 @@
{
"board": "jokeshop-day-board.jpg",
"caption": "Joke Shop frontage, day. Photo: local-only research frame (tmp/research/comedy-store). Concept: photo-anchored (gemini + gpt). Capture: 6.0 m low hall, dark stucco, white signature band, tied-back curtains, west hotel tower.",
"photo": "tmp/research/comedy-store/01.jpg",
"concept": "docs/screens/concepts/joke_shop/joke_shop_entrance_day-v2.png",
"capture": "docs/screenshots/12-joke-shop.png"
}
+20 -81
View File
@@ -1,6 +1,13 @@
# Scene concepts: the realistic target look # Scene concepts: the realistic target look
These are AI-generated example frames (`python3 tools/scene_concepts.py generate --group scene`, `openai/gpt-5-image-mini`, 1280×720) for the realism pass. They are art direction, not assets. `tools/scene_concepts.py realism` pairs them with the in-game shots from `src/test/capture_realism.gd` (see `SHOTS` in the tool). New generations never overwrite a file here; they are saved as `<name>-vN.png`. These are AI-generated example frames for the realism pass. They are art direction, not assets.
`tools/scene_concepts.py realism` pairs them with the in-game shots from `src/test/capture_realism.gd`
(see `SHOTS` in the tool). New generations never overwrite a file here; they are saved as
`<name>-vN.png`.
Concepts are organised per venue in the two subfolders below. The older top-level single-frame
concepts were removed on 2026-11-03 in favour of the per-venue boards, which carry photo-anchored
generations with a `.refgen.json` provenance sidecar each (source photo, licence, model).
## Real-world Hollywood block ## Real-world Hollywood block
@@ -10,37 +17,10 @@ The map-optimization references for the El Capitan Entertainment Centre block
facts and game mapping are documented in facts and game mapping are documented in
[`../../hollywood-boulevard-map.md`](../../hollywood-boulevard-map.md). [`../../hollywood-boulevard-map.md`](../../hollywood-boulevard-map.md).
## Concept list ## The Joke Shop — Sunset Strip
### Hollywood Entrance
![hollywood entrance morning](hollywood_entrance_morning.png)
warm low sun, long soft shadows, brick with visible mortar and wear, stone plinth, potted topiary, haze that fades the far street to beige
### Hollywood Entrance Golden Hour
![hollywood entrance golden hour](hollywood_entrance_golden_hour.png)
strong back light and rim light on people, marquee bulbs reading even in daylight
### Hollywood Entrance Rain Night
![hollywood entrance rain night](hollywood_entrance_rain_night.png)
dark scene lit by practical lights only (marquee, sodium lamps), wet glossy ground with reflections, fog
### Boulevard Skyline
![boulevard skyline day](boulevard_skyline_day.png)
deep layered skyline with real towers and haze, palms lining the road, red curb paint, believable asphalt
### Boulevard Skyline Dusk
![boulevard skyline dusk](boulevard_skyline_dusk.png)
purple/orange gradient sky, neon signs, lit windows, car light trails
### The Joke Shop — Sunset Strip
The current Joke Shop map is based on The Comedy Store at 8433 Sunset Blvd. The current Joke Shop map is based on The Comedy Store at 8433 Sunset Blvd.
The real-site mapping, simplifications and reference photographs are in The real-site mapping and simplifications are in
[`../../joke-shop-map.md`](../../joke-shop-map.md); the frames are in [`../../joke-shop-map.md`](../../joke-shop-map.md); the frames are in
[`joke_shop/README.md`](joke_shop/README.md). [`joke_shop/README.md`](joke_shop/README.md).
@@ -48,56 +28,15 @@ The real-site mapping, simplifications and reference photographs are in
![Joke Shop entrance at night](joke_shop/joke_shop_entrance_night.png) ![Joke Shop entrance at night](joke_shop/joke_shop_entrance_night.png)
### Legacy Joke Shop Alley (pre-map optimization) ## Cross-cutting targets
![joke shop alley evening](joke_shop_alley_evening.png) For comparison with locally generated realism runs (`docs/screens/realism/`, gitignored):
narrow brick alley, one warm wall lantern as key light, deep shadows, people in dark jackets
![joke shop door closeup](joke_shop_door_closeup.png) - **Exposure.** The concepts keep the ground mid-grey; the game's sidewalk reads lighter, so it
close material detail: brick, mortar, aged wood door, brass overexposes against the reference.
- **Night means dark.** The night/dusk concepts are lit by practical lights only (marquee,
These two frames describe the old alley layout and are retained for comparison; signage, street lamps), with wet pavement reflections.
they are no longer the target for the Joke Shop map. - **Depth.** The concepts show a layered skyline fading into haze; the v2 skyline strips supply
this at the boulevard boundary.
### Studio Stage Door Night - **Geometry and foliage.** The facades have plinths, cornices and deep window reveals, and the
trees and shrubs are organic; the venue-realism passes close these gaps incrementally.
![studio stage door night](studio_stage_door_night.png)
granite facade, a bright bulb canopy as the main light, a glossy black car, stanchions and a barrier
### Sidewalk Material Closeup
![sidewalk material closeup](sidewalk_material_closeup.png)
paver joints, stains, granite curb, aggregate asphalt and a tree grate at grazing light
### Entrance Steps Podium
![entrance steps podium](entrance_steps_podium.png)
granite steps, handrails, glass doors, the check-in podium
### Crowd Barrier Line
![crowd barrier line](crowd_barrier_line.png)
steel barriers, a red carpet, a crowd with depth-of-field haze
### Responder Arrival Wide
![responder arrival wide](responder_arrival_wide.png)
fire engine, turnout gear, red/blue light spill on wet pavement
### NPC Portrait Day
![npc portrait day](npc_portrait_day.png)
close portrait of a pedestrian: skin with visible pores and stubble, fabric weave, shallow depth of field. The bar for an avatar close-up, not for the crowd shots
The `npc_portrait` capture in `capture_realism.gd` is staged, not posed by the crowd: it freezes one NPC on an open patch of sidewalk, parks the rest of the crowd out of frame, turns the subject into the camera and stands the guard on the sunlit side. It is the only shot where a face fills the frame, so it is the one to eyeball after an avatar change (generate a local run under `docs/screens/realism/`).
Cross-cutting targets, for comparison with locally generated realism runs:
- **Exposure.** The concepts keep the ground mid-grey. The game's sidewalk is close to white, so it is overexposed.
- **Night means dark.** The night/dusk concepts are lit by practical lights. The game's "Evening" phase is a bright pink-orange frame.
- **Depth.** The concepts show a layered skyline fading into haze. The new v2 skyline strips supply this; the old box skyline did not.
- **Geometry and foliage.** The facades have plinths, cornices and deep window reveals, and the trees and shrubs are organic. The game uses flat walls and blob trees.
## Additional previews
![npc_portrait_day-v2.png](npc_portrait_day-v2.png)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

@@ -10,6 +10,33 @@ game textures. The geometry mapping and source links are in
![El Capitan Entertainment Centre entrance in daylight](hollywood_boulevard_entrance_day.png) ![El Capitan Entertainment Centre entrance in daylight](hollywood_boulevard_entrance_day.png)
## Entrance — day, photo-anchored
![El Capitan Entertainment Centre entrance in daylight, anchored on the 2009 facade photo](hollywood_boulevard_entrance_day-v2.png)
Generated with `generate --reference`, anchored on the licence-cleared
[`el-capitan-facade-day-wikimedia-2009-10-27.jpg`](../../refs/hollywood/el-capitan-facade-day-wikimedia-2009-10-27.jpg)
board photo (CC BY 2.0); provenance in
[`hollywood_boulevard_entrance_day-v2.refgen.json`](hollywood_boulevard_entrance_day-v2.refgen.json).
The facade geometry (motto band, column rhythm, lattice windows, banner slots,
blade sign) follows the photograph; the street is restaged clean for art
direction.
## Facade — night (photo-anchored)
![El Capitan facade at night, anchored on the facade photo](el_capitan_facade_night.png)
Same facade photo as the day frame, restaged to night with practical lighting
only (marquee, signage, street lamps) and wet pavement. The blade sign, banner
slots and lattice windows follow the photograph.
## Facade — overcast (photo-anchored)
![El Capitan facade under flat overcast light](el_capitan_facade_weathered.png)
Same framing under flat overcast light. The weathering requested came out
mild — treat this as the overcast target, not a decay reference.
## Entrance — night ## Entrance — night
![El Capitan Entertainment Centre entrance at night](hollywood_boulevard_entrance_night.png) ![El Capitan Entertainment Centre entrance at night](hollywood_boulevard_entrance_night.png)
@@ -17,3 +44,32 @@ game textures. The geometry mapping and source links are in
## Across the boulevard ## Across the boulevard
![Ovation Hollywood frontage across the boulevard](hollywood_boulevard_across_street.png) ![Ovation Hollywood frontage across the boulevard](hollywood_boulevard_across_street.png)
## Jimmy Kimmel Live entrance — local-reference anchored, two models
![Jimmy Kimmel Live entrance, day, Gemini](jimmy_kimmel_entrance_day_gemini.png)
![Jimmy Kimmel Live entrance, day, GPT image](jimmy_kimmel_entrance_day_gpt.png)
![Jimmy Kimmel Live entrance, night, Gemini](jimmy_kimmel_entrance_night_gemini.png)
![Jimmy Kimmel Live entrance, night, GPT image](jimmy_kimmel_entrance_night_gpt.png)
Four frames anchored on the same local-only research photo
(`tmp/research/jimmy-kimmel-entrance/07.jpg`, gitignored) with `--reference-unchecked`, two
treatments (day, night) × two models (`google/gemini-2.5-flash-image`, `openai/gpt-5-image-mini`).
Provenance and model are in each frame's `.refgen.json` sidecar. The building is the starting-point
venue: the El Capitan Entertainment Centre carrying the "Jimmy Kimmel Live!" marquee over the
six-column Masonic Temple facade.
## Facade — local-reference anchored, two models
![El Capitan facade anchored on a local research frame, Gemini](el_capitan_facade_gemini_day.png)
![El Capitan facade anchored on a local research frame, GPT image](el_capitan_facade_gpt_day.png)
Both frames are anchored on the same local-only research photo
(`tmp/research/elcapitan/01.jpg`, gitignored) with `--reference-unchecked`, one with
`google/gemini-2.5-flash-image` and one with `openai/gpt-5-image-mini`. Provenance and model are
in each frame's `.refgen.json` sidecar. Local reference only; the photo never enters the repo and
these frames are art direction, not assets.
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

@@ -0,0 +1,12 @@
{
"concept": "el_capitan_facade_gemini_day",
"generated": "el_capitan_facade_gemini_day.png",
"model": "google/gemini-2.5-flash-image",
"reference": {
"file": "tmp/research/elcapitan/01.jpg",
"licence": "unchecked",
"page": "",
"licence_checked": false
},
"suffix": "Use the attached reference photograph as the fixed source of geometry and composition: keep the building's proportions, column rhythm, band heights, signage placement and camera angle exactly as photographed. Only restage lighting, weather, people and surface condition where the prompt asks for it. Do not invent extra storeys, wings or ornaments that the photo does not show."
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

@@ -0,0 +1,12 @@
{
"concept": "el_capitan_facade_gpt_day",
"generated": "el_capitan_facade_gpt_day.png",
"model": "openai/gpt-5-image-mini",
"reference": {
"file": "tmp/research/elcapitan/01.jpg",
"licence": "unchecked",
"page": "",
"licence_checked": false
},
"suffix": "Use the attached reference photograph as the fixed source of geometry and composition: keep the building's proportions, column rhythm, band heights, signage placement and camera angle exactly as photographed. Only restage lighting, weather, people and surface condition where the prompt asks for it. Do not invent extra storeys, wings or ornaments that the photo does not show."
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

@@ -0,0 +1,12 @@
{
"concept": "el_capitan_facade_night",
"generated": "el_capitan_facade_night.png",
"model": "google/gemini-2.5-flash-image",
"reference": {
"file": "docs/screens/refs/hollywood/el-capitan-facade-day-wikimedia-2009-10-27.jpg",
"licence": "CC BY 2.0",
"page": "https://commons.wikimedia.org/wiki/File:El_Capitan_Theater_frontal_fachade-The_Masonic_Temple.jpg",
"licence_checked": true
},
"suffix": "Use the attached reference photograph as the fixed source of geometry and composition: keep the building's proportions, column rhythm, band heights, signage placement and camera angle exactly as photographed. Only restage lighting, weather, people and surface condition where the prompt asks for it. Do not invent extra storeys, wings or ornaments that the photo does not show."
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

@@ -0,0 +1,12 @@
{
"concept": "el_capitan_facade_weathered",
"generated": "el_capitan_facade_weathered.png",
"model": "google/gemini-2.5-flash-image",
"reference": {
"file": "docs/screens/refs/hollywood/el-capitan-facade-day-wikimedia-2009-10-27.jpg",
"licence": "CC BY 2.0",
"page": "https://commons.wikimedia.org/wiki/File:El_Capitan_Theater_frontal_fachade-The_Masonic_Temple.jpg",
"licence_checked": true
},
"suffix": "Use the attached reference photograph as the fixed source of geometry and composition: keep the building's proportions, column rhythm, band heights, signage placement and camera angle exactly as photographed. Only restage lighting, weather, people and surface condition where the prompt asks for it. Do not invent extra storeys, wings or ornaments that the photo does not show."
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

@@ -0,0 +1,12 @@
{
"concept": "hollywood_boulevard_entrance_day",
"generated": "hollywood_boulevard_entrance_day-v2.png",
"model": "google/gemini-2.5-flash-image",
"reference": {
"file": "docs/screens/refs/hollywood/el-capitan-facade-day-wikimedia-2009-10-27.jpg",
"licence": "CC BY 2.0",
"page": "https://commons.wikimedia.org/wiki/File:El_Capitan_Theater_frontal_fachade-The_Masonic_Temple.jpg",
"licence_checked": true
},
"suffix": "Use the attached reference photograph as the fixed source of geometry and composition: keep the building's proportions, column rhythm, band heights, signage placement and camera angle exactly as photographed. Only restage lighting, weather, people and surface condition where the prompt asks for it. Do not invent extra storeys, wings or ornaments that the photo does not show."
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

@@ -0,0 +1,12 @@
{
"concept": "jimmy_kimmel_entrance_day_gemini_day",
"generated": "jimmy_kimmel_entrance_day_gemini.png",
"model": "google/gemini-2.5-flash-image",
"reference": {
"file": "tmp/research/jimmy-kimmel-entrance/07.jpg",
"licence": "unchecked",
"page": "",
"licence_checked": false
},
"suffix": "Use the attached reference photograph as the fixed source of geometry and composition: keep the building's proportions, column rhythm, band heights, signage placement and camera angle exactly as photographed. Only restage lighting, weather, people and surface condition where the prompt asks for it. Do not invent extra storeys, wings or ornaments that the photo does not show."
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

@@ -0,0 +1,12 @@
{
"concept": "jimmy_kimmel_entrance_day_gpt_day",
"generated": "jimmy_kimmel_entrance_day_gpt.png",
"model": "openai/gpt-5-image-mini",
"reference": {
"file": "tmp/research/jimmy-kimmel-entrance/07.jpg",
"licence": "unchecked",
"page": "",
"licence_checked": false
},
"suffix": "Use the attached reference photograph as the fixed source of geometry and composition: keep the building's proportions, column rhythm, band heights, signage placement and camera angle exactly as photographed. Only restage lighting, weather, people and surface condition where the prompt asks for it. Do not invent extra storeys, wings or ornaments that the photo does not show."
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

@@ -0,0 +1,12 @@
{
"concept": "jimmy_kimmel_entrance_night_gemini_night",
"generated": "jimmy_kimmel_entrance_night_gemini.png",
"model": "google/gemini-2.5-flash-image",
"reference": {
"file": "tmp/research/jimmy-kimmel-entrance/07.jpg",
"licence": "unchecked",
"page": "",
"licence_checked": false
},
"suffix": "Use the attached reference photograph as the fixed source of geometry and composition: keep the building's proportions, column rhythm, band heights, signage placement and camera angle exactly as photographed. Only restage lighting, weather, people and surface condition where the prompt asks for it. Do not invent extra storeys, wings or ornaments that the photo does not show."
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

@@ -0,0 +1,12 @@
{
"concept": "jimmy_kimmel_entrance_night_gpt_night",
"generated": "jimmy_kimmel_entrance_night_gpt.png",
"model": "openai/gpt-5-image-mini",
"reference": {
"file": "tmp/research/jimmy-kimmel-entrance/07.jpg",
"licence": "unchecked",
"page": "",
"licence_checked": false
},
"suffix": "Use the attached reference photograph as the fixed source of geometry and composition: keep the building's proportions, column rhythm, band heights, signage placement and camera angle exactly as photographed. Only restage lighting, weather, people and surface condition where the prompt asks for it. Do not invent extra storeys, wings or ornaments that the photo does not show."
}
Loaded 100 of 192 files, more files were not shown because too many files have changed in this diff. Show more