Extend the v0.6.0 plan with the Blender asset library
Document the larger asset set produced by the running Blender generator (tools/blender_assets.py): 8 NPC character variants, 18 gear pieces, and 22 street/venue props with a manifest, editable sources, and preview sheets. - TODO gains Phase 3.5 with the audit/budget reconciliation (npc_casual is currently 7,756 tris / 5,616 verts, above the 6,000/4,000 contract), character selection by role, gear attach points, prop replacement/placement, emissive wiring, budgets, and screenshot gates - PLAN's Visual Quality Direction describes the library, runtime selection, and offline fallbacks - docs/plan-graphics-v0.6.md adds the library contract/output table and integration steps, and points Phase 4 at the Blender props - MEMORY records the manifest-as-source-of-truth rule and the generator caveat Generated library files stay untracked until the running build finishes and passes the audit; the generator itself is committed so the plan is reproducible.
This commit is contained in:
1 parent
a231f7588a
commit
7efb5024ec
5 files changed
+1766
-20
No files matched your search
+87
-13
@@ -164,20 +164,89 @@ Outputs land under `assets/textures/ai/game_ready/` (or a new
|
||||
6. Re-measure `smoke_npc_budget.gd`; adjust `LOD_TIERS` if the skinned rig is
|
||||
heavier up close. The impostor path is unchanged.
|
||||
|
||||
### Phase 3.5 — Blender asset library (characters, gear, props)
|
||||
|
||||
The library generator is `tools/blender_assets.py` (flatpak Blender, headless).
|
||||
It stages outputs for integration; nothing is wired into the game until the
|
||||
audit and manifest are clean. While the generator is running, do not edit it.
|
||||
|
||||
**Outputs and contract**
|
||||
|
||||
| Kind | Path | Notes |
|
||||
| --- | --- | --- |
|
||||
| Characters | `assets/models/blender/npc/<name>.glb` | 8 variants: `npc_casual`, `npc_jacket`, `npc_coat`, `npc_vest`, `npc_dress`, `npc_hoodie`, `npc_firefighter`, `npc_guard` |
|
||||
| Gear | `assets/models/blender/npc_gear/<name>.glb` | 18 pieces; authored in attach-point space (`head`, `hand`, `back`, `chest`) |
|
||||
| Props | `assets/models/blender/props/<name>.glb` | 22 pieces; the first nine replace current generated/primitive street furniture, the rest are new venue dressing |
|
||||
| Manifest | `assets/models/blender/manifest.json` | path, category, triangles, vertices, bounds, materials, roles, tint slots, attach points |
|
||||
| Sources | `assets/models/blender_src/<name>.blend` | committed, editable source |
|
||||
| Previews | `docs/blender_previews/*.png` + `sheet_<category>.png` | `render` / `sheet` for visual review |
|
||||
|
||||
All characters reuse the `npc_base` contract: mesh node `npc_base`, bones
|
||||
`Head/HipL/R/KneeL/R/ShoulderL/R/ElbowL/R/HandL/R` (+ Hips/Spine/Neck),
|
||||
material slots `skin/cloth/pants/accessory/hair`, front toward Blender `-Y`
|
||||
(Godot `+Z`), feet at `y ~= 0`. Gear origins are the attach points (head at
|
||||
`Rig/Head`, hand at the hand proxy, back at the spine, chest at the sternum).
|
||||
Props are grounded except `wall_lantern` and `marquee`; both may be emissive.
|
||||
|
||||
**Integration steps**
|
||||
|
||||
1. **Audit the finished build.** `python3 tools/blender_assets.py audit` and
|
||||
`sheet`; fix assets or reconcile the budgets. The first `npc_casual` result
|
||||
is 7,756 tris / 5,616 verts, above the current 6,000 / 4,000 character
|
||||
contract — either simplify the mesh or explicitly raise and document the
|
||||
character budget before wiring variants in.
|
||||
2. **Commit the library and sources.** Add `assets/models/blender/**`,
|
||||
`assets/models/blender_src/**`, the generator, manifest, previews, and
|
||||
`docs/blender-assets.md`; generated folders that CI can rebuild offline may
|
||||
stay ignored. `blender_assets.py audit` must work without Blender.
|
||||
3. **Select characters by role.** Extend `NpcAvatar` to pick a variant from the
|
||||
manifest using the profile's role and `outfit_for`/`layer_for` (casual,
|
||||
jacket, coat, vest, dress, hoodie, firefighter, guard). Fall back to
|
||||
`npc_base.glb`, then to the procedural rig, and record the chosen path.
|
||||
4. **Tint and anchor.** Apply `outfit_for` to every variant's five slots via
|
||||
`SurfaceMaterials.npc_slot()`; keep `Rig/Head` for the focus circle, name tag,
|
||||
reaction tag, and accessories. Keep the walk/idle/escalation bone-driving
|
||||
wrapper.
|
||||
5. **Replace procedural gear.** Use the `npc_gear` catalogue for caps, hoods,
|
||||
helmets, backpacks, lanyards, hand items (phone, cup, clipboard, umbrella,
|
||||
camera, sign, flashlight, wand, radio) and the SCBA tank; attach at the
|
||||
documented points and fall back to the current primitives when an asset is
|
||||
missing.
|
||||
6. **Replace and extend props.** Load the replacement set through
|
||||
`WorldBuilder` (`bollard`, `bench`, `trash_bin`, `planter_box`,
|
||||
`newspaper_box`, `fire_hydrant`, `street_lamp`, `street_tree`,
|
||||
`traffic_cone`), then place the new dressing (`palm_tree`, `round_planter`,
|
||||
`a_frame_sign`, `wall_lantern`, `crowd_barrier`, `stanchion`, `handrail`,
|
||||
`security_podium`, `double_door`, `marquee`, `sedan`) using the existing
|
||||
placement table/collider/avoidance contract. No prop may enter the
|
||||
door/steps/guest lane.
|
||||
7. **Wire emissives to the phase.** Street-lamp bulbs, wall lanterns, the door
|
||||
lock LED, marquee bulbs/sign face, and sedan headlights should follow the
|
||||
existing day/night lighting rather than staying always on.
|
||||
8. **Measure and gate.** Re-run `smoke_npc_budget.gd` with the new characters
|
||||
before raising `MAX_LIVE_NPCS`; add a prop triangle/draw budget check. Then
|
||||
recapture `docs/screenshots/` and run `screen_designs.py compare` + `judge`
|
||||
plus a close-up target shot for character readability.
|
||||
9. **Fallbacks stay offline.** A fresh checkout with no Blender and no network
|
||||
must boot on the committed library (or `npc_base.glb`/procedural rig when an
|
||||
asset is absent); CI still runs the Godot import and headless suite.
|
||||
|
||||
|
||||
### Phase 4 — Environment and lighting lift (after NPCs land)
|
||||
|
||||
1. **Baked AO on props:** export the existing prop set through Blender (or bake
|
||||
AO in `npc_pipeline`-style tooling) so contact shadows read without SSAO.
|
||||
This replaces the pure box/cylinder builder with Blender-authored props
|
||||
behind the same `assets/models/generated/<prop>.glb` contract (ADR-0012's
|
||||
follow-up).
|
||||
1. **Baked AO on props:** use the Phase 3.5 Blender prop replacements
|
||||
(`street_lamp`, `street_tree`, `bench`, …) and bake AO into their
|
||||
albedo/ORM maps so contact shadows read without SSAO. Keep the same
|
||||
`WorldBuilder` load/fallback contract (ADR-0012's follow-up).
|
||||
2. **Higher-resolution environment textures:** regenerate brick/concrete/asphalt
|
||||
through `asset_pipeline.py` with normal maps, keeping the current UV scales.
|
||||
through `asset_pipeline.py` with normal maps, keeping the current UV scales;
|
||||
use the same sRGB/albedo + packed ORM discipline as the library assets.
|
||||
3. **Evaluate a desktop-only Forward+ preset** (SSAO/SSIL/volumetrics) while the
|
||||
Web export preset keeps `thread_support=false` and GL Compatibility. Decide
|
||||
explicitly in an ADR addendum; do not silently change the renderer.
|
||||
4. Regenerate `docs/screenshots/` with `capture_screenshots.gd`, then run
|
||||
`screen_designs.py compare` and `judge` as the regression gate.
|
||||
`screen_designs.py compare` and `judge` as the regression gate, plus
|
||||
`blender_assets.py sheet` for the character/gear/prop library.
|
||||
|
||||
### Phase 5 — Verification and release
|
||||
|
||||
@@ -204,15 +273,20 @@ Outputs land under `assets/textures/ai/game_ready/` (or a new
|
||||
|
||||
## Acceptance criteria (definition of done)
|
||||
|
||||
1. NPCs are Blender-authored skinned meshes with baked maps; they read as people
|
||||
at conversation distance and survive a cinematic close-up.
|
||||
1. NPCs and street furniture are Blender-authored meshes with baked maps; the
|
||||
character variants, gear, and props read as people/objects at conversation
|
||||
distance and survive a cinematic close-up.
|
||||
2. `Rig/Head`, the focus cone, nametag, theater poses, crowd reactions, and LOD
|
||||
all still work; all existing NPC tests pass unchanged or are updated with
|
||||
clear reasons.
|
||||
3. The game boots and plays from a fresh checkout with **no** Blender and no
|
||||
network (committed assets + procedural fallback).
|
||||
4. `npc_pipeline.py build` is deterministic and `audit` enforces the contract.
|
||||
5. 208 headless + 56 Python tests stay green (Python audit tests skip when
|
||||
Blender is absent); NPC-budget and movement smokes pass; screenshot
|
||||
`compare`/`judge` show no regressions.
|
||||
6. Version bumped to v0.6.0, docs and ADR-0013 updated, release published.
|
||||
5. 212 headless + 60 Python tests stay green (Blender-dependent Python tests
|
||||
skip with a reason when Blender is absent); `npc_pipeline.py audit` and
|
||||
`blender_assets.py audit` pass; NPC-budget and movement smokes pass;
|
||||
screenshot `compare`/`judge` and the library contact sheets show no
|
||||
regressions.
|
||||
6. The library is committed with its generator/manifest/previews, runtime
|
||||
selection and fallbacks are covered by tests, version bumped to v0.6.0,
|
||||
docs and ADR-0013 updated, release published.
|
||||
Reference in new issue
Block a user