From 04d211b90bea1c4dc6a890ef06372e8f5bc5d026 Mon Sep 17 00:00:00 2001 From: Zwitschi Date: Fri, 6 Nov 2026 13:59:23 +0100 Subject: [PATCH] Release 0.9.9: full Quaternius roster, docs, changelog, version, slimmer export filters and checksums --- CHANGELOG.md | 26 ++++++++++++++++++++++-- README.md | 13 +++++++----- docs/blender-assets.md | 24 ++++++++++++++++++---- docs/development-status.md | 13 +++++++----- docs/npc-model-sourcing.md | 41 ++++++++++++++++++++++++++++++++++++++ export_presets.cfg | 8 ++++---- project.godot | 2 +- tools/build_releases.sh | 4 ++++ 8 files changed, 110 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d763e2..a8d0e5e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,11 +6,33 @@ Semantic Versioning. ## [Unreleased] +## [0.9.9] — 2026-11-06 + ### Changed - Raised the character mesh budget from 16,000 to 24,000 triangles and glTF - vertices so the Quaternius NPC base, the five-slot clothing variants and the - retargeted animation can fit without heavy decimation. Gear and prop budgets are unchanged. + vertices so the Quaternius base and the role-dressed variants fit without + heavy decimation. Gear and prop budgets are unchanged. +- Replaced the whole NPC roster with the CC0 Quaternius characters. All twelve + characters (tourist, jacket, coat, vest, dress, hoodie, firefighter, guard and + the four crowd variants) now use one of three source outfits — casual tee, + hoodie or work clothes — dressed by role with the five tint slots and the gear + library. The procedural library and the MakeHuman head remain in the build as + the fallback. +- Characters stand with their arms down instead of a T/A pose, and the seated, + idle and walking poses swing from the shoulder and hip the way the animation + code intends on the new skeleton. +- Head gear (cap, hood, sunglasses, firefighter helmet) and the camera were + resized for the new head and arm. The camera now hangs from a wrist strap + instead of a neck strap that floated next to the head. +- The backpack straps were pulled in so they sit on the chest instead of + hovering in front of it. + +### Fixed + +- Characters no longer render with black legs or black patches: the new base + carried a collapsed UV map that made the ambient-occlusion bake come out + black, and the roster is now unwrapped and baked correctly. ## [0.9.8] — 2026-11-04 diff --git a/README.md b/README.md index fb66e61..a7dd5d6 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,9 @@ Versions are assigned only when a track's scope is accepted into a release. Ever > Downloads are public (no sign-in required) since the host's instance-wide > `REQUIRE_SIGNIN_VIEW` was disabled on 2026-10-31. > -> **Latest published: v0.9.8** — the character-development patch: the +> **Latest published: v0.9.9** — the character-roster patch: all twelve NPCs now +> use the CC0 Quaternius base with the five tint slots, role gear and baked maps. +> Superseded: v0.9.8, the character-development patch: the > 12-character library, realistic face pass, four crowd-variety variants and the > wrist/hip/knee deformation fixes. Previous 0.9.x patches added the > Hollywood/Joke Shop maps, UI/accessibility polish, NPC visual optimization, @@ -96,13 +98,14 @@ Every capture is rendered from the current build by [`tools/check_screenshots.sh ### 3D asset progress -The current character library is Blender-authored and audited before use. The active character -migration moves the NPC base to the CC0 Quaternius modular character; the sheets below show the +The character roster is built from the CC0 Quaternius bases (ADR-0017/ADR-0018) and audited +before use; the procedural library and the MakeHuman head stay as the tested fallback. The +sheets below show the current library and will be replaced after the 12 × 6 baseline review. | | | | --- | --- | -| ![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. | +| ![Eight NPC characters](docs/blender_previews/sheet_npc.jpg) | **Character library.** Twelve role-dressed variants (4.5–6.4k triangles each) on three CC0 Quaternius bases, 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. | @@ -133,7 +136,7 @@ decisions are recorded as ADRs in [`docs/adr/`](docs/adr/). ## Tech Stack - **Engine:** Godot 4.7.2 · **Language:** GDScript -- **NPCs:** Blender-authored skinned library (`assets/models/blender/`) with procedural fallbacks; Quaternius CC0 base migration in progress; lightweight FSMs on `NpcProfile` +- **NPCs:** CC0 Quaternius skinned library (`assets/models/blender/`, ADR-0018) with a tested procedural fallback; lightweight FSMs on `NpcProfile` - **World:** procedural `WorldBuilder` + generated prop models - **Art:** v2 skyline/surface textures in `assets/textures/ai/game_ready/v2/picks/`; UI/scene art in `assets/images/` - **Asset tooling:** `asset_pipeline.py`, `model_pipeline.py`, `npc_pipeline.py`, `blender_assets.py`, `scene_concepts.py`, `screen_designs.py`, `check_screenshots.sh` diff --git a/docs/blender-assets.md b/docs/blender-assets.md index 562bbb1..4a58d30 100644 --- a/docs/blender-assets.md +++ b/docs/blender-assets.md @@ -142,11 +142,22 @@ render about 2.5 min. ## Characters -All library variants, including the incoming Quaternius-derived base, share the +All library variants share the [character and gear asset contract](architecture.md#character-and-gear-asset-contract): -`npc_base` mesh node, required 13 core bones (optional extras allowed), five -tint slots, +Z visual front, 24,000/24,000 character budget and the same 256² -slot-map/AO rules. Role selection and look notes: +`npc_base` mesh node, five tint slots, +Z visual front, 24,000/24,000 character budget and the +same 256² slot-map/AO rules. The shipped roster is on the 62-joint Quaternius skeleton +(ADR-0018); the procedural fallback built by `build --source procedural` keeps the 13 core bones. +Both are accepted by `audit`, `inspect`, the runtime bone map and the tests. + +The three Quaternius sources (`casual`, `hoodie`, `worker`) live in +`assets/models/blender_src/quaternius/` as build inputs. `build` (default +`--source quaternius`) does a two-pass bake per character: a cached T-pose round trip that joins +without welding, maps the upstream materials onto the five slots and unwraps the degenerate +source UVs, then an arm-down rest bake exported with `export_apply=False`. The per-character slot +map, triangle counts and measurements are in +[`npc-model-sourcing.md#shipped-roster-099-owner-chose-the-full-swap`](npc-model-sourcing.md#shipped-roster-099-owner-chose-the-full-swap). + +Role selection and look notes (tint + gear now carry the role, not the mesh): | Character | `layer_for()` / look | Suggested roles | Preview gear | | --- | --- | --- | --- | @@ -165,6 +176,11 @@ colour texture. The current `_apply_outfit_materials()` sets `albedo_color = WHITE` on any slot it does not recognise, and these keep their colour through that. When integrating, tint only the five contract slots. +**Head gear fit.** Head gear is authored for the shipped Quaternius head: +`HEAD_GEAR_SCALE = 0.64` (0.201 m base head against the 0.315 m procedural one) and +`HEAD_GEAR_LIFT = 0.07` (its centre sits higher). The procedural fallback therefore wears slightly +undersized caps — cosmetic and fallback-only. + **Runtime tint notes (implemented).** Only the five contract slots are tinted; fixed detail materials keep their authored colour. On `npc_vest` the vest is the fixed `hivis` material and `cloth` is the undershirt, so the yellow override is diff --git a/docs/development-status.md b/docs/development-status.md index 096fb61..723648e 100644 --- a/docs/development-status.md +++ b/docs/development-status.md @@ -34,11 +34,14 @@ and the active order/gaps in [`TODO.md`](../TODO.md). ## Known gaps - External first-time-player sessions and balance sweeps are not completed. -- The Quaternius NPC base is wired for one character (`npc_casual`): arm-down rest, five tint - slots, unwrapped UVs, 62-joint rig at source proportions, Idle/Walk/Sit pose code, 6,206 tris. - The remaining `0.9.9` blocker is the owner face/silhouette decision - (`docs/screens/npc-face-gate/`); the full 12-role roster rollout is `0.9.10`. The other eleven - characters stay procedural with the MakeHuman head until that decision lands. +- The Quaternius roster is shipped (`0.9.9`): all twelve characters are baked from the three CC0 + sources (casual tee, hoodie, work clothes), 4,458–6,424 triangles each, 62-joint rig at source + proportions, arm-down rest, five tint slots, unwrapped UVs and baked 256² AO. The procedural + library and the MakeHuman head remain the tested fallback. +- Roster silhouette variety is narrower than the procedural library (three meshes for twelve + roles, differentiated by tint and gear) until the modular part library is added. +- Head gear is authored for the shipped Quaternius head; the procedural fallback therefore wears + slightly undersized caps. Cosmetic, fallback-only. - Accessibility/localization acceptance, target-hardware profiling, macOS signing/notarization and AI/storefront legal approval remain open. - Live 3D replay, recorded VO/music, more venues and seasonal content are future diff --git a/docs/npc-model-sourcing.md b/docs/npc-model-sourcing.md index 49e8f92..3d36c39 100644 --- a/docs/npc-model-sourcing.md +++ b/docs/npc-model-sourcing.md @@ -238,6 +238,47 @@ Two source quirks shaped the bake: The face and silhouette gate sheet is in [`screens/npc-face-gate/`](screens/npc-face-gate/README.md). +## Shipped roster (0.9.9, owner chose the full swap) + +Every public character name is baked from one of the three CC0 sources. The build is +`tools/blender_assets.py build` (default `--source quaternius`); the sources live in +`assets/models/blender_src/quaternius/` and the geometry pipeline is two passes: + +1. `_quaternius_tpose_glb()` — import, drop the Icosphere helper, join **without welding**, + repoint the upstream materials onto the five tint slots, Smart-UV-unwrap + repack, export an + intermediate T-pose GLB. The round trip also normalises the mirrored upstream bone rolls, + which is what makes the next pass symmetric. +2. `_bake_quaternius_rest()` — pose `UpperArm.L/R` -90° local X, read the posed matrices, apply + the Armature modifier, reset the pose, write the rest matrices, re-add the modifier, export + with `export_apply=False`. + +Then `tools/bake_ao.py --only `. + +| Character | Source | Tris | Material slots | +| --- | --- | --- | --- | +| `npc_casual` | hoodie | 6,206 | skin, cloth, pants, hair, accessory + Eye, Eyebrows | +| `npc_jacket` | casual | 6,424 | five slots + eyes/brows | +| `npc_coat` | hoodie | 6,206 | five slots + eyes/brows | +| `npc_vest` | worker | 5,240 | five slots + hivis vest/hat, eyes, moustache | +| `npc_dress` | casual | 6,424 | five slots + eyes/brows | +| `npc_hoodie` | hoodie | 6,206 | five slots + eyes/brows | +| `npc_firefighter` | worker (vest + hat dropped) | 4,458 | five slots + eyes, moustache | +| `npc_guard` | worker (vest + hat dropped) | 4,458 | five slots + eyes, moustache | +| `npc_crowd_a` | casual | 6,424 | five slots + eyes/brows | +| `npc_crowd_b` | casual | 6,424 | five slots + eyes/brows | +| `npc_crowd_c` | hoodie | 6,206 | five slots + eyes/brows | +| `npc_crowd_d` | worker (vest + hat dropped) | 4,458 | five slots + eyes, moustache | + +Source slot maps (`QUATERNIUS_SOURCES`): the `casual` tee is `Skin`/`White`/`Orange`/`Grey`/ +`Hair_Blond`; the hoodie is `Skin`/`Purple`/`LightBlue`/`Hair`/`White`; the worker is `Skin`/ +`LightBrown`/`Brown`+`Brown2`/`Grey`+`Black`/`Eyebrows`. Everything not in the map keeps its +authored colour (eyes, brows, moustache, hivis vest and hard hat), so the contract still holds if +upstream adds a material — it shows up as an extra fixed-colour slot instead of vanishing. + +Head gear is authored for this head: `HEAD_GEAR_SCALE = 0.64` and `HEAD_GEAR_LIFT = 0.07` map the +0.315 m procedural head onto the 0.201–0.214 m Quaternius head. The procedural fallback therefore +wears slightly small hats. + ## Contract mismatch The expensive part is the rig and proportions, not the mesh. The source has a diff --git a/export_presets.cfg b/export_presets.cfg index f6f2f7a..3a10549 100644 --- a/export_presets.cfg +++ b/export_presets.cfg @@ -8,7 +8,7 @@ dedicated_server=false custom_features="" export_filter="all_resources" include_filter="" -exclude_filter="" +exclude_filter="tmp/*, tmp/**, build/*, build/**, docs/*, docs/**, tools/*, tools/**, src/test/*, src/test/**, .agents/*, .agents/**, packaging/*, packaging/**" export_path="build/gig-line-linux.x86_64" patches=PackedStringArray() encryption_include_filters="" @@ -39,7 +39,7 @@ dedicated_server=false custom_features="" export_filter="all_resources" include_filter="" -exclude_filter="" +exclude_filter="tmp/*, tmp/**, build/*, build/**, docs/*, docs/**, tools/*, tools/**, src/test/*, src/test/**, .agents/*, .agents/**, packaging/*, packaging/**" export_path="build/gig-line-windows.exe" patches=PackedStringArray() encryption_include_filters="" @@ -75,7 +75,7 @@ dedicated_server=false custom_features="" export_filter="all_resources" include_filter="" -exclude_filter="" +exclude_filter="tmp/*, tmp/**, build/*, build/**, docs/*, docs/**, tools/*, tools/**, src/test/*, src/test/**, .agents/*, .agents/**, packaging/*, packaging/**" export_path="build/gig-line-macos.zip" patches=PackedStringArray() encryption_include_filters="" @@ -114,7 +114,7 @@ dedicated_server=false custom_features="" export_filter="all_resources" include_filter="" -exclude_filter="" +exclude_filter="tmp/*, tmp/**, build/*, build/**, docs/*, docs/**, tools/*, tools/**, src/test/*, src/test/**, .agents/*, .agents/**, packaging/*, packaging/**" export_path="build/web/index.html" patches=PackedStringArray() encryption_include_filters="" diff --git a/project.godot b/project.godot index 7c6a7ad..b1e3949 100644 --- a/project.godot +++ b/project.godot @@ -12,7 +12,7 @@ config_version=5 config/name="Gig Line" config/description="Workplace security simulation about observation, access verification, and proportionate escalation." -config/version="0.9.8" +config/version="0.9.9" run/main_scene="res://scenes/main.tscn" config/features=PackedStringArray("4.7", "GL Compatibility") diff --git a/tools/build_releases.sh b/tools/build_releases.sh index 29ea5aa..52c6d34 100755 --- a/tools/build_releases.sh +++ b/tools/build_releases.sh @@ -90,5 +90,9 @@ echo "" echo "Artifacts:" ls -la build/*"${VERSION}"* echo "" +echo "Checksums:" +shasum -a 256 build/*"${VERSION}"* > "build/SHA256SUMS-${VERSION}.txt" +cat "build/SHA256SUMS-${VERSION}.txt" +echo "" echo "Upload to: https://git.allucanget.biz/zwitschi/security-game/releases" echo "See docs/RELEASING.md for the full release checklist."