Package a Forward+ preset with volumetric fog, SDFGI and a volumetric flashlight
for a separate Linux/Windows Desktop HQ zip. Gate the effects on a real
RenderingDevice, tune LATE fog, and adapt local light falloff for Godot 4.7.
Record the Compatibility/Forward+ A/B captures and metrics, add the artifact to
the build/publish scripts, and keep the default Compatibility/Web path
unchanged. Headless 231/231, Python 87/87; exported HQ binary boots with Vulkan.
Record the upgraded 4.7.2 binary, the retained 4.3 backup and the matching
export templates. Keep the project/CI baseline at 4.3 and note that 4.7.2
verified import, tests, the session smoke and a Linux export. Hide the
4.7-generated per-script UID sidecars from this clone only.
Add the alley walls, warm lantern, shutters, dumpster, AC clutter and door
step for the Joke Shop. Build the studio stone facade, bulb canopy, glossy
black car, stanchions and barriers. Rebuild only the world container when the
venue changes, so the guard and UI survive; add per-venue navigation checks.
Capture gallery shots 12/13, update the concept mapping and docs. Headless
231/231, Python 87/87, screenshot gate 13 good/0 bad. The vision-judge retry is
tracked separately because the API key is invalid.
Add the Hollywood, Joke Shop and TV Studio tables for facade, window,
stair, street, nav, guard-spawn and feature data. Unknown ids fall back to
the boulevard. Use the specs for the core dimensions and gates, with a headless
test for the distinct venue data. Headless 230/230.
Ship the fitted NPC gear pass with the post-v0.6.0 realism and UI work.
Bump the version source and documentation to 0.6.1 and move the changelog
entry out of Unreleased. Headless 229/229.
Create CHANGELOG.md with the post-0.6.0 gear-fit entries and backfill the
recent release history. Update the implemented-features list, asset-tooling
notes, README links and verification counts (headless 229, Python 87).
Move the completed gear section to DONE.md and record the hooded-portrait
follow-up. An explicit --portrait-type now overrides the hooded-subject skip,
though the day roster has no types 5-7 yet. Headless 229/229.
Fix the portrait staging: face the rig toward the camera (the old yaw was 180
degrees out) and hide the focus disc, which was covering the face in close-ups.
Add the before/after Influencer portrait, fit measurements and judge scores in
docs/screens/realism/2026-11-01-gear. Re-run check_screenshots (11 good/0 bad);
headless 229/229.
The Python fit test now caps the glasses at 0.70x head width and requires a
positive bag clearance on both the coat and dress. The Godot character suite
loads head/back gear on six roles and checks attach parents, head width and
brow bounds, and that back gear reaches beyond the 0.26 m body silhouette.
Rebuilt and re-baked all 18 gear assets; no-op GLB export churn was reverted.
Headless 229/229, Python 87/87.
The face pass added a brow ridge; lift the helmet mesh 2 cm so the brim sits
above the eyes. Cap and hood were rendered on their characters and leave the
brow/ears and face readable. Rebuild and re-bake the helmet; Python 87/87.
Narrow the bag to 0.06 m and move it outboard to centre x=0.292. The body inner
face is now 0.262 m, clearing the coat skirt (0.225) and dress (0.260); the
strap lower points start on the same line. The fit report measures the bag body
separately from the torso strap and uses a signed inner-face clearance. Run
Blender build/bake and Godot import. Python tooling 87/87.
Move the hinges to +/-0.075 (0.035 box), arms to +/-0.098, and lenses to a
0.024 m radius while keeping the lens plane in front of the eyes. Rebuild the
GLB and AO; fit now measures 0.202 m total width (0.64x head). capture_realism
now parses the documented --portrait-type option instead of ignoring it.
Python tooling 87/87; headless 228/228.
`blender_assets.py fit` measures each character head width (skin vertices
weighted to Head in y 1.55-1.81) and clothing radius (cloth skirt in y 0.30-0.52,
pants hip fallback), then prints every attached head/back/chest gear bounding box
with head-band status and x/radial skirt clearance. The report confirms the
glasses width and shoulder-bag coat clip, giving the next fit fixes numbers.
Python tooling 87/87; asset audit clean.
Blender library
- Rebuild the face: sclera, iris and upper lid per eye, brow ridge, cheekbones,
nose bridge and tip, ears with lobes, split upper/lower lips.
- Give each hand four fingers plus a thumb and end every sleeve in a cuff ring.
- Raise CHAR_MAX_VERTS 4000 -> 5000 (16 avatars still cost ~6.9 ms of a 50 ms
frame), decimate the body to 26 %; characters are now 3,974-5,026 tris and
3,744-4,807 verts. Rebuild all 8 variants and re-bake their AO maps.
Capture tooling
- Add a `portrait` stage to capture_realism.gd: freeze one NPC, park the crowd
out of frame, stand the subject on open sidewalk, turn it into the camera and
put the guard on the sunlit side. New --portrait-type=N picks the role.
- Add the npc_portrait_day concept and map the shot to it, so avatar detail is
scored against a portrait instead of a wide street frame.
Flashlight
- Drop the fake additive beam (Materials.light_beam + the cone mesh): on GL
Compatibility a first-person camera inside the cone renders it as a filled
disc with a bright far ring. Keep the tight spot (14 deg, 20 m, energy 4.2)
and its headless test; the visible shaft is now planned behind a Forward+
preset.
Docs and task tracking
- Move the finished realism follow-ups (ground exposure, flashlight, NPC detail,
judge re-check) to DONE.md and expand TODO.md with step-by-step plans for NPC
gear fit, venue geometry plus the committed gallery, and the Forward+ preset.
- Record the decisions, gotchas and portrait recipe in MEMORY.md; update the
Blender contract, the concept README and the capture section of README.md.
- Refresh the gallery captures affected by the avatar rebuild.
Checks: headless 228/228, Python 86/86, blender_assets audit exit 0,
scene_concepts audit all GOOD, screen_designs compare 11 good / 0 bad,
smoke_npc_budget OK, boot clean (only the known headless mesh warning).
- reduce PLAN.md from a 674-line implementation log to a 187-line product/design
plan; keep escalation, venues, NPC/systems, controls, presentation and constraints
- refresh README for implemented venues, Blender/v2 assets, the custom test runner,
Web target, current release state and the screenshot smoke
- update architecture for 0.6.0, the runtime art loader, Gitea CI/build/publish,
Web deployment, six release artifacts and visual regression
- remove stale uncommitted/active-pass claims from MEMORY and point it at the
current NPC follow-ups; move the completed documentation task to DONE
Narrow the spot to 11° with a 20 m range so it lights the person/door rather
than the whole facade, and regenerate the staged screenshots. Headless 227/227,
compare 11 good / 0 bad.
A GradientTexture1D varies along U, so the cone showed a bright ring; build a
1×64 vertical ramp for UV.y instead (faint at the lens, brightest near the
start, gone before the tip). Regenerate the affected captures; headless 227/227,
compare 11 good / 0 bad.
Jump the staged shift to 760 s before the night shots, so 05/06 are true night
scenes with a visible flashlight beam instead of dusk. Regenerate the affected
captures; compare stays 11 good / 0 bad.
Widen and lengthen the additive beam cone and raise its near-end opacity so the
night flashlight reads on screen. Regenerate the staged captures; compare stays
11 good / 0 bad, headless 227/227.
- add the v2 runtime picks: per-phase skyline panoramas, brick, sidewalk
pavers, dry/wet asphalt, awning canvas, and their normal maps
- add the realism tooling and evidence: tools/scene_concepts.py, capture_realism.gd,
concept frames, reports/sheets, and tests
- retune phase lighting/fog/exposure, add sun yaw, brighten the night glow,
add the flashlight beam mesh, and rebuild the planter/tree assets
- regenerate all eleven staged screenshots from the current build; compare is
11 good / 0 bad
- finish the visual-alignment closeout in DONE/TODO, update architecture,
blender-assets, PLAN, and ignore rules (editable Blender sources untracked)
- keep the judge retry and document the verified default judge model
Verification: headless 227/227; Python tooling 86/86; check_screenshots 11/11.
The REC/clock block sat on top of the top-right shift/rep/crowd lines. Start it
at y=92 and slightly farther from the edge, keeping the overlay visible without
covering the status. Headless 226/226 and a windowed HUD screenshot checked.
Mark the default vision judge as verified (7 match / 4 review / 0 diff), note the
active realism pass blocking the remaining lighting task, and replace the stale
memory note that said screen_designs still read the docs tree.
- ignore assets/models/blender_src/*.blend (keep the .gdignore marker tracked) and
remove the 46 editable .blend files from the index; they remain on disk and are
regenerated by tools/blender_assets.py
- move the completed storage/docs/code-path/art-loader/verification, mouse-fix,
and pop-up sections to DONE.md; TODO now holds only the open lighting item,
realism follow-ups, and optional ideas
- docs changes only; runtime code unchanged
Add the access_inspection art layer to the HUD, keep the panel transparent and
padded, center the title/status/issue text and artifact cards, and hide the art
with the panel. Also record the pop-up visual pass as done. Headless 226/226
verified in a clean HEAD worktree.
_start_shift() now calls _refresh_freeze(), clearing the start-menu input lock
and returning to captured mouse mode. The movement smoke asserts both and no
longer captures the mouse itself. Headless 226/226 and smoke_movement pass in a
clean worktree; only this game_manager hunk is staged, not the active realism
edits.
Both capture helpers now accept --out=res://docs/screenshots, and
tools/check_screenshots.sh renders the staged set (using xvfb-run when headless)
before running screen_designs.py compare. Record the judge result: 7 match,
4 review, 0 diff. Headless 226/226 and the smoke both pass in a clean worktree.
Widen the doughnut, use dark charcoal wedges with a dimmed scene behind them,
add divider spokes and inner/outer rings, raise the center-name size, and use a
restrained light highlight for the selected slice instead of the old yellow
fill. Headless 226/226 verified in a clean HEAD worktree.
Move the target name out of the top-left stack into a boxed chip under the
crosshair, keep the log/hints left and shift status right, and add a five-segment
escalation bar under the existing color-coded label. Empty targets hide the
chip. Headless 226/226 verified in a clean HEAD worktree.
Draw body_camera_timeline behind a full-height narrow panel, constrain the
content to that column, wrap long event text, and scroll the event list so the
Previous/Next/Close row stays pinned at the bottom. Headless 226/226 verified in
a clean HEAD worktree.
Draw radio_report/emergency_radio behind a transparent, padded form and switch
the backdrop with the call type. The wand HUD popup now shows wand_screening
behind its text while open. Both covers use the mockup panel bounds so baked-in
controls stay hidden. Headless 226/226 verified in a clean HEAD worktree.
Update the resize/audit examples and the screen-design section to
assets/images/ui|scenes, with docs/screens/designs as the reference snapshot.
The separate realism-pass README hunk stays unstaged.
Wrap the review content in a Control root, draw the shift_review art behind an
opaque panel, and style the action buttons to match the mockup. Headless
226/226 verified in a clean HEAD worktree.
Add UiArt.add_screen_backdrop() to place the reference art behind an opaque
panel, then wire the pause overlay and settings screen to it. Pause rows get
larger, rounded styles; settings widens to fit its expanded controls. Headless
226/226 verified in a clean HEAD worktree (the realism WIP currently editing
materials.gd remains unstaged).
- screen_designs.py now reads/writes assets/images/ui/ (ADR-0014); docs/
screens/designs/ stays the reference-only snapshot, documented as historical
- add src/game/ui/art.gd: cached loader for assets/images/ui|scenes with null
fallbacks for missing files, plus headless tests
- start menu uses the start_menu scene art as a full-screen backdrop, covers the
baked-in mockup panel with an opaque panel, and styles the venue rows to match
- update README/architecture/TODO path notes and mark the storage/code-path/loader
items done; DONE records the historical path move
- compare still 11 good / 0 bad; headless 226/226
README/PLAN realism-pass edits from another workstream remain unstaged." && git log --oneline -1
Run the headless Godot import after copying the 21 design references into
assets/images/ui/; all sidecars are generated and TODO records the item done.
Add the path table from ADR-0014 to the architecture documentation (runtime UI/scene
art, tiled textures, models, reference art, QA captures, raw sources) and close the
second storage-restructure TODO item.
- AGENTS.md now requires agents to mark a task [-] while claimed/in progress and
only use [x] after implementation and verification, with an example
- copied the 21 reference mockups from docs/screens/designs/ into the runtime
root assets/images/ui/ (byte-identical names); docs/screens/designs/ stays as
the reference-only copy per ADR-0014
- MEMORY records where the copies live and that screen_designs.py still reads
the docs tree until the code-path migration
First storage-restructure TODO item completed.
assets/images/ is now the runtime root for composed interface/scene art:
ui/ for screen and panel art, scenes/ for full-frame scene art. Tiled PBR
textures remain under assets/textures/; docs/screens/designs and concepts stay
reference-only; QA captures stay under docs/screenshots. Mockups that become
runtime art are copied/processed with a new name (no overwrites) and always
have a code fallback.
Records the convention in MEMORY, adds ADR-0014 to the architecture index, and
closes the first storage-restructure TODO item.
- TODO now tracks only the visual-alignment pass and optional future ideas; the
completed Blender/graphics plan moved out
- DONE records the six published v0.6.0 artifacts and final verification counts
- header updated to v0.6.0 / 222 headless / 69 Python tests
Phase 4 of the v0.6.0 graphics plan:
- tools/bake_ao.py bakes 256² AO maps for every Blender character/gear/prop
(Cycles, existing UVs) next to each GLB; Materials.apply_ao() wires the red
channel into character slots, gear, and props. Compatibility has no SSAO.
- Regenerated brick/concrete/asphalt at 1024² with OpenRouter, derived tangent
normal maps via tools/make_normal_maps.py, and wired them through
SurfaceMaterials.textured() without changing UV scales.
- Evaluated Forward+: boots on desktop Vulkan, but the renderer is project-wide
and Web must stay GL Compatibility; v0.6.0 keeps Compatibility (decision in
MEMORY/plan). A desktop-only override is deferred.
- Recaptured screenshots; compare 11 good / 0 bad. Fixed marquee text alignment.
- Tests: baked AO maps exist for all 46 assets; prop/character AO material
checks; headless 222/222, Python 69/69, all smokes pass.
- Version 0.6.0; ADR-0013 accepted; README/architecture/blender-assets/plan and
TODO/DONE updated.
NpcAvatar
- select one of 8 library character variants by role/seed (with npc_base and the
procedural rig as fallbacks), keep Rig/Head and the existing bone animation
- tint only skin/cloth/pants/accessory/hair; fixed detail materials keep their
colour, npc_vest keeps its hi-vis vest, firefighter/guard use dark uniform tints
- attach caps, hoods, helmets, backpacks, SCBA tanks, lanyards and hand items at
the documented head/back/chest/hand points (primitive fallbacks retained)
WorldBuilder
- prefer assets/models/blender/props/ for the six replacements and the new
street dressing (street lamp/tree, palms, planters, A-frame, cone, barrier,
stanchion, podium, handrail, wall lantern, double door, marquee, sedan)
- fit the same colliders/navigation obstacles and keep the placement validator;
collect library emissives (bulbs, marquee face, wall lanterns, door LED, sedan
lights) for set_night_mode()
- add a library triangle counter + 60k budget check (current ~27,986); toggle
prop gallery to the library models; fix the marquee label placement
Tests/smoke
- character selection/gear attach/fixed-material tint tests; library prop load,
emissive and triangle-budget tests; smoke_props routes a guest around a
stanchion in open sidewalk (the old bench route is now crowded by trees)
- headless 222/222, Python 68/68, all smokes pass, compare 11 good / 0 bad
Docs: TODO Phase 3.5 moved to DONE, README/architecture/blender-assets/plan
describe the integrated runtime, MEMORY records the integration rules.