One pawn, both rigs (ADR-9): a skeletal body hidden in first person, a collision-tested spring arm, and a toggle that swaps the active camera and the body's visibility. Shipped default stays first person; -thirdperson starts the pawn in the third-person rig so the review shot is reproducible, and the screenshot run passes it. Three defects found and two fixed: - The skin material had no SkeletalMesh usage flag, so Unreal silently substituted the default grey. That is why the body rendered as clay. - render_screenshots.sh still called ./Engine/... on this branch (the fix lives on the facade branch and never reached main); applied here so the shots generate. - OPEN: the idle clip is bound and PlayAnimation is called - the run logs the clip name - but the body still renders in bind pose, arms out. Recorded with that evidence in TODO.md rather than called done. Shot 5 (demo-third-person) added and documented; camera collision is implemented but unproven, since the spawn has open space behind it.
Screenshots — demo-map visual review
Rendered captures of the demo map only — what a player sees when the demo runs. Generated by Tools/render_screenshots.sh; the PNGs are committed so a reviewer sees exactly what the build rendered.
The review staging map (/Game/Test/ReviewMap) is not part of this set: it exists to hold the camera list and the hero detail rig, and it is not what ships.
How to regenerate
Tools/render_screenshots.sh --verify
Stages the demo shot cameras, runs the game on /Game/Hollywood/DemoMap, copies the PNGs into Screenshots/demo/ and then runs Tools/visual_loop.py --verify to check that each shot still shows the content its expectation describes. About a minute.
The shot list
Each shot has an expectation in Tools/visual_targets.json — the content the capture must show — and a verification state produced by --verify: it fails if the frame is blank, the wrong size, or has no tonal range.
| # | File | View | Expected content | Verified | Approved |
|---|---|---|---|---|---|
| 1 | demo/review-demo-spawn-view.png |
north sidewalk | The whole south block: the neoclassical hero façade between its neighbours, both sidewalks and the road in the foreground | ☑ 2026-11-09 | ☑ 2026-11-09 |
| 2 | demo/review-demo-street-level.png |
eye height, north side | Street level: the hero colonnade with the adjacent frontage buildings either side, shopfronts at pavement level | ☑ 2026-11-09 | ☑ 2026-11-09 |
| 3 | demo/review-demo-crossing.png |
along the crosswalk | The designated mid-block crossing (s=130 m, UE X −14956): zebra bars on the asphalt, south frontage and colonnade behind | ☑ 2026-11-09 | ☑ 2026-11-09 |
| 4 | demo/review-demo-north-buildings.png |
across the Boulevard | The two north-side buildings (TCL Chinese Theatre, Madame Tussaud's) from the south side, full height in frame | ☑ 2026-11-09 | ☑ 2026-11-09 |
| 5 | demo/review-demo-third-person.png |
third-person boom, 6 m behind the pawn | The player's own visible body on the north sidewalk, seen from behind, with the hero façade across the street. Captured with -thirdperson, which starts the pawn in the third-person rig |
☑ 2026-11-09 | ☐ pending |
Approval is per shot, in the table above (owner review of the 0.1.4 set, recorded in Docs/reviews/0.1.4-review.md). Add a row when a shot is added; remove the file in the same change when a shot is retired.
The iteration loop (uncommitted)
Tools/visual_loop.py measures each capture against its reference photograph and turns the deltas into modelling actions for the Blender skill packs:
python3 Tools/visual_loop.py --compare --iteration 3 # writes Art/reference/iterations/3/
That directory is gitignored: iterations stay uncommitted until a shot is confirmed, and only confirmed shots are promoted into Screenshots/demo/. The feedback file names the affected skill (blender-modeler, archviz, materials, lookdev, camera-cinematography) so the next modelling pass has a starting point rather than an opinion.
Note the comparison is only meaningful when the shot and the reference frame the same subject — a wide block view measured against a tight façade crop will always report low edge similarity.
Scene conventions
- Demo map (
/Game/Hollywood/DemoMap): fixed daytime — sun pitch −62 / yaw 120 (intensity 4, warm), sky light 2.6, sky atmosphere, height fog, fixed exposure. - Cameras: elevation shots sit at their target height (pitch 0, so verticals stay parallel) and use a 42–55° lens to fill the frame from across the street.
- Materials: every surface carries a look-developed material from
Tools/ue_build_demo_map.py— noise-blended base colour, masonry coursing, and a generated texture set (Tools/generate_facade_textures.py) sampled world-aligned. Explicit roughness and specular per surface type.
Known cosmetic issues
- Hero façade renders pale: the stone material is a graph and a texture set, not a scanned surface (the
0.1.4façade pass is in progress). - Banners sit on the column line rather than flush to the wall (they hang on the columns in the photographs, so this is acceptable).
- Between kerb and building line the walkable surface is the terrain mesh, not a modelled pavement.
- The El Capitan Theatre has no marquee or blade sign yet — the feature that makes it read as itself.
0.2.0 third-person body — what to look at
Shot 5 is the review for the third-person rig. It is not a finished body: the figure is in bind pose, arms out.
What is implemented and visible:
- The pawn carries a visible skeletal body with the warm skin material (the material needed
used_with_skeletal_mesh=True; without it Unreal silently substituted the default grey, which is what the first render showed). - A spring-arm camera with collision testing, and a V toggle between first and third person. The shipped default stays first person; the review passes
-thirdpersonso the shot is reproducible.
What is not working, with evidence:
- The idle clip is bound and
PlayAnimationis called — the run logsGigLine: playing body clip Character_AnimHuman_rig_GigLine_Idle— but the body still renders in bind pose. The clip therefore is not deforming the mesh; that is the open defect, tracked inTODO.mdunder "Verify animation plays correctly on the imported rig". - The arms-down offsets are baked into the clips as a base on top of the A-pose bind (
BASEinTools/character_anim_build.py), so a correct playback should show arms down. Seeing them out is the same defect, not a missing offset.