Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a196a35342 | ||
|
|
efa062833f | ||
|
|
6381dbc5cb | ||
|
|
7546092c01 | ||
|
|
16dc1dfea4 | ||
|
|
2ba40f3578 | ||
|
|
045ed2a58f | ||
|
|
d3a87acf2d | ||
|
|
b18236f9b4 | ||
|
|
3b9e3b61d8 | ||
|
|
f6bb2b1de3 | ||
|
|
7a46963e3f | ||
|
|
a0dbf75806 | ||
|
|
c70a523f0f | ||
|
|
fcbeee0db2 | ||
|
|
d5e180e50c | ||
|
|
a36068aae7 | ||
|
|
6b58350464 | ||
|
|
219588bf8a | ||
|
|
cba00facf5 | ||
|
|
9fd48243ad | ||
|
|
30d145079a | ||
|
|
98f618c501 | ||
|
|
a290fe83c8 | ||
|
|
529d15ee7a | ||
|
|
3ab7577634 | ||
|
|
c8875a3dfa | ||
|
|
b3acf370fc | ||
|
|
04d211b90b | ||
|
|
a6ccd86f85 | ||
|
|
1ce173e9d1 | ||
|
|
90f189a269 | ||
|
|
fb3e75aba3 | ||
|
|
cd285b3a39 | ||
|
|
68f49253fe | ||
|
|
b012c6a675 | ||
|
|
2a6f29f5d0 | ||
|
|
bb54ef3eec | ||
|
|
11f53f66a3 | ||
|
|
9b65a93587 | ||
|
|
56a14747d4 | ||
|
|
8b1bf736af | ||
|
|
f121167e52 | ||
|
|
140a7ada0f | ||
|
|
5508f5510f | ||
|
|
7baa2c4f54 | ||
|
|
0cd12af994 | ||
|
|
271f10ac4d | ||
|
|
e2f52fbfd1 | ||
|
|
f5fa321a8f | ||
|
|
a2ae9e03c3 | ||
|
|
cff3937c16 | ||
|
|
1ed9e05d9b | ||
|
|
8c69f367b0 | ||
|
|
2a7921bae6 | ||
|
|
b419923637 | ||
|
|
c7fd4b59cc | ||
|
|
3fa3482608 | ||
|
|
1049d8631e | ||
|
|
deb74c53af | ||
|
|
9968bc0a4c | ||
|
|
2e1bb19e2c | ||
|
|
5450dbf88a | ||
|
|
79224c5acf | ||
|
|
f0d4b81239 | ||
|
|
48a9795248 | ||
|
|
a5e62534ce | ||
|
|
cd7697cba4 | ||
|
|
d2f773c7ad | ||
|
|
a3c3a37270 | ||
|
|
8dd4f77901 | ||
|
|
ba444152c9 | ||
|
|
d56f14c6dd | ||
|
|
b297c4543f | ||
|
|
958d3ae0ff | ||
|
|
d1898b3221 | ||
|
|
2e1e4d7f70 | ||
|
|
0b2f124ffe | ||
|
|
cdd2e02564 | ||
|
|
632ec16aaa | ||
|
|
30f240b591 | ||
|
|
58d1e79a12 | ||
|
|
44dba010a7 | ||
|
|
2a53ec9aac | ||
|
|
f0f609fe1b | ||
|
|
b386a21173 | ||
|
|
00bd197173 | ||
|
|
4f1eb1f5bf | ||
|
|
50edc47480 | ||
|
|
b8d8869e03 | ||
|
|
1b554df516 | ||
|
|
5fdda88d46 | ||
|
|
ecd50503e7 | ||
|
|
2b6e774580 | ||
|
|
dee939c2ee | ||
|
|
aec1fb7b69 | ||
|
|
50a48d2256 | ||
|
|
69f4f11633 | ||
|
|
d1fa25629e | ||
|
|
359bb9a8c7 | ||
|
|
36576a023a | ||
|
|
c1ccfd6e72 | ||
|
|
27b8f9a249 | ||
|
|
d5a2c911a6 | ||
|
|
236fbf537f | ||
|
|
588722fe7a | ||
|
|
7f2f06bf42 | ||
|
|
6db3cc0873 | ||
|
|
8938dd918c | ||
|
|
742bfd3898 | ||
|
|
87069a30e8 | ||
|
|
3f5c5ce442 | ||
|
|
28fcd96b59 | ||
|
|
e984129597 | ||
|
|
75dea2e7c2 | ||
|
|
09d07452af | ||
|
|
f5ee2b7408 | ||
|
|
5980d329e8 | ||
|
|
6052ea391b | ||
|
|
4e8665e25b | ||
|
|
b945eb6e8f | ||
|
|
03c13c716a | ||
|
|
0a9c78cb30 | ||
|
|
abe5c3f933 | ||
|
|
140ab42536 | ||
|
|
8bdfd0176e | ||
|
|
4e23cc3ad5 | ||
|
|
8d32a8cac0 | ||
|
|
2445ddab34 | ||
|
|
8cacd510bf | ||
|
|
bf383aa0fa | ||
|
|
4bbc576b7f | ||
|
|
542b1264da | ||
|
|
56f4833c8e | ||
|
|
1b31dfdbe4 | ||
|
|
5158efc467 | ||
|
|
ac0cf35cfb | ||
|
|
6655edb5c6 | ||
|
|
60f389c16b | ||
|
|
3084145031 | ||
|
|
34bca89885 | ||
|
|
b53e8a67f9 | ||
|
|
cdfd57fb65 | ||
|
|
5bab6754c0 | ||
|
|
7dd8251a0c | ||
|
|
8e113a4110 | ||
|
|
32c9c45605 | ||
|
|
e4065c2068 | ||
|
|
e7d733bc93 | ||
|
|
93da916f90 | ||
|
|
e3ec4a356a | ||
|
|
55339f23c1 | ||
|
|
a51dae2c33 | ||
|
|
6824dd76a1 | ||
|
|
fde4aa4d0a | ||
|
|
ebb36cf0cb | ||
|
|
724e8b183f | ||
|
|
e4e1566e55 | ||
|
|
0aacee6518 | ||
|
|
215b843b67 | ||
|
|
53d9dc3f78 | ||
|
|
98f2f95f07 | ||
|
|
a677a95d13 | ||
|
|
1afd97c72d | ||
|
|
6ca8bcf034 | ||
|
|
13eb4e0c87 | ||
|
|
8fac1b47cf | ||
|
|
b79e30e9df | ||
|
|
1e761e5a76 | ||
|
|
3eb2ae5e3c | ||
|
|
888897cac9 | ||
|
|
988d431da8 | ||
|
|
87e1c9e7a5 | ||
|
|
480a1ba05f | ||
|
|
43c17ce3c0 | ||
|
|
03f4d4bc49 | ||
|
|
15f9117517 | ||
|
|
78267918bf | ||
|
|
ea3860a60c | ||
|
|
b721f189c5 | ||
|
|
634b1f75a3 | ||
|
|
36583921cf | ||
|
|
3866b0ae01 | ||
|
|
8c2761427f | ||
|
|
2b07913481 | ||
|
|
768dd94bfc | ||
|
|
f516d3e796 | ||
|
|
f95a685934 | ||
|
|
05cb6a43cb | ||
|
|
343b3348c2 | ||
|
|
ad91e71eeb | ||
|
|
6e04c59589 | ||
|
|
e21ff30783 | ||
|
|
5b306b1c52 | ||
|
|
f09a5e7937 | ||
|
|
383f601bc9 | ||
|
|
c46db76d85 | ||
|
|
1a5f2863b0 | ||
|
|
a6fd77068a | ||
|
|
4ed73fcc7b | ||
|
|
c0ddce79e8 | ||
|
|
0c7c9a2b23 | ||
|
|
b94b87d096 | ||
|
|
5dec59355a | ||
|
|
fe3ba3054e | ||
|
|
88a0793bba | ||
|
|
1d4f718376 | ||
|
|
7a5b902797 | ||
|
|
2d67e14e52 | ||
|
|
2443343f2b | ||
|
|
3e41cda591 | ||
|
|
84bc4137cb | ||
|
|
5dc3ef0f4c | ||
|
|
6f3facff43 | ||
|
|
51f537720f | ||
|
|
08e9044593 | ||
|
|
ad14410337 | ||
|
|
876fb59882 | ||
|
|
979c6ad789 | ||
|
|
1921bfae91 | ||
|
|
78485259b7 | ||
|
|
fef3af44c0 | ||
|
|
bfe3c5a701 | ||
|
|
46f1e41874 | ||
|
|
f48d87c84f | ||
|
|
a9658ecd81 | ||
|
|
b8507df346 | ||
|
|
60bf9a8ef6 | ||
|
|
b51bdc8efe | ||
|
|
a7b2852253 | ||
|
|
4bb2896819 | ||
|
|
f5b8ef2e70 | ||
|
|
0044f5f065 | ||
|
|
4bc6390e9f | ||
|
|
fb3da52438 | ||
|
|
d7220c1a0a | ||
|
|
31574b8d82 | ||
|
|
b60f67548d | ||
|
|
a57b86cd48 | ||
|
|
dfe5056303 | ||
|
|
58cf12fd1d | ||
|
|
7150bd7673 | ||
|
|
12e70357c5 | ||
|
|
7dc3d3c873 | ||
|
|
cd5e0e0ff7 | ||
|
|
8ce62e7556 | ||
|
|
24c939d388 | ||
|
|
48082c3dfa | ||
|
|
03c355e7c1 | ||
|
|
15ab8c686d | ||
|
|
ab9c67d266 | ||
|
|
7c1a4bfd69 | ||
|
|
e7ee177c31 | ||
|
|
c1cd4898e8 | ||
|
|
e805a91ad3 | ||
|
|
7315166361 | ||
|
|
f6aa26e6ca | ||
|
|
26e6dd6413 | ||
|
|
8f65751975 | ||
|
|
9692f262f1 | ||
|
|
98c31fe44c | ||
|
|
daf0926d91 | ||
|
|
f71a36faa1 | ||
|
|
37f925c7ad | ||
|
|
74dc1fdc1d | ||
|
|
3f335481d6 | ||
|
|
af923b1483 | ||
|
|
3a74cedee0 | ||
|
|
844e39246a | ||
|
|
7c48183410 | ||
|
|
64590fe797 | ||
|
|
49bfccc808 | ||
|
|
7401d4bca0 | ||
|
|
e79a37beba | ||
|
|
fbd2ab2cb3 | ||
|
|
9b8f513f9f | ||
|
|
ad12fdad7e | ||
|
|
87612f2057 | ||
|
|
ffd98daf08 | ||
|
|
f811e6054d | ||
|
|
9d37e0a1c5 | ||
|
|
883626a067 | ||
|
|
b5d4d5fb87 | ||
|
|
fac9b002c3 | ||
|
|
aa51ee331e | ||
|
|
86332cd401 | ||
|
|
76eb5e3a79 | ||
|
|
f4a53e2d4f | ||
|
|
806fe78688 | ||
|
|
6a3066d763 | ||
|
|
f4cce28454 | ||
|
|
7d39523e49 | ||
|
|
7e084192ce | ||
|
|
6c367e8c7e |
No files matched your search
@@ -0,0 +1,212 @@
|
||||
---
|
||||
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 required 13 core bones (optional extra bones allowed), five tint slots, 24,000/24,000 character budgets, gear attach space, 256² texture/AO rules, headless flatpak Blender commands, optional MCP guidance, 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.
|
||||
Blender MCP is optional interactive tooling; the headless flatpak CLI remains
|
||||
authoritative and CI never needs Blender or MCP. The `blender-skills` pack is
|
||||
optional, local guidance only, and gitignored. Setup and safety are in
|
||||
`docs/assets/asset-tooling.md#optional-interactive-blender-mcp`.
|
||||
|
||||
## 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/assets/blender-assets.md` — library contract and command reference.
|
||||
4. `docs/assets/asset-tooling.md` — exact rebuild/bake/capture commands.
|
||||
5. `docs/assets/npc-model-sourcing.md` and `docs/assets/3d-model-review.md` — accepted limits,
|
||||
scorecards and known blockers.
|
||||
6. `docs/design/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 | The 13 required core bones: `Head`, `HipL/R`, `KneeL/R`, `ShoulderL/R`, `ElbowL/R`, `HandL/R`, `Spine`, `Neck`. Optional extra bones (fingers, face, toes) are allowed; they must not move the core rest positions or break animation proxies. |
|
||||
| Tint slots | `skin`, `cloth`, `pants`, `accessory`, `hair`. |
|
||||
| Orientation | Front is Blender −Y / Godot +Z; feet grounded near y = 0; metres. |
|
||||
| Character budget | **24,000 triangles / 24,000 glTF vertices** per character (`CHAR_MAX_TRIS`/`CHAR_MAX_VERTS`). |
|
||||
| Frozen fallback | `npc_base` remains the low-poly fallback; it shares the 24,000/24,000 cap but is not required to use it. Do not silently lower the cap. |
|
||||
| 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`
|
||||
|
||||
If MCP is available, use it for interactive part exploration only; mirror the result into a scripted change or local `.blend`, then re-export and run the CLI audit/fit gates. Never make the build, CI, tests or runtime depend on MCP. Setup: `docs/assets/asset-tooling.md#optional-interactive-blender-mcp`.
|
||||
|
||||
### 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 24,000/24,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/assets/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.
|
||||
- `docs/assets/asset-tooling.md#optional-interactive-blender-mcp` — optional MCP installation, connection, safety and
|
||||
part-workflow instructions.
|
||||
- [`references/verification.md`](references/verification.md) — command matrix,
|
||||
capture gates, expected results and acceptance criteria.
|
||||
|
||||
## Do not
|
||||
|
||||
- Make the build, CI, tests or runtime depend on MCP, Blender or API calls.
|
||||
- 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,141 @@
|
||||
# Asset Contract Reference
|
||||
|
||||
This is a working summary. The authoritative sources remain
|
||||
`docs/assets/blender-assets.md`, `docs/assets/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 required contract skeleton has 13 core bones:
|
||||
|
||||
```text
|
||||
Head, Spine, Neck,
|
||||
HipL, HipR,
|
||||
KneeL, KneeR,
|
||||
ShoulderL, ShoulderR,
|
||||
ElbowL, ElbowR,
|
||||
HandL, HandR
|
||||
```
|
||||
|
||||
Optional extra bones (fingers, face controls, toes) are allowed if they do not
|
||||
move these core rest positions and do not break `NpcAvatar`'s animation proxies.
|
||||
|
||||
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 |
|
||||
| --- | --- |
|
||||
| Character (library and base fallback) | 24,000 triangles / 24,000 glTF 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,130 @@
|
||||
# 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 |
|
||||
| Part GLB (local) | `flatpak run org.blender.Blender --background --python "$PWD/tools/npc_parts.py" -- inspect --file "$PWD/tmp/npc-parts/<variant>/<part>.glb"` | measurements; a part GLB is not a shipped asset |
|
||||
| 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
|
||||
|
||||
The part pipeline (`tools/npc_parts.py`) builds/extracts head/face/hand parts under
|
||||
`tmp/npc-parts/<variant>/`; these are local working files and are **not shipped**. Only the
|
||||
assembled character GLBs, AO/maps, the manifest and the review sheets are committed. An
|
||||
assembled GLB still goes through `blender_assets.py inspect`/`audit`/`fit` before any part is
|
||||
accepted. The `npc_base.blend` fallback is frozen: never save prototype detail into it.
|
||||
|
||||
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/assets/3d-model-review.md` and
|
||||
`docs/design/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.
|
||||
@@ -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/process/RELEASING.md` — build/publish commands, artifact list, macOS policy.
|
||||
4. `docs/process/release-qa.md` — manual QA matrix and balance protocol.
|
||||
5. `docs/project/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/project/architecture.md`,
|
||||
`docs/project/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/project/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/design/ui-copy.md#screen-design-judge-report` 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/process/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/project/architecture.md` | current version reference |
|
||||
| `docs/project/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.
|
||||
@@ -17,12 +17,13 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install Godot 4.3
|
||||
- name: Install Godot 4.7.2
|
||||
run: |
|
||||
curl -sL -o /tmp/godot.zip \
|
||||
https://github.com/godotengine/godot/releases/download/4.3-stable/Godot_v4.3-stable_linux.x86_64.zip
|
||||
https://github.com/godotengine/godot/releases/download/4.7.2-stable/Godot_v4.7.2-stable_linux.x86_64.zip
|
||||
unzip -qo /tmp/godot.zip -d /tmp/godot-bin
|
||||
sudo install /tmp/godot-bin/Godot_v4.3-stable_linux.x86_64 /usr/local/bin/godot
|
||||
sudo install /tmp/godot-bin/Godot_v4.7.2-stable_linux.x86_64 /usr/local/bin/godot
|
||||
godot --version
|
||||
|
||||
- name: Import project (build class cache)
|
||||
run: godot --headless --import
|
||||
@@ -56,18 +57,24 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install Godot 4.3 and export templates
|
||||
- name: Install Godot 4.7.2 and export templates
|
||||
run: |
|
||||
curl -sL -o /tmp/godot.zip \
|
||||
https://github.com/godotengine/godot/releases/download/4.3-stable/Godot_v4.3-stable_linux.x86_64.zip
|
||||
https://github.com/godotengine/godot/releases/download/4.7.2-stable/Godot_v4.7.2-stable_linux.x86_64.zip
|
||||
unzip -qo /tmp/godot.zip -d /tmp/godot-bin
|
||||
sudo install /tmp/godot-bin/Godot_v4.3-stable_linux.x86_64 /usr/local/bin/godot
|
||||
sudo install /tmp/godot-bin/Godot_v4.7.2-stable_linux.x86_64 /usr/local/bin/godot
|
||||
godot --version
|
||||
TEMPLATE_DIR="$HOME/.local/share/godot/export_templates/4.7.2.stable"
|
||||
NEEDED="version.txt icudt_godot.dat linux_release.x86_64 windows_release_x86_64.exe macos.zip web_nothreads_release.zip web_dlink_nothreads_release.zip"
|
||||
curl -sL -o /tmp/templates.tpz \
|
||||
https://github.com/godotengine/godot/releases/download/4.3-stable/Godot_v4.3-stable_export_templates.tpz
|
||||
mkdir -p ~/.local/share/godot/export_templates/4.3.stable
|
||||
cd /tmp && rm -rf tpl && mkdir tpl && unzip -qo templates.tpz -d tpl
|
||||
cp tpl/templates/* "$HOME/.local/share/godot/export_templates/4.3.stable/" 2>/dev/null || true
|
||||
ls "$HOME/.local/share/godot/export_templates/4.3.stable" | head -5
|
||||
https://github.com/godotengine/godot/releases/download/4.7.2-stable/Godot_v4.7.2-stable_export_templates.tpz
|
||||
rm -rf /tmp/tpl && mkdir -p /tmp/tpl
|
||||
unzip -qo /tmp/templates.tpz -d /tmp/tpl
|
||||
mkdir -p "$TEMPLATE_DIR"
|
||||
for file in $NEEDED; do
|
||||
cp "/tmp/tpl/templates/$file" "$TEMPLATE_DIR/$file"
|
||||
done
|
||||
ls "$TEMPLATE_DIR" | head -10
|
||||
|
||||
- name: Import project
|
||||
run: godot --headless --import
|
||||
@@ -114,7 +121,7 @@ jobs:
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
env:
|
||||
# An explicit repo secret wins. Without one, publish_release.sh reuses
|
||||
# the local git extraheader that actions/checkout configures for the job
|
||||
# the local git extraheader that actions/checkout configures on the job
|
||||
# (the runner's own credentials), so tag builds still publish.
|
||||
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||
VERSION: ${{ github.ref_name }}
|
||||
|
||||
@@ -37,6 +37,7 @@ Thumbs.db
|
||||
*.new
|
||||
|
||||
# Logs and temp
|
||||
tmp/
|
||||
*.log
|
||||
user://
|
||||
# CI runner workflow logs (written into the checkout by the Gitea runner)
|
||||
@@ -57,6 +58,20 @@ assets/models/generated/npc_base_*_normal.png
|
||||
|
||||
# Local AppImage extraction
|
||||
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
|
||||
# committed review artefacts are docs/blender_previews/sheet_*.jpg), and Godot
|
||||
# extracts the GLB-embedded textures next to the models on import.
|
||||
@@ -66,10 +81,14 @@ assets/models/blender/**/*.png
|
||||
assets/models/blender_src/*.blend1
|
||||
# Editable Blender sources are developer-only; keep the .gdignore marker tracked.
|
||||
assets/models/blender_src/*.blend
|
||||
# Realism pass (tools/scene_concepts.py): the candidate pool and per-run captures
|
||||
# stay local; the validated picks are tracked under game_ready/v2/picks/ (ADR-0014),
|
||||
# and each run commits its report.{json,md} + sheet.jpg. Concept references are
|
||||
# committed in docs/screens/concepts/.
|
||||
# Realism pass (tools/scene_concepts.py): candidate pools, per-run captures and
|
||||
# generated reports stay local; validated picks are tracked under
|
||||
# game_ready/v2/picks/ (ADR-0014). Concept references are committed in
|
||||
# docs/screens/concepts/, but generated QA lives outside the repository.
|
||||
assets/textures/ai/game_ready/v2/*
|
||||
!assets/textures/ai/game_ready/v2/picks/
|
||||
docs/screens/realism/**/*.png
|
||||
docs/screens/realism/
|
||||
|
||||
## Local pi agent session data
|
||||
pi-session-*.html
|
||||
pi-session-*.jsonl
|
||||
@@ -15,14 +15,106 @@ The project should be developed in small, reviewable steps. Agents must keep pla
|
||||
- `README.md` — Root-level documentation for the project. It should explain what the game is, how to work on it, how to run it, and where to find project information.
|
||||
- `AGENTS.md` — This collaboration and agent workflow guide.
|
||||
- `CHANGELOG.md` — The version history of user-facing changes. Keep an entry for each patch, minor, and major version.
|
||||
- `docs/development-status.md` — The implemented-features list and what is not yet implemented. Update it whenever a feature lands, is renamed, or is removed.
|
||||
- `docs/architecture.md` — The arc42-style architecture documentation (goals, constraints, building blocks, runtime views, decisions, risks).
|
||||
- `docs/gameplay.md` — Gameplay systems, venues, and the escalation model.
|
||||
- `docs/asset-tooling.md` — Asset pipelines, model tools, and screenshot gates.
|
||||
- `docs/getting-started.md` — Setup, run/test commands, and the controls table.
|
||||
- `docs/smoke-checklist.md` — The manual smoke-test checklist.
|
||||
- `docs/project/development-status.md` — The implemented-features list and what is not yet implemented. Update it whenever a feature lands, is renamed, or is removed.
|
||||
- `docs/project/architecture.md` — The arc42-style architecture documentation (goals, constraints, building blocks, runtime views, decisions, risks).
|
||||
- `docs/design/gameplay.md` — Gameplay systems, tutorial, venues and the escalation model.
|
||||
- `docs/design/venues.md` — Real-site evidence, game mapping and venue simplifications.
|
||||
- `docs/assets/asset-tooling.md` — Asset pipelines, model tools, optional Blender MCP and screenshot gates.
|
||||
- `docs/assets/blender-assets.md` — Blender library operation and asset roles.
|
||||
- `docs/assets/npc-model-sourcing.md` — Character-source evaluation, licence rules and the character-development plan.
|
||||
- `docs/process/getting-started.md` — Setup, run/test commands, and the controls table.
|
||||
- `docs/process/release-qa.md` — The manual smoke checklist and balance-acceptance protocol.
|
||||
- `docs/adr/` — Architecture Decision Records.
|
||||
|
||||
## Priority and Versioning
|
||||
|
||||
`TODO.md` is the priority source. The active order is:
|
||||
|
||||
1. unversioned development tracks;
|
||||
2. versioned release milestones, in version order;
|
||||
3. future/unversioned candidates and deferred work.
|
||||
|
||||
Do not assign a version number to an unversioned track until its scope is accepted into a
|
||||
release. When a version is assigned, it must be the next semantic version that matches the
|
||||
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, five tint slots, front on Blender −Y /
|
||||
Godot +Z, grounded feet, 24,000 triangles / 24,000 glTF vertices per character, 1,500 per
|
||||
gear, 4,000 per prop. The shipped procedural library uses the 13 required core bones at their
|
||||
rest positions; optional extra bones (fingers, face, toes) are allowed if they do not move the
|
||||
core rest positions. The one documented exception is the accepted Quaternius runtime path
|
||||
([ADR-0018](docs/adr/0018-quaternius-stage2-runtime-rig.md)): it keeps the 62-joint source rig
|
||||
at runtime while the 0.9.9 face/silhouette gate is open, and it must still supply the five tint
|
||||
slots, valid gear attach points and the same budgets. Both paths stay tested until that gate
|
||||
closes. 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. **Blender MCP is optional interactive tooling.** The headless flatpak scripts
|
||||
(`tools/blender_assets.py`, `tools/npc_pipeline.py`) remain authoritative. MCP may be used
|
||||
for local part exploration; setup and safety are in [`docs/assets/asset-tooling.md#optional-interactive-blender-mcp`](docs/assets/asset-tooling.md#optional-interactive-blender-mcp).
|
||||
Never add an MCP dependency to the build, CI, tests or runtime, and always re-run the CLI
|
||||
audit/fit gates on anything MCP touched.
|
||||
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-0017 (the CC0 Quaternius NPC base) supersedes the generator-first
|
||||
decision in ADR-0015, and the CC0/CC-BY rule in ADR-0015 (attribution in `CREDITS.md`) plus
|
||||
the provenance rules in `docs/assets/npc-model-sourcing.md` still apply to any new source.
|
||||
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
|
||||
|
||||
### 1. Start by Inspecting the Repository
|
||||
@@ -44,7 +136,16 @@ Do not assume that a task is unimplemented without checking the code and documen
|
||||
All planned implementation work must be represented in `TODO.md`.
|
||||
|
||||
- Use headings to group related work into sections.
|
||||
- Use checkbox items for each concrete task.
|
||||
- Use level-2 headings (`##`) for milestones or stable themes. A milestone should state its goal
|
||||
and an explicit exit criterion; a theme groups small related work that does not need a
|
||||
milestone.
|
||||
- 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
|
||||
version number to an unversioned track until it is scheduled for a release.
|
||||
- Use level-3 headings (`###`) for workstreams inside a milestone. Keep the hierarchy to three
|
||||
levels: milestone → workstream → checkbox.
|
||||
- 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.
|
||||
- Keep tasks small enough to complete and review independently.
|
||||
- Add new tasks when discoveries expand the scope.
|
||||
- When starting a task, claim it for the agent workflow by changing `[ ]` to `[-]`. Keep it `[-]`
|
||||
@@ -61,29 +162,53 @@ Recommended format:
|
||||
```md
|
||||
# TODO
|
||||
|
||||
## Core Gameplay
|
||||
## Milestone X.Y.Z — goal and exit criterion
|
||||
|
||||
- [ ] Add player movement controls.
|
||||
- [-] Implement NPC approach behavior. (claimed; implementation/verification in progress)
|
||||
- [x] Define escalation levels.
|
||||
### Workstream A
|
||||
|
||||
## Documentation
|
||||
- [x] Completed task.
|
||||
- [-] Task in progress. (claimed; implementation/verification in progress)
|
||||
- [ ] Open task.
|
||||
|
||||
- [ ] Document the test procedure in `README.md`.
|
||||
### Workstream B
|
||||
|
||||
- [ ] Another task.
|
||||
|
||||
**Exit:** a verifiable statement of what "done" means for the milestone.
|
||||
|
||||
## Theme
|
||||
|
||||
- [ ] 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
|
||||
first, then versioned milestones in version order, then future/deferred work.
|
||||
|
||||
### 3. Move Completed Sections to `DONE.md`
|
||||
|
||||
When every task in a `TODO.md` section is complete:
|
||||
`TODO.md` uses nested sections. Apply these completion rules:
|
||||
|
||||
1. Verify the work and update the checkbox items to `[x]`.
|
||||
2. Move the entire completed section, including its heading and checklist, to `DONE.md`.
|
||||
3. Remove that section from `TODO.md`.
|
||||
4. Add a short completion note or date when useful.
|
||||
1. **Level-3 workstream:** verify the work, mark every checkbox `[x]`, and add a short completion
|
||||
note. Leave the completed workstream under its parent milestone; do not move an isolated
|
||||
level-3 section to `DONE.md`.
|
||||
2. **Level-2 milestone/theme:** it is complete only when its direct checkboxes and **all** of its
|
||||
level-3 workstreams are complete. Verify the whole milestone, record its capabilities in
|
||||
`docs/project/development-status.md` when it represents shipped functionality, and write the matching
|
||||
`CHANGELOG.md` entry.
|
||||
3. Move the **entire level-2 section**, including all level-3 headings and checklists, to
|
||||
`DONE.md`. Remove it from `TODO.md` and add a completion date/note.
|
||||
4. **Planning/overview sections** such as a gap analysis, roadmap overview, dependencies or
|
||||
deferred ideas are not completion milestones. Do not move them merely because their checkboxes
|
||||
are empty or complete; update or supersede them as the roadmap changes.
|
||||
5. Do not move partially completed milestones. Leave them in `TODO.md` until every nested task is
|
||||
complete, or split the unfinished work into a new smaller level-2 milestone first.
|
||||
|
||||
Do not move partially completed sections. Leave them in `TODO.md` until all of their tasks are complete, or split the section into smaller sections first.
|
||||
|
||||
When a completed section represents shipped functionality, also record the new capability in `docs/development-status.md` so the implemented-features list stays accurate, and write a matching entry in `CHANGELOG.md` (see "Maintain `CHANGELOG.md`" below).
|
||||
When a completed milestone represents shipped functionality, also record the new capability in
|
||||
`docs/project/development-status.md` so the implemented-features list stays accurate, and write a matching
|
||||
entry in `CHANGELOG.md` (see "Maintain `CHANGELOG.md`" below).
|
||||
|
||||
### 4. Maintain `MEMORY.md`
|
||||
|
||||
@@ -92,7 +217,7 @@ Use `MEMORY.md` for information that should persist between sessions but does no
|
||||
Record items such as:
|
||||
|
||||
- Important design and architecture decisions
|
||||
- Notable implementation state and gotchas (the canonical implemented-features list lives in `docs/development-status.md`, not here)
|
||||
- Notable implementation state and gotchas (the canonical implemented-features list lives in `docs/project/development-status.md`, not here)
|
||||
- Known bugs and workarounds
|
||||
- Commands needed to run, test, or build the project
|
||||
- Decisions that future agents should not revisit unnecessarily
|
||||
@@ -142,19 +267,21 @@ The root-level `README.md` is the project’s public-facing technical and projec
|
||||
- Links to `PLAN.md`, `TODO.md`, `DONE.md`, `MEMORY.md`, and this file where appropriate
|
||||
- Known limitations and contribution guidance
|
||||
|
||||
Update `README.md` whenever setup instructions, commands, project structure, or user-facing behavior changes. The README is intentionally concise and links to the `docs/` files; keep `docs/development-status.md` (and the other docs it links to) synchronized with the implementation rather than pasting detail back into the README.
|
||||
Update `README.md` whenever setup instructions, commands, project structure, or user-facing behavior changes. The README is intentionally concise and links to the `docs/` files; keep `docs/project/development-status.md` (and the other docs it links to) synchronized with the implementation rather than pasting detail back into the README.
|
||||
|
||||
### 7. Maintain `CHANGELOG.md`
|
||||
|
||||
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.
|
||||
- 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
|
||||
matching local release build have all been produced and verified.
|
||||
- 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.
|
||||
- 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 level-2 section 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`:
|
||||
|
||||
1. Verify the work and mark every checkbox in the section `[x]`.
|
||||
2. Use the section heading and its completed items to describe the changes and write a `CHANGELOG.md` entry under the next appropriate version.
|
||||
@@ -170,16 +297,44 @@ For each task:
|
||||
2. Inspect the relevant files and dependencies.
|
||||
3. Make the smallest coherent change that completes the task.
|
||||
4. Run the relevant tests, checks, or manual verification.
|
||||
5. Update documentation if the change creates lasting context: add features to `docs/development-status.md`, adjust the README links or other `docs/` files as needed, and record decisions/gotchas in `MEMORY.md`.
|
||||
5. Update documentation if the change creates lasting context: add features to `docs/project/development-status.md`, adjust the README links or other `docs/` files as needed, and record decisions/gotchas in `MEMORY.md`.
|
||||
6. Mark the task complete.
|
||||
7. Move its section to `DONE.md` when the entire section is complete (after recording its `CHANGELOG.md` entry).
|
||||
8. Commit the changes to the version control system with a descriptive message.
|
||||
9. If a section from `TODO.md` has been fully completed, ensure its `CHANGELOG.md` entry is in place, then create a new version or tag in the version control system to mark the milestone.
|
||||
10. Push the committed changes to the shared repository if applicable.
|
||||
11. Note the new version or tag created in the version control system in any relevant documentation or handoff summary.
|
||||
7. Keep completed level-3 workstreams in place until the parent milestone is complete; then move the entire level-2 milestone to `DONE.md` after recording its `CHANGELOG.md` entry.
|
||||
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
|
||||
shareable.
|
||||
9. If the change is a release (a major, minor, or patch version increment), follow the Release
|
||||
Procedure in "Commit, Build and Version Discipline".
|
||||
10. Push committed changes to the shared repository if applicable.
|
||||
11. Note the new version, build artifacts or tag in the relevant documentation and handoff
|
||||
summary.
|
||||
|
||||
Avoid unrelated refactors unless they are required for the task or explicitly approved.
|
||||
|
||||
### 9. Commit, Build and Version Discipline
|
||||
|
||||
- **Commit often.** Make a commit after each coherent change or verified task, not only when a
|
||||
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
|
||||
local-only history.
|
||||
- **Build every version.** Every major, minor and patch increment follows the Release Procedure
|
||||
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
|
||||
the required pre-tag check for every version.
|
||||
- **Unversioned tracks stay unversioned.** A development track does not get a placeholder
|
||||
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
|
||||
|
||||
- Prefer clear, reversible changes over broad rewrites.
|
||||
@@ -188,6 +343,8 @@ Avoid unrelated refactors unless they are required for the task or explicitly ap
|
||||
- Do not claim a task is complete without verification.
|
||||
- Keep documentation synchronized with the implementation.
|
||||
- Mention files changed and checks run in handoff summaries.
|
||||
- Commit coherent increments as you go; do not wait until the end of a milestone.
|
||||
- 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.
|
||||
- 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.
|
||||
@@ -199,6 +356,10 @@ Before handing off work, an agent must run every check below that applies to the
|
||||
- Run automated tests.
|
||||
- Run formatting, linting, or type checks.
|
||||
- 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.
|
||||
- Review the final diff for accidental changes or unfinished markers.
|
||||
|
||||
|
||||
@@ -4,6 +4,327 @@ All notable user-facing changes to Gig Line. The format follows
|
||||
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and versions use
|
||||
Semantic Versioning.
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Fixed
|
||||
|
||||
- The red event banners are lit from the top down at night instead of reading as flat red cards.
|
||||
- Hollywood and the TV Studio got the same queue treatment, and the TV Studio's props no longer sit
|
||||
in the entrance steps.
|
||||
- The Joke Shop has a readable queue: a velvet rope line leading to the check-in podium, a thicker
|
||||
bike-rack barricade on the curb side, and a planter no longer clipping the palm foliage.
|
||||
- Street lamps now throw a warm pool on the pavement instead of dimly washing the whole walkway.
|
||||
- The flashlight actually lights what it points at. It was tuned to a beam so weak it changed the
|
||||
frame by less than one 255th of a level; it now throws a visible pool on the door and the pavement
|
||||
ahead, in both venues.
|
||||
|
||||
### Changed
|
||||
|
||||
- Street greenery now reads as leaves instead of green rocks: the planter shrubs and tree crowns
|
||||
are built from leaf cards, which also cut their triangle count by about a third.
|
||||
|
||||
### Changed
|
||||
|
||||
- Removed every hat and hood from the NPC roster: the firefighter helmet is the only head gear
|
||||
left, so no character hides its face behind a cap. The street performer no longer wears the
|
||||
cone hat and carries the baton and board in the hands instead.
|
||||
- Hands, head gear and carried items were re-fitted to the new characters: hand items sit in the
|
||||
palm instead of floating at the wrist, the lanyard moved up to the sternum, back gear moved up to
|
||||
shoulder-blade height, and the clipboard is carried by its top edge.
|
||||
- NPCs now wear eleven different outfits instead of three: the modular outfit pack brought a formal
|
||||
suit for the influencer, a punk jacket and mohawk, beach wear, farmer overalls and straw hat, an
|
||||
adventurer jacket, a second casual jersey, and royal armour with a gold crown for the street
|
||||
performer.
|
||||
- NPCs no longer all share one hairstyle: the roster now uses short, buzz and long hair silhouettes
|
||||
instead of a single shell in twelve colours.
|
||||
- Eyes now have whites and pupils instead of flat dark rectangles.
|
||||
- Every NPC now has a visible mouth; the Quaternius heads shipped without one, so the faces read as
|
||||
brow-and-eye masks.
|
||||
- Fixed the modular Worker characters: the guard, delivery, firefighter and crowd roles had holes
|
||||
in the torso and an open crown, a continuous unibrow and no visible eyes. They now have a closed
|
||||
torso, hair, two eyebrows and two eyes.
|
||||
|
||||
## [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 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
|
||||
|
||||
### 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
|
||||
|
||||
### Changed
|
||||
|
||||
- Prepared the release-candidate packages for Linux, Windows, macOS, Web and the
|
||||
optional Desktop HQ zip. The Web/HQ archives now include the credits, privacy,
|
||||
accessibility and known-limitations pages, and release publishing writes
|
||||
SHA-256 checksums and rolls back partial uploads.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Corrupt or partial save files now fall back to safe defaults without logging a
|
||||
parse error, and a failed atomic replace leaves the previous valid settings
|
||||
intact. Added migration coverage for 0.8-era profiles and 0.9.0 checkpoints
|
||||
across all three venues.
|
||||
|
||||
## [0.9.6] — 2026-11-02
|
||||
|
||||
### Changed
|
||||
|
||||
- The UI, model and texture passes are now integrated into a verified checkpoint
|
||||
build. The gallery, NPC portraits, realism captures, asset audits, smoke
|
||||
matrix, 24-NPC budget and Web/Desktop HQ packages were regenerated and
|
||||
re-checked; no gameplay or content changes were introduced.
|
||||
|
||||
## [0.9.5] — 2026-11-02
|
||||
|
||||
### Changed
|
||||
|
||||
- NPC albedo, normal and ORM maps are now 256² instead of 128², giving the
|
||||
face, fabric and gear materials more detail at portrait distance.
|
||||
- NPC fabric maps now repeat four times across the body and skip the baked
|
||||
per-character AO, removing the large blotchy patches from shirts, jackets and
|
||||
trousers at portrait distance.
|
||||
- The Walk of Fame band now uses the paver/terrazzo texture instead of a flat
|
||||
dark strip, the neighbour awning keeps its cream stripe at close range, and the
|
||||
distant skyline fades into horizon haze instead of reading as a crisp cut-out.
|
||||
|
||||
## [0.9.4] — 2026-11-02
|
||||
|
||||
### Changed
|
||||
|
||||
- Character meshes now have an 8,000-triangle / 8,000-vertex library budget
|
||||
(up from 6,000 / 5,000) to support the remaining face, grip and clothing
|
||||
detail; the `npc_base` fallback keeps its original 6,000 / 4,000 contract.
|
||||
- Character necks are fuller and shoulders slope from the neck instead of
|
||||
reading as a thin post on a hanger.
|
||||
- Character eyes sit in the socket behind a thin upper lid, and the chin and
|
||||
cheekbones are sculpted into the head instead of reading as separate spheres.
|
||||
- Character torsos taper from the chest to the waist and flare slightly into
|
||||
the hips, so shirts and jackets sit less like straight tubes.
|
||||
- Character hands now have a wider palm, bent fingers with rounded tips and a
|
||||
separate thumb instead of flat bars.
|
||||
- Character noses gained ala wings and a smaller bridge/tip, the mouth is a
|
||||
rounded slot, and the ears have a darker inner concha.
|
||||
- Hand-held items now sit forward in the open palm instead of being partly
|
||||
buried inside the hand.
|
||||
- Shoes and responder boots now have rounded toes and heels instead of reading
|
||||
as flat blocks.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Tourists no longer appear to carry two backpacks: the photo-pose camera bag is
|
||||
hidden except while they are actually taking a picture.
|
||||
- Backpack shoulder straps are now flattened bands that sit outside the chest
|
||||
instead of thin rods partly buried in the torso.
|
||||
|
||||
## [0.9.3] — 2026-11-02
|
||||
|
||||
### Added
|
||||
|
||||
- Eight committed gallery captures now cover the start menu, pause, settings,
|
||||
shift review, emergency radio, action wheel, crowd panic and responder
|
||||
arrival, so every screen-design reference has a deterministic current-build
|
||||
capture.
|
||||
|
||||
### Changed
|
||||
|
||||
- All session, settings, radio, Help, review and timeline action buttons now
|
||||
share explicit normal, hover, pressed, focus and disabled styles. Timeline
|
||||
Previous/Next disable at their boundaries.
|
||||
- Keyboard and gamepad focus rings now wrap through every modal, with explicit
|
||||
default focus and A/B accept/cancel bindings; hidden Continue and disabled
|
||||
timeline controls are skipped.
|
||||
- Esc and right-click now close the top panel consistently, restore the venue
|
||||
menu after menu Settings, and recapture the mouse without leaving the guard
|
||||
frozen. Help no longer opens Pause behind itself.
|
||||
- The HUD target chip grows and caps with the selected font scale, top labels
|
||||
clip safely, and long action-button labels ellipsize instead of pushing panels
|
||||
wider than the screen.
|
||||
- Campaign reset and tutorial replay now share a guarded confirmation dialog;
|
||||
repeated presses cannot stack dialogs or fire the action twice. Emergency
|
||||
hold-to-send still submits once and ignores the release after submission.
|
||||
- NPC reason answers now use role-specific dialogue contexts, so staff, guests,
|
||||
delivery workers, performers and other archetypes answer instead of silently
|
||||
deflecting the Reason verb.
|
||||
- Hollywood and the TV Studio now have door-staff lines for their wristband,
|
||||
ticket, credential and guest-list checks.
|
||||
- Clarified the emergency radio cancellation message, the Ask verb in Help/HUD
|
||||
hints, the start-menu key hint and the campaign-reset confirmation.
|
||||
|
||||
## [0.9.2] — 2026-11-02
|
||||
|
||||
### Added
|
||||
|
||||
- A stylized reconstruction of the real El Capitan Entertainment Centre block at
|
||||
6840 Hollywood Boulevard: six Ionic columns, eight stone steps, the Masonic
|
||||
parapet motto and medallions, red event banners, central and side entrances,
|
||||
the El Capitan Theatre and retail neighbours, the Ovation Hollywood arcade,
|
||||
the Walk of Fame and four-lane street markings.
|
||||
- Real-site reference notes and AI art-direction frames for the Hollywood block.
|
||||
- The Joke Shop is now a Sunset Strip comedy-club block based on The Comedy Store at
|
||||
8433 Sunset Blvd: a 27 m black hall under a signature-covered canopy, a circular
|
||||
**THE JOKE SHOP** blade sign, red velvet curtain bays, a west-end entrance, cream
|
||||
and white neighbours, a dry hillside of stucco houses and palms, and a low retail
|
||||
and billboard frontage across Sunset.
|
||||
- Real-site reference notes and AI art-direction frames for the Joke Shop block,
|
||||
including day, night and across-the-street concepts.
|
||||
- A separate day capture stage for the Joke Shop, so the club can be compared in
|
||||
both lighting states.
|
||||
- Completed the UI string migration: start menu, settings, pause, Help, HUD,
|
||||
radio and shift-review labels now come from the English string table.
|
||||
- Separate **Hollywood Boulevard — Day** and **Hollywood Boulevard — Night**
|
||||
rows in the venue menu. Night starts directly in the late phase and keeps the
|
||||
full shift after dark.
|
||||
|
||||
### Changed
|
||||
|
||||
- The default Hollywood venue is no longer a generic brick entrance; the venue
|
||||
name and policy copy now identify the El Capitan Entertainment Centre.
|
||||
- Night lighting on the landmark uses low-energy practical washes rather than
|
||||
the street-lamp brightness, so the facade reads without blowing out.
|
||||
- The Joke Shop lighting now uses warm sconces, canopy downlights and ground
|
||||
uplights; the hillside stays a dark silhouette at night instead of a lit wall.
|
||||
- The Joke Shop venue copy and gallery captions describe the Sunset Strip block,
|
||||
not the old brick alley.
|
||||
|
||||
### Fixed
|
||||
|
||||
- The Ovation Hollywood sign faces the boulevard instead of rendering mirrored.
|
||||
- Local night lights use linear attenuation instead of constant falloff, so
|
||||
sconces and street lamps pool on the ground and stone rather than washing the
|
||||
whole facade flat and yellow.
|
||||
- The captured HUD clears stale objectives and target prompts between staged
|
||||
screenshots.
|
||||
- The Joke Shop beauty capture closes a stale wand/inspection panel before shooting
|
||||
and frames the entrance and sign instead of a nearby target.
|
||||
- Multiline HUD and wand strings now render real line breaks instead of a literal
|
||||
`\n`; the wand panel also lists the guest's carried items.
|
||||
- Final-context NPC gear fit: authorized-guest lanyards now show their badge in
|
||||
front of the jacket, and responder helmets sit above the eyes instead of across
|
||||
the brow.
|
||||
|
||||
## [0.9.1] — 2026-11-02
|
||||
|
||||
### Changed
|
||||
|
||||
- Unified the project, local tooling and CI/release environment on Godot 4.7.2,
|
||||
including matching export templates and project feature metadata.
|
||||
- Evaluated Gitea Actions cache for the Godot binary/templates; disabled it after
|
||||
cache saves timed out or were rejected, pending a healthy host cache service.
|
||||
- Updated release and setup documentation for the 4.7.2 baseline.
|
||||
|
||||
## [0.9.0] — 2026-11-01
|
||||
|
||||
### Added
|
||||
|
||||
- Master/SFX/ambience volume controls, a captions toggle and a Reduce motion
|
||||
option in Settings.
|
||||
- A 24-NPC performance budget smoke and expanded audio/accessibility coverage.
|
||||
- Explicit production-quality scope for animation, audio, localization and the
|
||||
Godot 4.3-CI/4.7-local support matrix.
|
||||
|
||||
### Changed
|
||||
|
||||
- Coat and dress strides are shortened to reduce hem/leg clipping.
|
||||
- Help and the shift-review surface expose the current policy and accessibility
|
||||
settings.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Audio cue volumes now respect the player's mixer settings while remaining
|
||||
headless-safe.
|
||||
|
||||
## [0.8.1] — 2026-11-01
|
||||
|
||||
### Fixed
|
||||
|
||||
- Normal radio reports now send on click. The button was wired only to the
|
||||
emergency hold-to-confirm handlers, so a non-emergency press did nothing.
|
||||
|
||||
## [0.8.0] — 2026-11-01
|
||||
|
||||
### Added
|
||||
|
||||
- A first-shift tutorial with contextual prompts, a safe visitor and replay/skip.
|
||||
- A three-venue campaign shell with shift progression and a Continue action.
|
||||
- Resume-from-checkpoint for paused shifts, including NPC, incident and system state.
|
||||
- Easy/normal/hard difficulty presets for spawn pacing, compliance tolerance and
|
||||
report strictness.
|
||||
- A searchable in-game Help overlay with controls and the current venue policy.
|
||||
- Recovery events, contextual NPC dialogue and an eligible-event debug preview.
|
||||
|
||||
### Changed
|
||||
|
||||
- The shift review now includes venue policy, campaign next steps and continued
|
||||
review controls.
|
||||
- Event scheduling suppresses recently played scripted events and respects the
|
||||
difficulty spawn multiplier.
|
||||
- Save data is written atomically and split into settings, campaign, shift
|
||||
history and versioned checkpoint files.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Missing/older settings migrate through defaults; a partial write cannot
|
||||
replace a valid save.
|
||||
- The HUD debug overlay now refreshes and shows the next eligible events.
|
||||
|
||||
## [0.7.3] — 2026-11-01
|
||||
|
||||
### Fixed
|
||||
|
||||
- Mouse look now reads relative motion at the `_input` stage, so a full-screen
|
||||
HUD or focused control cannot swallow it while the cursor is captured.
|
||||
- Mouse capture is restored after window/compositor focus returns, and clicking
|
||||
back into a gameplay window recaptures it instead of opening the radial menu.
|
||||
- The HUD is mouse-transparent; its presentation controls no longer block
|
||||
gameplay mouse input.
|
||||
|
||||
## [0.7.2] — 2026-11-01
|
||||
|
||||
### Added
|
||||
@@ -49,12 +370,6 @@ Semantic Versioning.
|
||||
|
||||
## [0.7.0] — 2026-11-01
|
||||
|
||||
### Changed
|
||||
|
||||
- Agent workflow now requires maintaining this changelog for every patch, minor, and major version.
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
|
||||
- Distinct venue geometry: the Joke Shop is now a narrow brick alley with a
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
# Credits and Provenance
|
||||
|
||||
Gig Line is a local, single-player security-shift game built with Godot 4 and
|
||||
GDScript. This file records the asset provenance needed for the release review;
|
||||
it is not a legal opinion or a claim that every provider licence has already
|
||||
been cleared for public distribution.
|
||||
|
||||
## Game, code and design
|
||||
|
||||
- Game design, systems, scenarios, dialogue and UI code: the Gig Line project.
|
||||
- Engine: [Godot Engine 4.7.2](https://godotengine.org/), MIT licence.
|
||||
- The game bundles no third-party fonts; it uses Godot's default theme font.
|
||||
- No third-party music, sound effects or voice recordings are bundled. Crowd
|
||||
ambience and radio cues are generated procedurally at runtime.
|
||||
|
||||
## 3D characters, gear and props
|
||||
|
||||
The local MakeHuman head prototype uses the CC0 MakeHuman/MPFB base mesh
|
||||
(see [`docs/assets/makehuman-head-review.md`](docs/assets/makehuman-head-review.md)); it is a
|
||||
development prototype, not a shipped character.
|
||||
|
||||
The character, gear and prop library is generated by project-owned scripts
|
||||
(`tools/blender_assets.py`, `tools/npc_pipeline.py`, `tools/model_pipeline.py`)
|
||||
using Blender. The `.blend` working sources are developer artifacts and are not
|
||||
shipped. The exported `.glb` files and baked AO maps are project assets; they do
|
||||
not embed third-party models or purchased asset packs.
|
||||
|
||||
### Development-only research previews
|
||||
|
||||
Two review sheets under `docs/blender_previews/` compare source candidates for
|
||||
the future NPC variety work. They are development documentation and are not
|
||||
bundled with the game or its release packages. The underlying source models are
|
||||
kept outside version control.
|
||||
|
||||
- [`sheet_npc_sources_research.jpg`](docs/blender_previews/sheet_npc_sources_research.jpg)
|
||||
includes renders of **Quaternius Ultimate Modular Characters** (CC0 1.0,
|
||||
<https://quaternius.com/>), **Kenney Blocky Characters 2.0** (CC0 1.0,
|
||||
<https://kenney.nl/assets/blocky-characters>), and **CesiumMan** and
|
||||
**RiggedFigure** (CC BY 4.0, © 2017 Cesium,
|
||||
<https://github.com/KhronosGroup/glTF-Sample-Assets>).
|
||||
- [`sheet_npc_crowd_prototypes.jpg`](docs/blender_previews/sheet_npc_crowd_prototypes.jpg)
|
||||
contains renders of project-owned generator prototypes.
|
||||
|
||||
The CC-BY preview images are included only as development evidence. Any future
|
||||
shipped derivative of CesiumMan or RiggedFigure must keep the attribution above.
|
||||
|
||||
### MakeHuman head source
|
||||
|
||||
The standalone MakeHuman head prototype is derived from the MakeHuman / MPFB base
|
||||
mesh, **CC0** (`assets/models/blender_src/makehuman_head.glb`; source
|
||||
<https://static.makehumancommunity.org/makehuman.html>, MakeHuman base mesh,
|
||||
CC0 1.0). It is cut, retopologised and re-weighted by project scripts; the exported
|
||||
character GLBs remain project assets. The development source files were removed
|
||||
from `tmp/` after the 2026-11-05 pivot to Quaternius. The head is retained as a
|
||||
tested fallback, not the active NPC base. See ADR-0017 and
|
||||
`docs/assets/npc-model-sourcing.md`.
|
||||
|
||||
### Quaternius NPC base source
|
||||
|
||||
The active NPC base migration uses **Quaternius Ultimate Modular Characters** and
|
||||
**Ultimate Modular Women** (CC0 1.0, <https://quaternius.com/>). The three
|
||||
researched GLBs are development inputs and are not shipped directly; the baked,
|
||||
retargeted character GLBs are project assets. See ADR-0017 and
|
||||
`docs/assets/npc-model-sourcing.md` for the decision, source hashes and rollout status.
|
||||
|
||||
The venue geometry is authored procedurally in `src/game/world_builder.gd` as a
|
||||
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
|
||||
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
|
||||
|
||||
Surface textures, skyline panoramas, UI art and concept references were produced
|
||||
with image-generation calls from the project's tooling. The default model slugs
|
||||
recorded in the source are:
|
||||
|
||||
- `bytedance-seed/seedream-4.5` — `tools/generate_textures.py`
|
||||
- `openai/gpt-5-image-mini` — `tools/asset_pipeline.py`,
|
||||
`tools/model_pipeline.py`, `tools/scene_concepts.py` and
|
||||
`tools/screen_designs.py`
|
||||
- Judging/review calls use the model selected by `tools/openrouter_judge.py` and
|
||||
are development-only; they do not ship in the game.
|
||||
|
||||
The prompts and generation workflow live in those tools. Per-file generation
|
||||
metadata is not stored with every image, so the exact provider, model version and
|
||||
generation date of each committed bitmap cannot be reconstructed from the
|
||||
repository alone. Before a public 0.10.0 release, the provider terms and
|
||||
commercial-use/redistribution rights for those generated outputs must be
|
||||
reviewed and recorded. **This is a release blocker, not an assumed clearance.**
|
||||
|
||||
Reference photographs linked from the venue documents are hosted on Wikimedia
|
||||
Commons and were used for proportion/material study only. They are not included
|
||||
in the game or its release packages. If any future derivative asset copies a
|
||||
reference more directly, its attribution and licence must be added here.
|
||||
|
||||
## Audio
|
||||
|
||||
All runtime audio is procedural (crowd bed, radio crackle and interface cues).
|
||||
There are no external audio files, so there is no separate music/SFX licence to
|
||||
clear. See `docs/design/accessibility.md` for caption and volume behaviour.
|
||||
|
||||
## Third-party names
|
||||
|
||||
The game is a work of fiction. Real place names and public references are used
|
||||
for orientation and satire/stand-in geography; no real person, venue or brand
|
||||
endorses the game. Review the storefront and trademark language before release.
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## Premise
|
||||
|
||||
You are a private security guard working the entrance of a fictional Hollywood Boulevard building. You keep the steps and doors clear, check who is allowed in, and deal with tourists, performers, influencers, confused visitors, intoxicated pedestrians, trespassers, people in mental-health crisis, and rare determined threats.
|
||||
You are a private security guard working the entrance of a stylized reconstruction of the real El Capitan Entertainment Centre on Hollywood Boulevard. You keep the steps and doors clear, check who is allowed in, and deal with tourists, performers, influencers, confused visitors, intoxicated pedestrians, trespassers, people in mental-health crisis, and rare determined threats.
|
||||
|
||||
The game is about **judgment, communication, access verification, and proportionate escalation**, not about attacking everyone who approaches.
|
||||
|
||||
@@ -14,6 +14,94 @@ The game is about **judgment, communication, access verification, and proportion
|
||||
- **Emergency help is a last resort.** Responders handle crises the guard cannot safely manage; calling them has costs.
|
||||
- **Readability beats raw fidelity.** The GL Compatibility renderer, clear silhouettes, the focus ring, and the HUD stay legible.
|
||||
|
||||
## Development Priorities
|
||||
|
||||
The active task order is in [`TODO.md`](TODO.md); the gap analysis and the release roadmap are
|
||||
below. The current order is:
|
||||
|
||||
1. **0.9.9–0.9.12 patches.** Finish the character base (the accepted Quaternius 62-joint runtime),
|
||||
roll it out to the 12 roles, close the scheduled venue/prop/lighting polish, and verify
|
||||
performance, Web and accessibility.
|
||||
2. **0.10.0 minor.** Public readiness: external playtests, balance acceptance, legal/storefront
|
||||
approval, the platform matrix and the documentation/picture lock.
|
||||
3. **0.10.x patches → 0.11.0.** Content and systems depth: live body-camera replay, a fourth
|
||||
venue and the localization foundation.
|
||||
4. **0.12.0 → 1.0.0.** Platform/distribution, content complete, release candidates and the stable
|
||||
release.
|
||||
|
||||
Versions are assigned only when a track's scope is accepted into a release (see
|
||||
[Release Roadmap](#release-roadmap)). Unversioned tracks — the 3D review evidence base,
|
||||
maintenance and the Gaussian-splatting study — do not receive a placeholder version.
|
||||
|
||||
## Plan Evaluation (2026-11-05)
|
||||
|
||||
The game plan itself is sound and largely built: three venues, the escalation ladder, access
|
||||
artifacts, the radio/report system, the shift review and the campaign loop all exist and are
|
||||
tested. What needed fixing was the **delivery plan**, not the design.
|
||||
|
||||
- **Character sourcing churned.** The project moved procedural → MakeHuman → Quaternius, and the
|
||||
Quaternius Stage-1 warp failed its own gate. That leaves a correct decision (ADR-0018) with a
|
||||
half-finished implementation. The plan now makes the rig correction one small version, gates the
|
||||
roster behind a face/readability decision, and keeps exactly one fallback.
|
||||
- **One milestone carried too much.** The old 0.10.0 mixed character work, map work and every
|
||||
public-release gate, so one blocked export blocked the release. Character and venue polish are
|
||||
now patches; 0.10.0 is only the release gate.
|
||||
- **Unversioned work had no deadline.** The 3D review backlog could grow without bound. It is now
|
||||
capped: the ranked venue/prop/lighting items are scheduled into 0.9.11, the budget checks into
|
||||
0.9.12, and everything else is an explicit accept or deferred. Gaussian splatting stays
|
||||
unscheduled because no product need justifies its risk yet.
|
||||
- **Legal, signing and storefront work is release work, not polish.** It now has named checkboxes
|
||||
in 0.10.0 and 1.0.0 instead of living in prose.
|
||||
- **What is deliberately not planned:** new genres or mechanics, a live-service model, or a
|
||||
runtime splat renderer. The de-escalation-first, rare-emergency design stays frozen.
|
||||
|
||||
Feasibility: the remaining character work is small in geometry terms (6.2k triangles against a
|
||||
24k cap) and larger in rig/export terms; the venue work is polish; most release gates are
|
||||
evidence gathering rather than engineering. The main schedule risk is external review and
|
||||
approval, not code.
|
||||
|
||||
## Character Creation Re-Evaluation (2026-11-05)
|
||||
|
||||
**Where it stands.** The shipped library is 12 procedural Blender variants (4.7k–5.8k triangles
|
||||
each) with a sculpted face, five tint slots and 18 gear pieces. The owner then chose the CC0
|
||||
**Quaternius Ultimate Modular Characters** as the primary source. Stage 1 (warp the Quaternius
|
||||
mesh onto the 13-core contract) failed its silhouette gate — arm ×1.63, leg ×0.74, torso ×1.61,
|
||||
judged distorted. [ADR-0018](docs/adr/0018-quaternius-stage2-runtime-rig.md) therefore adopts the
|
||||
source **62-joint rig at runtime**: no warp, source LOD (3,199 verts / 6,206 tris), source
|
||||
Idle/Walk clips, and gear pivots re-derived from the Quaternius skeleton.
|
||||
|
||||
**What is already built.** The canonical `quaternius_base.glb` (welded, grounded, arm-down rest),
|
||||
the 62→13 joint map, the material→five-slot map, the clip inventory (24 clips; Idle and Walk in
|
||||
scope) and the `NpcAvatar` joint-name mapping with rest-derived gear pivots.
|
||||
|
||||
**What actually blocks it.** Two technical items about the export and the pose math, not the art:
|
||||
|
||||
1. the arm-down GLB renders in A-pose in Godot because the bake writes wrong inverse bind
|
||||
matrices; and
|
||||
2. `_pose_bone()` composes rotations as `rest * Quaternion(axis, angle)`, which only cancels for
|
||||
the old 180° rest, not the Quaternius ~76° rest.
|
||||
|
||||
**Re-evaluation findings.**
|
||||
|
||||
- Triangle budget is not the problem (6.2k against a 24k cap). Do not decimate the source.
|
||||
- **Face fidelity is the real risk.** The 0.9.7 library has a sculpted realistic face; the
|
||||
Quaternius head is low-poly. A blanket swap would regress every close-up. The plan therefore
|
||||
makes the owner choose at 0.9.9 between (a) a full swap, (b) Quaternius for crowd roles with the
|
||||
procedural library for named roles, or (c) extra head subdivision/hair cards on the Quaternius
|
||||
head.
|
||||
- **Animation** becomes clip-driven, which removes the hand-built pose composition as the main
|
||||
path. Poses the clips do not cover (seated, raise-hand, head turn) must be decided explicitly
|
||||
rather than patched per scene.
|
||||
- **One fallback, no third source.** The procedural `npc_base` and the MakeHuman head stay tested
|
||||
until the new base passes the gate. MPFB body work stays closed and the Stage-1 warp is not
|
||||
reopened. A new character source needs a new ADR.
|
||||
- **Sequence matters.** Fix the rig first (0.9.9), then the roster (0.9.10). Rolling a broken rig
|
||||
across 12 variants would waste the whole pass.
|
||||
|
||||
**Reversal condition.** If the skin cannot be exported correctly without a new exporter path, or
|
||||
if the owner rejects the low-poly face in every option, the plan falls back to the procedural
|
||||
library and retires Quaternius with a recorded ADR. That decision is made at 0.9.9, not later.
|
||||
|
||||
## Core Gameplay Loop
|
||||
|
||||
1. Watch the entrance, steps, queue, and sidewalk.
|
||||
@@ -96,15 +184,19 @@ A poor shift involves excessive force, confronting innocent people, ignoring a r
|
||||
|
||||
## Venues
|
||||
|
||||
### Hollywood Boulevard Building
|
||||
### El Capitan Entertainment Centre (6840 Hollywood Blvd)
|
||||
|
||||
The original scenario: a building entrance with steps, sidewalk, street lamps, and a restricted door. Tourists, performers, influencers, confused visitors, intoxicated pedestrians, trespassers, people in crisis, and rare violent threats approach from the boulevard.
|
||||
The original scenario: the historic Masonic Temple / El Capitan Entertainment Centre, with six Ionic columns, eight stone steps, the Hollywood Walk of Fame sidewalk, neighbouring theatre and retail frontage, and the four-lane boulevard. Tourists, performers, influencers, confused visitors, intoxicated pedestrians, trespassers, people in crisis, and rare violent threats approach from the street.
|
||||
|
||||
Authorized people are recognized or present a valid wristband. Wristbands vary by color, pattern, date, and event marking, and may be valid, expired, counterfeit, or missing.
|
||||
|
||||
### The Joke Shop
|
||||
|
||||
A comedy-club entrance. The door person checks IDs, tickets, reservations, guest-list status, and screens guests with a handheld wand under venue policy.
|
||||
A Sunset Strip comedy club inspired by The Comedy Store at 8433 Sunset Blvd: a
|
||||
low black hall under a deep, signature-covered canopy, a circular blade sign,
|
||||
red velvet curtains and the dry hillside rising behind it. The door person
|
||||
checks IDs, tickets, reservations, guest-list status, and screens guests with a
|
||||
handheld wand under venue policy.
|
||||
|
||||
The wand does **not** identify a weapon automatically. Keys, belts, and phones can trigger false alarms; the player must ask the guest to identify the item and apply procedure. A guest with valid credentials can still require assistance if they threaten staff or patrons.
|
||||
|
||||
@@ -123,7 +215,7 @@ Joke Shop escalation follows the common ladder: direction, explanation, repeat r
|
||||
|
||||
### 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.
|
||||
|
||||
@@ -148,18 +240,19 @@ The action wheel prioritizes de-escalation: Stop, Look, Point, No, Ask, Inspect,
|
||||
|
||||
The visual direction is readable stylized realism:
|
||||
|
||||
- **Blender library:** 8 skinned NPC variants, 18 gear pieces, and 20 street/venue props, with baked albedo/normal/AO/ORM maps, a manifest, and procedural fallbacks. `Rig/Head` stays the focus anchor.
|
||||
- **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.
|
||||
- **Character direction:** 12 skinned NPC variants, 18 gear pieces and 20 street/venue props. The active character track is the Quaternius base at runtime ([ADR-0018](docs/adr/0018-quaternius-stage2-runtime-rig.md)): the CC0 source mesh keeps its proportions on the 62-joint rig, Idle/Walk run as clips, and the procedural library stays as the tested fallback until the face/silhouette gate passes. See [Character Creation Re-Evaluation](#character-creation-re-evaluation-2026-11-05).
|
||||
- **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.
|
||||
- **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.
|
||||
|
||||
Remaining visual work is tracked in `TODO.md` (NPC fidelity and the two venue stages), not in this plan.
|
||||
The active planning order — unversioned character and local-map development first, then the versioned 0.10.0 release-candidate hardening and later releases — is tracked in [`TODO.md`](TODO.md); this plan stays at the product/design level.
|
||||
|
||||
Primary decisions: [ADR-0007](docs/adr/0007-locomotion-and-input-layers.md), [ADR-0008](docs/adr/0008-cone-focus-and-head-ring.md), [ADR-0009](docs/adr/0009-radial-action-menu.md), [ADR-0010](docs/adr/0010-procedural-npc-presentation.md), [ADR-0011](docs/adr/0011-aim-free-selection-and-precision-walk.md), [ADR-0012](docs/adr/0012-surface-materials-and-generated-props.md), [ADR-0013](docs/adr/0013-blender-authored-npc-characters.md).
|
||||
Primary decisions: [ADR-0007](docs/adr/0007-locomotion-and-input-layers.md), [ADR-0008](docs/adr/0008-cone-focus-and-head-ring.md), [ADR-0009](docs/adr/0009-radial-action-menu.md), [ADR-0010](docs/adr/0010-procedural-npc-presentation.md), [ADR-0011](docs/adr/0011-aim-free-selection-and-precision-walk.md), [ADR-0012](docs/adr/0012-surface-materials-and-generated-props.md), [ADR-0013](docs/adr/0013-blender-authored-npc-characters.md), [ADR-0015](docs/adr/0015-npc-model-variety-sourcing.md), [ADR-0017](docs/adr/0017-quaternius-npc-base.md).
|
||||
|
||||
## Tech Stack
|
||||
|
||||
- **Engine:** Godot 4.3, GL Compatibility renderer (Web parity).
|
||||
- **Engine:** Godot 4.7.2, GL Compatibility renderer (Web parity); optional Forward+ Desktop HQ build.
|
||||
- **Language:** GDScript.
|
||||
- **Architecture:** venue-driven simulation; shared systems plus `Resource`-based scenario data.
|
||||
- **Navigation:** `NavigationRegion3D` / `NavigationAgent3D`.
|
||||
@@ -172,7 +265,107 @@ Primary decisions: [ADR-0007](docs/adr/0007-locomotion-and-input-layers.md), [AD
|
||||
|
||||
## Versioning and Delivery
|
||||
|
||||
`config/version` in `project.godot` is the single version source (currently `0.7.2`). Releases are tagged `v<version>`; the CI pipeline builds and publishes the standard artifacts plus the optional Desktop HQ zip. Version bumps follow [Semantic Versioning](https://semver.org/). See [`docs/RELEASING.md`](docs/RELEASING.md) and [`README.md`](README.md) for commands.
|
||||
`config/version` in `project.godot` is the single version source (currently `0.9.9`). Releases are tagged `v<version>`; the CI pipeline builds and publishes the standard artifacts plus the optional Desktop HQ zip. Version bumps follow [Semantic Versioning](https://semver.org/): every major, minor and patch increment needs a changelog entry, a local `tools/build_releases.sh` build, and artifact/checksum verification before tagging. Unversioned development tracks do not receive a version until their scope enters a release. See [`docs/process/RELEASING.md`](docs/process/RELEASING.md) and [`README.md`](README.md) for commands.
|
||||
|
||||
## Gap Analysis
|
||||
|
||||
**Published baseline:** v0.9.8 (2026-11-04) — three playable venues, tutorial/campaign/checkpoint
|
||||
resume, the access/radio/escalation loop, shift review, the 12-character Blender library, 277
|
||||
Godot + 162 Python tests, a 21/21 screen-design judge and Compatibility/Web/Desktop HQ builds.
|
||||
|
||||
**Current source:** 0.9.8. The 0.10.0-rc.1 package built on 2026-11-03 is stale and is superseded
|
||||
by the patch sequence below; it is not a published release.
|
||||
|
||||
| Area | Remaining gap | Milestone |
|
||||
| --- | --- | --- |
|
||||
| Character base | Quaternius arm-down skin export, rest-relative pose composition, face/silhouette acceptance | 0.9.9 |
|
||||
| Character roster | 12-role mapping, modular outfits, gear fit, AO/texels, budget evidence | 0.9.10 |
|
||||
| Venue and asset polish | Ranked prop/foliage/lighting/set-dressing fixes, collider verification | 0.9.11 |
|
||||
| Performance and Web | Frame/memory/load evidence after the content changes, LOD/impostor verification | 0.9.12 |
|
||||
| Onboarding and balance | External first-time-player evidence, balance sweeps/tuning, content lock | 0.10.0 |
|
||||
| Accessibility and localization | Acceptance pass, caption coverage, pseudo-locale/length checks | 0.9.12 / 0.10.0 |
|
||||
| QA and release engineering | Full smoke matrix, clean build/checksum verification, target-matrix launches | 0.10.0 |
|
||||
| Legal, signing, storefront | macOS signing/notarization, AI-provider rights, storefront/rating approval, privacy sign-off | 0.10.0 / 0.12.0 |
|
||||
| Systems and content depth | Live incident replay, fourth venue, localization foundation | 0.11.0 |
|
||||
| Distribution | Signed storefront builds, frozen save contract, launch languages, hardware matrix | 0.12.0 |
|
||||
| Stable release | Content complete, accessibility audit, release candidates, 1.0.0 decision | 0.13.0 / 1.0.0 |
|
||||
| Future | More venues/seasonal content, image-to-mesh props, other deferred ideas | Unscheduled |
|
||||
|
||||
The 0.9.3 UI, 0.9.4 animation, 0.9.5 texture, 0.9.6 integration, 0.9.7 character development and
|
||||
0.9.8 deformation fixes are complete in [`DONE.md`](DONE.md); they are not remaining gaps. The
|
||||
2026-11-01 documentation audit is also closed.
|
||||
|
||||
## Release Roadmap
|
||||
|
||||
Every version below follows the release procedure in `AGENTS.md`. Patch versions contain fixes and
|
||||
polish; minor versions add user-facing features; the major version is the stable release with a
|
||||
compatibility promise. Each version's executable checklist is in [`TODO.md`](TODO.md).
|
||||
|
||||
### Roadmap to 0.10.0
|
||||
|
||||
The goal of this line is to finish the character and venue work and clear every public-release
|
||||
gate. The character track is versioned rather than unversioned so a blocked rig cannot hold the
|
||||
whole release.
|
||||
|
||||
| Version | Type | Scope | Exit criterion |
|
||||
| --- | --- | --- | --- |
|
||||
| 0.9.9 | patch | Quaternius pilot: correct skin export, rest-relative pose math, Idle/Walk verification, owner face/silhouette gate, one-role (or crowd-only) rollout | A Quaternius NPC renders and animates correctly and ships behind a tested procedural fallback |
|
||||
| 0.9.10 | patch | 12-role roster, modular outfits, five slots, AO/texels, gear fit, 12×6 baseline | The full roster passes contract, gear, budget and owner-baseline gates |
|
||||
| 0.9.11 | patch | Scheduled 3D review fixes: props/foliage, gear silhouette, venue shape language, lighting, set dressing, colliders | Every scheduled P1/P2 item is fixed or accepted with a measurement |
|
||||
| 0.9.12 | patch | Performance/Web/LOD/memory verification plus accessibility and pseudo-locale checks | No regression against the pre-character baselines |
|
||||
| 0.10.0 | minor | Public readiness: external playtests, balance acceptance, legal/storefront/signing decisions, platform matrix, docs and picture lock | 0.10.0 is content-locked, externally played, legally reviewed, documented and reproducibly built |
|
||||
|
||||
### Roadmap to 0.11.0
|
||||
|
||||
This line turns a stable 0.10.x into a deeper game: the incident timeline becomes a live replay, a
|
||||
fourth venue enters the campaign, and the text catalogue becomes a real localization pipeline.
|
||||
|
||||
| Version | Type | Scope | Exit criterion |
|
||||
| --- | --- | --- | --- |
|
||||
| 0.10.1 | patch | Onboarding and accessibility issues deferred from the 0.10.0 playtests | First-hour and accessibility defects closed |
|
||||
| 0.10.2 | patch | Balance/fairness sweeps, review-text and difficulty-progression tuning | Every balance-acceptance cell is in target or explicitly accepted |
|
||||
| 0.10.3 | patch | Save/checkpoint edge cases, gamepad/remap, pause/resume, small quality-of-life fixes | No known P1 stability defect remains |
|
||||
| 0.11.0 | minor | Live body-camera replay, fourth venue (candidate: TCL Chinese Theatre forecourt), localization foundation with one secondary language | The new systems ship without regressing performance, accessibility or balance |
|
||||
|
||||
### Roadmap to 1.0.0
|
||||
|
||||
This line is about distribution, contracts and completeness: signed builds on the launch stores, a
|
||||
frozen save format, finished content and release candidates.
|
||||
|
||||
| Version | Type | Scope | Exit criterion |
|
||||
| --- | --- | --- | --- |
|
||||
| 0.11.1 | patch | Replay/venue/localization fixes from wider play | No P1 defect in the 0.11.0 feature set |
|
||||
| 0.11.2 | patch | New-venue balance, campaign pacing and content readability | The 0.11.x line is stable enough to freeze its contracts |
|
||||
| 0.12.0 | minor | macOS signing/notarization, storefront packages/metadata/ratings, save-format v2 freeze, hardware matrix, launch languages | Signed, storefront-ready builds exist on every launch platform |
|
||||
| 0.12.1 | patch | Signing, installer, metadata and save-migration fixes from storefront dry runs | Every storefront build installs, launches and migrates cleanly |
|
||||
| 0.13.0 | minor | Content complete: all planned venues/events/dialogue, audio decision, final tutorial, accessibility audit, balance freeze | All planned content is implemented and frozen |
|
||||
| 0.13.1 | patch | Release candidate 1: full smoke/performance/save/accessibility matrix | A candidate passes every gate except final approval |
|
||||
| 0.13.2 | patch | Release candidate 2: verify fixes, freeze release notes/credits/privacy/known limitations | The final candidate is reproducible and documented |
|
||||
| 1.0.0 | major | Stable release: legal/storefront/rating approval, hardware/accessibility/localization sign-off, no P0/P1, publish on every platform | 1.0.0 is published with verified checksums and no open blocker |
|
||||
|
||||
## Roadmap Dependencies and Risks
|
||||
|
||||
- Content volume is the largest schedule risk; tutorial and campaign work must not outrun the
|
||||
event/dialogue matrix.
|
||||
- The vision judge is a dev-time aid with an external key and budget; CI must never make it a hard
|
||||
gate.
|
||||
- Godot engine changes can alter lighting and imports; do not combine an engine baseline move with
|
||||
a content or feature milestone.
|
||||
- Signed macOS builds, AI provenance and storefront approval are release blockers, not polish.
|
||||
- The character pipeline is the current critical path. The rig/export fix must be proven on one
|
||||
variant before the roster rollout; otherwise 0.9.10 multiplies a defect.
|
||||
- Photo-derived map assets add a provenance risk: downloaded or user-supplied photos can carry
|
||||
unclear licences, identifiable people, plates and property restrictions. No photo- or
|
||||
splat-derived asset ships without a completed sidecar, consent/licence review and redaction.
|
||||
- Gaussian-splat training is GPU/disk-heavy and the toolchain churns; keep it offline,
|
||||
version-pinned and outside CI, and never make a runtime splat renderer a release dependency.
|
||||
- The Blender skill pack is local, unversioned guidance; it can drift from the project contract or
|
||||
assume Blender MCP. Re-verify every adopted technique with `inspect`/`audit`/`fit` and never make
|
||||
a skill, asset pack or tool version a build or CI dependency.
|
||||
- The 3D re-evaluation can expand without bound. Cap it with the scorecard ranking: P0/P1 only, one
|
||||
asset family per commit, and an explicit accept for everything else.
|
||||
- Keep the de-escalation-first rules and rare-emergency design unchanged while adding progression,
|
||||
difficulty and feedback.
|
||||
|
||||
## Design Direction
|
||||
|
||||
@@ -184,4 +377,5 @@ The game should feel like a tense workplace simulation with occasional crisis mo
|
||||
|
||||
- A rare Bob Dobbs cameo (Easter-egg appearance; placement note in `MEMORY.md`).
|
||||
- Specific unusual NPC behaviors, such as slapping their own face, using hands as scissors, or interacting with props unexpectedly.
|
||||
- Live 3D body-camera replay; additional venues or seasonal events; real voice/dialogue audio; an image-to-mesh prop pipeline.
|
||||
- A fifth venue or seasonal events after the 0.11.0 fourth venue proves the venue pipeline.
|
||||
- Real voice/dialogue audio if the 0.13.0 audio decision does not fund it; an image-to-mesh prop pipeline remains unscheduled.
|
||||
@@ -0,0 +1,27 @@
|
||||
# Privacy Note
|
||||
|
||||
Gig Line runs locally. The game itself does not include telemetry, analytics,
|
||||
accounts, advertising, cloud saves or network requests. It does not access the
|
||||
camera, microphone, contacts or location, and the body-camera feature is a
|
||||
simulated overlay, not a real recording device.
|
||||
|
||||
Player data is written only to Godot's local `user://` directory:
|
||||
|
||||
- `settings.json`
|
||||
- `campaign.json`
|
||||
- `shift_results.json`
|
||||
- `shift_state.json`
|
||||
|
||||
Those files stay on the player's machine unless the player copies them. Deleting
|
||||
the files (or the `Gig Line` user directory) resets the profile. See
|
||||
[`docs/process/getting-started.md`](docs/process/getting-started.md#save-data) for
|
||||
locations, migration and rollback instructions.
|
||||
|
||||
The repository's development tools can call OpenRouter when a developer supplies
|
||||
`OPENROUTER_API_KEY`; those calls generate or judge development assets and are
|
||||
not part of the shipped game. The key and generated review artifacts remain
|
||||
local/gitignored.
|
||||
|
||||
Questions about a storefront release should be checked against the final package
|
||||
and the provider terms recorded in [`CREDITS.md`](CREDITS.md); external legal and
|
||||
storefront approval is still pending for 0.10.0.
|
||||
@@ -6,20 +6,16 @@ The central design goal is simple:
|
||||
|
||||
> The player wins by choosing the lowest level of escalation that keeps everyone safe.
|
||||
|
||||
## Screenshots
|
||||
## Development Priorities
|
||||
|
||||
| | |
|
||||
| --- | --- |
|
||||
|  |  |
|
||||
|  |  |
|
||||
|  |  |
|
||||
|  |  |
|
||||
|  |  |
|
||||
|  |  |
|
||||
|  | |
|
||||
The active planning order lives in [`PLAN.md`](PLAN.md) (gap analysis and release roadmap), [`TODO.md`](TODO.md) (executable checklist) and [`AGENTS.md`](AGENTS.md):
|
||||
|
||||
*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 alley, the TV Studio arrival, and the prop lineup.*
|
||||
1. **`0.9.9`–`0.9.12` patches** — finish the Quaternius NPC base on the accepted 62-joint runtime, roll it out to the 12 roles, close the scheduled venue/prop/lighting polish, then verify performance, Web and accessibility.
|
||||
2. **`0.10.0` minor** — public readiness: external playtests, balance acceptance, legal/storefront/signing decisions, the platform matrix and the documentation/picture lock.
|
||||
3. **`0.10.x` → `0.11.0`** — live incident replay, a fourth venue and the localization foundation.
|
||||
4. **`0.12.0` → `1.0.0`** — signed storefront builds, a frozen save contract, content complete, release candidates and the stable release.
|
||||
|
||||
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.
|
||||
|
||||
## ⬇️ Downloads
|
||||
|
||||
@@ -31,37 +27,102 @@ precision walk, the Joke Shop alley, the TV Studio arrival, and the prop lineup.
|
||||
| **Linux — portable** | [`gig-line-linux-<ver>.x86_64`](https://git.allucanget.biz/zwitschi/security-game/releases) · 64-bit, `chmod +x` and run |
|
||||
| **macOS** | [`gig-line-macos-<ver>.zip`](https://git.allucanget.biz/zwitschi/security-game/releases) · unsigned build, quarantine note below |
|
||||
| **Web (browser)** | [`gig-line-web-<ver>.zip`](https://git.allucanget.biz/zwitschi/security-game/releases) · unzip and serve the folder from any static host (no special headers) |
|
||||
| **Desktop HQ** | [`gig-line-desktop-hq-<ver>.zip`](https://git.allucanget.biz/zwitschi/security-game/releases) · optional Forward+ build with volumetric fog/SDFGI/flashlight; requires a Vulkan-capable GPU/driver |
|
||||
|
||||
**All releases:** <https://git.allucanget.biz/zwitschi/security-game/releases>
|
||||
|
||||
> Downloads are public (no sign-in required) since the host's instance-wide
|
||||
> `REQUIRE_SIGNIN_VIEW` was disabled on 2026-10-31.
|
||||
>
|
||||
> **Latest: v0.7.0** — distinct Joke Shop and TV Studio geometry, fitted NPC gear,
|
||||
> and the post-v0.6.0 realism/visual-alignment work (v2 skylines/textures, UI mockup
|
||||
> art, flashlight beam, HUD fixes).
|
||||
> **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,
|
||||
> texture/material refinement and integration checkpoint.
|
||||
>
|
||||
> **Current source: v0.9.8** — tagged from the same commit. The 0.10.0
|
||||
> development track remains gated on the Quaternius NPC rollout, local-map work
|
||||
> and release approvals.
|
||||
> Releases are built automatically when a `vX.Y.Z` tag is pushed
|
||||
> (see [`docs/RELEASING.md`](docs/RELEASING.md)); manual builds use
|
||||
> (see [`docs/process/RELEASING.md`](docs/process/RELEASING.md)); manual builds use
|
||||
> `./tools/build_releases.sh`. Installer/AppImage packaging runs in the same pipeline
|
||||
> (NSIS + appimagetool) and uploads with the portable binaries.
|
||||
>
|
||||
> macOS builds are unsigned: right-click → Open, or clear the quarantine with
|
||||
> `xattr -dr com.apple.quarantine gig-line-macos.zip`. Build instructions and
|
||||
> the release pipeline live in [`docs/RELEASING.md`](docs/RELEASING.md).
|
||||
> the release pipeline live in [`docs/process/RELEASING.md`](docs/process/RELEASING.md).
|
||||
|
||||
If you are here to develop or test locally instead of downloading, jump to
|
||||
[Setup and Run](#setup-and-run) below.
|
||||
|
||||
The project is under active development. The design and architecture are documented, and a playable prototype vertical slice exists (Godot 4 + GDScript): a procedural Hollywood Boulevard entrance, 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.** The El Capitan Entertainment Centre block: six Ionic columns, Masonic parapet, event banners, eight stone steps and the Walk of Fame terrazzo. |
|
||||
|  | **Hollywood Boulevard — late.** Sconces pool on the limestone, street lamps light the boulevard and the skyline fades into night haze. |
|
||||
|  | **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.** A black Sunset Strip club under its signature-covered canopy, circular blade sign, red curtains and the dry hillside behind. |
|
||||
|  | **TV Studio arrival.** Stone facade, bulb canopy, black car and crowd barriers for a late celebrity arrival. |
|
||||
|
||||
### Interaction and systems
|
||||
|
||||
| | |
|
||||
| --- | --- |
|
||||
|  | **Focus and targeting.** The cone focus ring, name tag and target chip; `Tab`/wheel cycles nearby people without aiming. |
|
||||
|  | **Access inspection.** A venue-correct wristband check with evidence shown before the admit/refuse decision. |
|
||||
|  | **Radio report.** Security assistance with location, behaviour and what was actually seen. |
|
||||
|  | **Wand screening.** A false alarm on keys: ask the guest to identify the item before choosing a response. |
|
||||
|  | **Escalation.** Level 3 blocking with the shape meter, body camera armed and the reaction log. |
|
||||
|  | **Body-camera timeline.** Every recorded event, step by step, in the shift review. |
|
||||
|  | **Precision walk.** Half-speed close work on the steps, with the HUD state chip visible. |
|
||||
|
||||
### Shell and UI
|
||||
|
||||
| | |
|
||||
| --- | --- |
|
||||
|  | **Venue menu.** Day and night rows for Hollywood, the Joke Shop and the TV Studio, campaign continue and review links. |
|
||||
|  | **Settings.** Difficulty, volumes, HUD scale, reduce motion, captions and key/button remapping, all persisted. |
|
||||
|  | **Shift review.** Grade, policy outcome, incidents, responder results and campaign Continue. |
|
||||
|  | **Action wheel.** De-escalation first: stop, look, point, no, ask, inspect, warn, block, reason, recognize, radio. |
|
||||
|
||||
### 3D asset progress
|
||||
|
||||
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.
|
||||
|
||||
| | |
|
||||
| --- | --- |
|
||||
|  | **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. |
|
||||
|  | **Street and venue props.** Twenty library props with colliders, navigation avoidance and colour atlases. |
|
||||
|  | **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.** 128 → 256 px NPC maps and a 4× fabric weave, shown before/after on the same camera. |
|
||||
|  | **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/assets/3d-model-review.md`](docs/assets/3d-model-review.md).
|
||||
|
||||
## Game Overview
|
||||
|
||||
A typical shift lasts 10–15 minutes: watch the entrance and sidewalk, judge why
|
||||
each person is approaching, verify access with recognition, wristbands, IDs,
|
||||
tickets or credentials, and escalate only when necessary. The game rewards calm
|
||||
resolution over force. The full mechanics — the three venues, the six-level
|
||||
resolution over force. The venue menu splits Hollywood Boulevard into Day and
|
||||
Night rows; the full mechanics — the three venues, the six-level
|
||||
escalation model, and the core systems — are in
|
||||
[`docs/gameplay.md`](docs/gameplay.md); the design rationale lives in
|
||||
[`docs/design/gameplay.md`](docs/design/gameplay.md); the design rationale lives in
|
||||
[`PLAN.md`](PLAN.md).
|
||||
|
||||
## Architecture
|
||||
@@ -69,13 +130,13 @@ escalation model, and the core systems — are in
|
||||
A venue-driven simulation: shared systems (movement, perception, interaction,
|
||||
access verification, escalation, radio, crowd, reputation, evidence, shift
|
||||
review) driven by per-venue scenario data, on Godot 4 + GDScript. The full
|
||||
arc42-style document is [`docs/architecture.md`](docs/architecture.md);
|
||||
decisions are recorded as ADRs in [`docs/adr/`](docs/adr/).
|
||||
arc42-style document is [`docs/project/architecture.md`](docs/project/architecture.md);
|
||||
decisions are recorded as ADRs in [`docs/adr/`](docs/adr).
|
||||
|
||||
## Tech Stack
|
||||
|
||||
- **Engine:** Godot 4.x · **Language:** GDScript
|
||||
- **NPCs:** Blender-authored skinned library (`assets/models/blender/`) with procedural fallbacks; lightweight FSMs on `NpcProfile`
|
||||
- **Engine:** Godot 4.7.2 · **Language:** GDScript
|
||||
- **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`
|
||||
@@ -83,7 +144,7 @@ decisions are recorded as ADRs in [`docs/adr/`](docs/adr/).
|
||||
- **Targets:** Windows, Linux, macOS, Web
|
||||
|
||||
The asset pipelines, model tools, and screenshot gates are documented in
|
||||
[`docs/asset-tooling.md`](docs/asset-tooling.md).
|
||||
[`docs/assets/asset-tooling.md`](docs/assets/asset-tooling.md).
|
||||
|
||||
## Setup and Run
|
||||
|
||||
@@ -96,34 +157,60 @@ godot --headless --path . --script res://src/test/test_runner.gd # run all tes
|
||||
```
|
||||
|
||||
Full setup, every run/test/smoke command, and the controls table are in
|
||||
[`docs/getting-started.md`](docs/getting-started.md).
|
||||
[`docs/process/getting-started.md`](docs/process/getting-started.md).
|
||||
|
||||
## Project Documentation
|
||||
|
||||
- [`PLAN.md`](PLAN.md) — Game design plan and scenario details.
|
||||
- [`AGENTS.md`](AGENTS.md) — Development and collaboration workflow.
|
||||
- [`TODO.md`](TODO.md) — Active checkbox task list.
|
||||
- [`PLAN.md`](PLAN.md) — Game design plan, development priorities and scenario details.
|
||||
- [`TODO.md`](TODO.md) — Priority-ordered tasks: character and local-map development, release milestones, and future work.
|
||||
- [`docs/README.md`](docs/README.md) — Documentation index, current priorities and visual previews.
|
||||
- [`docs/assets/npc-model-sourcing.md`](docs/assets/npc-model-sourcing.md) — Character-source evaluation, licence rules and the character-development plan.
|
||||
- [`docs/assets/makehuman-head-review.md`](docs/assets/makehuman-head-review.md) — Local MakeHuman head prototype, provenance and review verdict.
|
||||
- [`AGENTS.md`](AGENTS.md) — Development, commit, build and collaboration workflow.
|
||||
- [`DONE.md`](DONE.md) — Completed task sections.
|
||||
- [`MEMORY.md`](MEMORY.md) — Persistent session notes.
|
||||
- [`CHANGELOG.md`](CHANGELOG.md) — User-facing changes by version.
|
||||
- [`docs/architecture.md`](docs/architecture.md) — arc42-style architecture documentation.
|
||||
- [`docs/gameplay.md`](docs/gameplay.md) — Gameplay systems, venues, and the escalation model.
|
||||
- [`docs/asset-tooling.md`](docs/asset-tooling.md) — Asset pipelines, model tools, and screenshot gates.
|
||||
- [`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/smoke-checklist.md`](docs/smoke-checklist.md) — Manual smoke-test checklist.
|
||||
- [`docs/blender-assets.md`](docs/blender-assets.md) — Blender asset library: characters, gear, props, attach points.
|
||||
- [`docs/adr/`](docs/adr/) — Architecture Decision Records.
|
||||
- [`docs/plan-graphics-v0.6.md`](docs/plan-graphics-v0.6.md) — Graphics-quality plan: Blender-authored NPC characters.
|
||||
- [`docs/project/architecture.md`](docs/project/architecture.md) — arc42-style architecture documentation.
|
||||
- [`docs/design/gameplay.md`](docs/design/gameplay.md) — Gameplay systems, venues, and the escalation model.
|
||||
- [`docs/design/venues.md`](docs/design/venues.md) — Real-site references, game mapping and limitations for Hollywood, the Joke Shop and the TV Studio.
|
||||
- [`docs/assets/asset-tooling.md`](docs/assets/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/process/getting-started.md`](docs/process/getting-started.md) — Setup, run/test commands, and controls.
|
||||
- [`docs/project/development-status.md`](docs/project/development-status.md) — Implemented features and what's next.
|
||||
- [`docs/design/accessibility.md`](docs/design/accessibility.md) — Accessibility features, known gaps and statement.
|
||||
- [`docs/design/known-limitations.md`](docs/design/known-limitations.md) — Release-candidate blockers and accepted limitations.
|
||||
- [`docs/process/release-qa.md`](docs/process/release-qa.md) — Manual smoke checklist and release-candidate balance protocol.
|
||||
- [`CREDITS.md`](CREDITS.md) — Credits, AI/reference provenance and licensing notes.
|
||||
- [`PRIVACY.md`](PRIVACY.md) — Local-only data, save files and development API use.
|
||||
- [`docs/assets/blender-assets.md`](docs/assets/blender-assets.md) — Blender asset library: characters, gear, props, attach points.
|
||||
- [`docs/assets/npc-model-sourcing.md`](docs/assets/npc-model-sourcing.md) — character sources, the shipped roster table and the build steps; 0.9.5 texture comparison is in [`docs/blender_previews/sheet_texture_refinement_0.9.5.jpg`](docs/blender_previews/sheet_texture_refinement_0.9.5.jpg).
|
||||
- [`docs/adr/`](docs/adr) — Architecture Decision Records.
|
||||
|
||||
## Development Status
|
||||
|
||||
v0.7.0 shipped distinct venue geometry: the Joke Shop alley and TV Studio
|
||||
entrance no longer share the Hollywood layout. It builds on v0.6.1's fitted NPC
|
||||
gear and v0.6.0's Blender asset library, baked AO and environment lift. See
|
||||
[`docs/development-status.md`](docs/development-status.md) for the full
|
||||
implemented list and [`TODO.md`](TODO.md) for what's next. Manual verification
|
||||
uses the [`docs/smoke-checklist.md`](docs/smoke-checklist.md).
|
||||
v0.9.8 is the current source version: the character-development patch with the
|
||||
12-character library, realistic face and crowd variants, pose/deformation fixes
|
||||
and save-migration/release hardening. It sits on the 0.9.6 integration
|
||||
checkpoint, 0.9.5 texture refinement, 0.9.4 NPC visual optimization, 0.9.3
|
||||
UI/accessibility polish, 0.9.2 Hollywood/Joke Shop maps and the 0.9.x engine
|
||||
baseline. The active work is the `0.9.9`–`0.9.12` patch line (Quaternius NPC
|
||||
base, roster, venue/asset polish, performance) followed by the `0.10.0`
|
||||
public-readiness minor. See
|
||||
[`docs/project/development-status.md`](docs/project/development-status.md) for the implemented list
|
||||
and [`TODO.md`](TODO.md) for the priority-ordered roadmap. Manual verification uses
|
||||
[`docs/process/release-qa.md`](docs/process/release-qa.md).
|
||||
|
||||
## Credits, Privacy and Accessibility
|
||||
|
||||
Gig Line is a local-only single-player game: there is no runtime telemetry or
|
||||
network service, and saves stay in Godot's local `user://` folder. The
|
||||
body-camera overlay is simulated. Asset provenance, AI-assisted image usage and
|
||||
credits are recorded in [`CREDITS.md`](CREDITS.md); the local-data policy is in
|
||||
[`PRIVACY.md`](PRIVACY.md); accessibility features and gaps are in
|
||||
[`docs/design/accessibility.md`](docs/design/accessibility.md); and release-candidate blockers
|
||||
are listed in [`docs/design/known-limitations.md`](docs/design/known-limitations.md).
|
||||
|
||||
## Development Workflow
|
||||
|
||||
|
||||
@@ -29,8 +29,8 @@
|
||||
"bounds_godot": {
|
||||
"max": [
|
||||
0.15,
|
||||
0.3,
|
||||
0.141
|
||||
0.296,
|
||||
0.172
|
||||
],
|
||||
"min": [
|
||||
-0.15,
|
||||
@@ -42,33 +42,11 @@
|
||||
"materials": [
|
||||
"pack_nylon",
|
||||
"steel",
|
||||
"plastic_black"
|
||||
"denim_bag"
|
||||
],
|
||||
"path": "assets/models/blender/npc_gear/backpack.glb",
|
||||
"triangles": 316,
|
||||
"vertices": 360
|
||||
},
|
||||
"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
|
||||
"triangles": 380,
|
||||
"vertices": 410
|
||||
},
|
||||
"bench": {
|
||||
"bounds_godot": {
|
||||
@@ -96,14 +74,14 @@
|
||||
"bollard": {
|
||||
"bounds_godot": {
|
||||
"max": [
|
||||
0.105,
|
||||
0.125,
|
||||
0.975,
|
||||
0.105
|
||||
0.125
|
||||
],
|
||||
"min": [
|
||||
-0.105,
|
||||
-0.125,
|
||||
0,
|
||||
-0.105
|
||||
-0.125
|
||||
]
|
||||
},
|
||||
"category": "props",
|
||||
@@ -114,20 +92,20 @@
|
||||
"path": "assets/models/blender/props/bollard.glb",
|
||||
"replaces": "generated/bollard.glb",
|
||||
"triangles": 138,
|
||||
"vertices": 225
|
||||
"vertices": 221
|
||||
},
|
||||
"camera": {
|
||||
"attach": "hand",
|
||||
"bounds_godot": {
|
||||
"max": [
|
||||
0.106,
|
||||
0.376,
|
||||
0.065,
|
||||
0.06,
|
||||
0.143
|
||||
],
|
||||
"min": [
|
||||
-0.106,
|
||||
-0.065,
|
||||
-0.053,
|
||||
-0.055
|
||||
0.005
|
||||
]
|
||||
},
|
||||
"category": "npc_gear",
|
||||
@@ -136,42 +114,20 @@
|
||||
"lens"
|
||||
],
|
||||
"path": "assets/models/blender/npc_gear/camera.glb",
|
||||
"triangles": 318,
|
||||
"vertices": 406
|
||||
},
|
||||
"cap": {
|
||||
"attach": "head",
|
||||
"bounds_godot": {
|
||||
"max": [
|
||||
0.168,
|
||||
0.209,
|
||||
0.258
|
||||
],
|
||||
"min": [
|
||||
-0.168,
|
||||
0.037,
|
||||
-0.186
|
||||
]
|
||||
},
|
||||
"category": "npc_gear",
|
||||
"materials": [
|
||||
"plastic_black"
|
||||
],
|
||||
"path": "assets/models/blender/npc_gear/cap.glb",
|
||||
"triangles": 328,
|
||||
"vertices": 285
|
||||
"triangles": 312,
|
||||
"vertices": 422
|
||||
},
|
||||
"clipboard": {
|
||||
"attach": "hand",
|
||||
"bounds_godot": {
|
||||
"max": [
|
||||
0.115,
|
||||
0.05,
|
||||
0.11,
|
||||
-0.07,
|
||||
0.053
|
||||
],
|
||||
"min": [
|
||||
-0.115,
|
||||
-0.265,
|
||||
-0.11,
|
||||
-0.375,
|
||||
0.036
|
||||
]
|
||||
},
|
||||
@@ -188,12 +144,12 @@
|
||||
"crowd_barrier": {
|
||||
"bounds_godot": {
|
||||
"max": [
|
||||
1.116,
|
||||
1.066,
|
||||
1.12,
|
||||
1.07,
|
||||
0.307
|
||||
],
|
||||
"min": [
|
||||
-1.122,
|
||||
-1.128,
|
||||
-0.014,
|
||||
-0.307
|
||||
]
|
||||
@@ -262,14 +218,14 @@
|
||||
"fire_hydrant": {
|
||||
"bounds_godot": {
|
||||
"max": [
|
||||
0.24,
|
||||
0.76,
|
||||
0.19
|
||||
0.265,
|
||||
0.815,
|
||||
0.235
|
||||
],
|
||||
"min": [
|
||||
-0.24,
|
||||
-0.265,
|
||||
0,
|
||||
-0.19
|
||||
-0.235
|
||||
]
|
||||
},
|
||||
"category": "props",
|
||||
@@ -279,21 +235,21 @@
|
||||
],
|
||||
"path": "assets/models/blender/props/fire_hydrant.glb",
|
||||
"replaces": "generated/fire_hydrant.glb",
|
||||
"triangles": 466,
|
||||
"vertices": 725
|
||||
"triangles": 610,
|
||||
"vertices": 902
|
||||
},
|
||||
"firefighter_helmet": {
|
||||
"attach": "head",
|
||||
"bounds_godot": {
|
||||
"max": [
|
||||
0.166,
|
||||
0.26,
|
||||
0.245,
|
||||
0.26
|
||||
0.166
|
||||
],
|
||||
"min": [
|
||||
-0.26,
|
||||
0.035,
|
||||
-0.351
|
||||
-0.166,
|
||||
0.125,
|
||||
-0.225
|
||||
]
|
||||
},
|
||||
"category": "npc_gear",
|
||||
@@ -351,28 +307,6 @@
|
||||
"triangles": 268,
|
||||
"vertices": 400
|
||||
},
|
||||
"hood": {
|
||||
"attach": "head",
|
||||
"bounds_godot": {
|
||||
"max": [
|
||||
0.184,
|
||||
0.236,
|
||||
0.123
|
||||
],
|
||||
"min": [
|
||||
-0.184,
|
||||
-0.146,
|
||||
-0.225
|
||||
]
|
||||
},
|
||||
"category": "npc_gear",
|
||||
"materials": [
|
||||
"plastic_grey"
|
||||
],
|
||||
"path": "assets/models/blender/npc_gear/hood.glb",
|
||||
"triangles": 804,
|
||||
"vertices": 649
|
||||
},
|
||||
"lanyard": {
|
||||
"attach": "chest",
|
||||
"bounds_godot": {
|
||||
@@ -439,26 +373,28 @@
|
||||
"category": "props",
|
||||
"materials": [
|
||||
"news_blue",
|
||||
"dark_metal",
|
||||
"glass",
|
||||
"paper",
|
||||
"steel"
|
||||
],
|
||||
"path": "assets/models/blender/props/newspaper_box.glb",
|
||||
"replaces": "generated/newspaper_box.glb",
|
||||
"triangles": 244,
|
||||
"vertices": 528
|
||||
"triangles": 300,
|
||||
"vertices": 648
|
||||
},
|
||||
"npc_casual": {
|
||||
"base": "hoodie",
|
||||
"bounds_godot": {
|
||||
"max": [
|
||||
0.321,
|
||||
1.824,
|
||||
0.185
|
||||
0.262,
|
||||
1.866,
|
||||
0.287
|
||||
],
|
||||
"min": [
|
||||
-0.321,
|
||||
0,
|
||||
-0.178
|
||||
-0.262,
|
||||
-0.004,
|
||||
-0.091
|
||||
]
|
||||
},
|
||||
"category": "npc",
|
||||
@@ -466,11 +402,13 @@
|
||||
"materials": [
|
||||
"skin",
|
||||
"cloth",
|
||||
"pants",
|
||||
"eye_white",
|
||||
"accessory",
|
||||
"Eyebrows",
|
||||
"sclera",
|
||||
"hair",
|
||||
"rubber"
|
||||
"pants",
|
||||
"mouth",
|
||||
"pupil"
|
||||
],
|
||||
"mesh_node": "npc_base",
|
||||
"path": "assets/models/blender/npc/npc_casual.glb",
|
||||
@@ -487,32 +425,36 @@
|
||||
"accessory",
|
||||
"hair"
|
||||
],
|
||||
"triangles": 3974,
|
||||
"vertices": 3744
|
||||
"triangles": 6242,
|
||||
"vertices": 13100
|
||||
},
|
||||
"npc_coat": {
|
||||
"base": "suit",
|
||||
"bounds_godot": {
|
||||
"max": [
|
||||
0.332,
|
||||
1.824,
|
||||
0.185
|
||||
0.255,
|
||||
1.809,
|
||||
0.279
|
||||
],
|
||||
"min": [
|
||||
-0.332,
|
||||
0,
|
||||
-0.18
|
||||
-0.255,
|
||||
-0.001,
|
||||
-0.083
|
||||
]
|
||||
},
|
||||
"category": "npc",
|
||||
"layer": "coat",
|
||||
"materials": [
|
||||
"skin",
|
||||
"Tie",
|
||||
"cloth",
|
||||
"pants",
|
||||
"eye_white",
|
||||
"White",
|
||||
"accessory",
|
||||
"Eyebrows",
|
||||
"hair",
|
||||
"rubber"
|
||||
"sclera",
|
||||
"pants",
|
||||
"pupil"
|
||||
],
|
||||
"mesh_node": "npc_base",
|
||||
"path": "assets/models/blender/npc/npc_coat.glb",
|
||||
@@ -528,32 +470,220 @@
|
||||
"accessory",
|
||||
"hair"
|
||||
],
|
||||
"triangles": 5026,
|
||||
"vertices": 4807
|
||||
"triangles": 6582,
|
||||
"vertices": 13607
|
||||
},
|
||||
"npc_dress": {
|
||||
"npc_crowd_a": {
|
||||
"base": "beach",
|
||||
"bounds_godot": {
|
||||
"max": [
|
||||
0.288,
|
||||
1.825,
|
||||
0.208
|
||||
0.252,
|
||||
1.805,
|
||||
0.277
|
||||
],
|
||||
"min": [
|
||||
-0.288,
|
||||
0,
|
||||
-0.208
|
||||
-0.252,
|
||||
-0.005,
|
||||
-0.088
|
||||
]
|
||||
},
|
||||
"category": "npc",
|
||||
"layer": "none",
|
||||
"materials": [
|
||||
"skin",
|
||||
"cloth",
|
||||
"accessory",
|
||||
"Eyebrows",
|
||||
"sclera",
|
||||
"hair",
|
||||
"Earrings",
|
||||
"pants",
|
||||
"pupil"
|
||||
],
|
||||
"mesh_node": "npc_base",
|
||||
"path": "assets/models/blender/npc/npc_crowd_a.glb",
|
||||
"roles": [
|
||||
"tourist",
|
||||
"guest"
|
||||
],
|
||||
"tint_slots": [
|
||||
"skin",
|
||||
"cloth",
|
||||
"pants",
|
||||
"accessory",
|
||||
"hair"
|
||||
],
|
||||
"triangles": 6602,
|
||||
"vertices": 13557
|
||||
},
|
||||
"npc_crowd_b": {
|
||||
"base": "farmer",
|
||||
"bounds_godot": {
|
||||
"max": [
|
||||
0.256,
|
||||
1.81,
|
||||
0.28
|
||||
],
|
||||
"min": [
|
||||
-0.256,
|
||||
-0.0,
|
||||
-0.11
|
||||
]
|
||||
},
|
||||
"category": "npc",
|
||||
"layer": "none",
|
||||
"materials": [
|
||||
"skin",
|
||||
"LightBlue",
|
||||
"cloth",
|
||||
"Beige",
|
||||
"accessory",
|
||||
"Eyebrows",
|
||||
"Beige.001",
|
||||
"Red",
|
||||
"sclera",
|
||||
"pants",
|
||||
"pupil",
|
||||
"hair"
|
||||
],
|
||||
"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": 5512,
|
||||
"vertices": 11291
|
||||
},
|
||||
"npc_crowd_c": {
|
||||
"base": "adventurer",
|
||||
"bounds_godot": {
|
||||
"max": [
|
||||
0.255,
|
||||
1.809,
|
||||
0.279
|
||||
],
|
||||
"min": [
|
||||
-0.255,
|
||||
-0.001,
|
||||
-0.256
|
||||
]
|
||||
},
|
||||
"category": "npc",
|
||||
"layer": "coat",
|
||||
"materials": [
|
||||
"Brown",
|
||||
"LightGreen",
|
||||
"Gold",
|
||||
"Green",
|
||||
"skin",
|
||||
"Tie",
|
||||
"cloth",
|
||||
"White",
|
||||
"accessory",
|
||||
"Eyebrows",
|
||||
"hair",
|
||||
"sclera",
|
||||
"pants",
|
||||
"pupil"
|
||||
],
|
||||
"mesh_node": "npc_base",
|
||||
"path": "assets/models/blender/npc/npc_crowd_c.glb",
|
||||
"roles": [
|
||||
"intoxicated",
|
||||
"guest"
|
||||
],
|
||||
"tint_slots": [
|
||||
"skin",
|
||||
"cloth",
|
||||
"pants",
|
||||
"accessory",
|
||||
"hair"
|
||||
],
|
||||
"triangles": 9526,
|
||||
"vertices": 19501
|
||||
},
|
||||
"npc_crowd_d": {
|
||||
"base": "worker",
|
||||
"bounds_godot": {
|
||||
"max": [
|
||||
0.262,
|
||||
1.866,
|
||||
0.287
|
||||
],
|
||||
"min": [
|
||||
-0.262,
|
||||
-0.004,
|
||||
-0.087
|
||||
]
|
||||
},
|
||||
"category": "npc",
|
||||
"layer": "hood",
|
||||
"materials": [
|
||||
"skin",
|
||||
"cloth",
|
||||
"accessory",
|
||||
"Eyebrows",
|
||||
"Moustache",
|
||||
"pants",
|
||||
"Brows",
|
||||
"sclera",
|
||||
"hair",
|
||||
"mouth",
|
||||
"pupil"
|
||||
],
|
||||
"mesh_node": "npc_base",
|
||||
"path": "assets/models/blender/npc/npc_crowd_d.glb",
|
||||
"roles": [
|
||||
"tourist",
|
||||
"guest"
|
||||
],
|
||||
"tint_slots": [
|
||||
"skin",
|
||||
"cloth",
|
||||
"pants",
|
||||
"accessory",
|
||||
"hair"
|
||||
],
|
||||
"triangles": 6290,
|
||||
"vertices": 13188
|
||||
},
|
||||
"npc_dress": {
|
||||
"base": "king",
|
||||
"bounds_godot": {
|
||||
"max": [
|
||||
0.249,
|
||||
1.809,
|
||||
0.269
|
||||
],
|
||||
"min": [
|
||||
-0.249,
|
||||
-0.001,
|
||||
-0.083
|
||||
]
|
||||
},
|
||||
"category": "npc",
|
||||
"layer": "dress",
|
||||
"materials": [
|
||||
"skin",
|
||||
"Blue",
|
||||
"cloth",
|
||||
"pants",
|
||||
"eye_white",
|
||||
"Beige",
|
||||
"Metal_Dark",
|
||||
"accessory",
|
||||
"hair",
|
||||
"rubber"
|
||||
"Gold",
|
||||
"sclera",
|
||||
"pants",
|
||||
"Metal_Dark_legs",
|
||||
"pupil"
|
||||
],
|
||||
"mesh_node": "npc_base",
|
||||
"path": "assets/models/blender/npc/npc_dress.glb",
|
||||
@@ -567,20 +697,21 @@
|
||||
"accessory",
|
||||
"hair"
|
||||
],
|
||||
"triangles": 4428,
|
||||
"vertices": 4026
|
||||
"triangles": 11126,
|
||||
"vertices": 22516
|
||||
},
|
||||
"npc_firefighter": {
|
||||
"base": "worker",
|
||||
"bounds_godot": {
|
||||
"max": [
|
||||
0.37,
|
||||
1.819,
|
||||
0.213
|
||||
0.262,
|
||||
1.866,
|
||||
0.287
|
||||
],
|
||||
"min": [
|
||||
-0.37,
|
||||
0,
|
||||
-0.213
|
||||
-0.262,
|
||||
-0.004,
|
||||
-0.087
|
||||
]
|
||||
},
|
||||
"category": "npc",
|
||||
@@ -588,13 +719,15 @@
|
||||
"materials": [
|
||||
"skin",
|
||||
"cloth",
|
||||
"pants",
|
||||
"eye_white",
|
||||
"accessory",
|
||||
"Eyebrows",
|
||||
"Moustache",
|
||||
"pants",
|
||||
"Brows",
|
||||
"sclera",
|
||||
"hair",
|
||||
"hivis",
|
||||
"reflective",
|
||||
"rubber"
|
||||
"mouth",
|
||||
"pupil"
|
||||
],
|
||||
"mesh_node": "npc_base",
|
||||
"path": "assets/models/blender/npc/npc_firefighter.glb",
|
||||
@@ -608,20 +741,21 @@
|
||||
"accessory",
|
||||
"hair"
|
||||
],
|
||||
"triangles": 4848,
|
||||
"vertices": 4735
|
||||
"triangles": 6290,
|
||||
"vertices": 13188
|
||||
},
|
||||
"npc_guard": {
|
||||
"base": "worker",
|
||||
"bounds_godot": {
|
||||
"max": [
|
||||
0.361,
|
||||
1.819,
|
||||
0.185
|
||||
0.262,
|
||||
1.866,
|
||||
0.287
|
||||
],
|
||||
"min": [
|
||||
-0.361,
|
||||
0,
|
||||
-0.172
|
||||
-0.262,
|
||||
-0.004,
|
||||
-0.087
|
||||
]
|
||||
},
|
||||
"category": "npc",
|
||||
@@ -629,15 +763,15 @@
|
||||
"materials": [
|
||||
"skin",
|
||||
"cloth",
|
||||
"pants",
|
||||
"eye_white",
|
||||
"accessory",
|
||||
"Eyebrows",
|
||||
"Moustache",
|
||||
"pants",
|
||||
"Brows",
|
||||
"sclera",
|
||||
"hair",
|
||||
"rubber",
|
||||
"leather",
|
||||
"steel",
|
||||
"patch",
|
||||
"plastic_black"
|
||||
"mouth",
|
||||
"pupil"
|
||||
],
|
||||
"mesh_node": "npc_base",
|
||||
"path": "assets/models/blender/npc/npc_guard.glb",
|
||||
@@ -652,32 +786,38 @@
|
||||
"accessory",
|
||||
"hair"
|
||||
],
|
||||
"triangles": 4560,
|
||||
"vertices": 4529
|
||||
"triangles": 6290,
|
||||
"vertices": 13188
|
||||
},
|
||||
"npc_hoodie": {
|
||||
"base": "punk",
|
||||
"bounds_godot": {
|
||||
"max": [
|
||||
0.326,
|
||||
1.856,
|
||||
0.185
|
||||
0.241,
|
||||
1.806,
|
||||
0.263
|
||||
],
|
||||
"min": [
|
||||
-0.326,
|
||||
0,
|
||||
-0.225
|
||||
-0.241,
|
||||
-0.004,
|
||||
-0.147
|
||||
]
|
||||
},
|
||||
"category": "npc",
|
||||
"layer": "hood",
|
||||
"materials": [
|
||||
"skin",
|
||||
"White",
|
||||
"cloth",
|
||||
"pants",
|
||||
"eye_white",
|
||||
"accessory",
|
||||
"sclera",
|
||||
"Eyebrows",
|
||||
"Red_Dark",
|
||||
"hair",
|
||||
"rubber"
|
||||
"Earrings",
|
||||
"Skin_legs",
|
||||
"pants",
|
||||
"pupil"
|
||||
],
|
||||
"mesh_node": "npc_base",
|
||||
"path": "assets/models/blender/npc/npc_hoodie.glb",
|
||||
@@ -693,20 +833,21 @@
|
||||
"accessory",
|
||||
"hair"
|
||||
],
|
||||
"triangles": 4826,
|
||||
"vertices": 4504
|
||||
"triangles": 5524,
|
||||
"vertices": 11257
|
||||
},
|
||||
"npc_jacket": {
|
||||
"base": "casual_2",
|
||||
"bounds_godot": {
|
||||
"max": [
|
||||
0.332,
|
||||
1.824,
|
||||
0.185
|
||||
0.255,
|
||||
1.809,
|
||||
0.279
|
||||
],
|
||||
"min": [
|
||||
-0.332,
|
||||
0,
|
||||
-0.178
|
||||
-0.255,
|
||||
-0.001,
|
||||
-0.164
|
||||
]
|
||||
},
|
||||
"category": "npc",
|
||||
@@ -714,11 +855,13 @@
|
||||
"materials": [
|
||||
"skin",
|
||||
"cloth",
|
||||
"pants",
|
||||
"eye_white",
|
||||
"accessory",
|
||||
"Skin_Darker",
|
||||
"Eyebrows",
|
||||
"hair",
|
||||
"rubber"
|
||||
"sclera",
|
||||
"pants",
|
||||
"pupil"
|
||||
],
|
||||
"mesh_node": "npc_base",
|
||||
"path": "assets/models/blender/npc/npc_jacket.glb",
|
||||
@@ -734,34 +877,38 @@
|
||||
"accessory",
|
||||
"hair"
|
||||
],
|
||||
"triangles": 4394,
|
||||
"vertices": 4175
|
||||
"triangles": 5800,
|
||||
"vertices": 11866
|
||||
},
|
||||
"npc_vest": {
|
||||
"base": "worker",
|
||||
"bounds_godot": {
|
||||
"max": [
|
||||
0.321,
|
||||
1.819,
|
||||
0.185
|
||||
0.262,
|
||||
1.789,
|
||||
0.287
|
||||
],
|
||||
"min": [
|
||||
-0.321,
|
||||
0,
|
||||
-0.172
|
||||
-0.262,
|
||||
-0.004,
|
||||
-0.083
|
||||
]
|
||||
},
|
||||
"category": "npc",
|
||||
"layer": "vest",
|
||||
"materials": [
|
||||
"skin",
|
||||
"Worker_Yellow",
|
||||
"cloth",
|
||||
"pants",
|
||||
"eye_white",
|
||||
"accessory",
|
||||
"Eyebrows",
|
||||
"Moustache",
|
||||
"pants",
|
||||
"Brows",
|
||||
"sclera",
|
||||
"hair",
|
||||
"rubber",
|
||||
"hivis",
|
||||
"reflective"
|
||||
"mouth",
|
||||
"pupil"
|
||||
],
|
||||
"mesh_node": "npc_base",
|
||||
"path": "assets/models/blender/npc/npc_vest.glb",
|
||||
@@ -775,8 +922,8 @@
|
||||
"accessory",
|
||||
"hair"
|
||||
],
|
||||
"triangles": 4474,
|
||||
"vertices": 4340
|
||||
"triangles": 6290,
|
||||
"vertices": 13186
|
||||
},
|
||||
"palm_tree": {
|
||||
"bounds_godot": {
|
||||
@@ -794,7 +941,8 @@
|
||||
"category": "props",
|
||||
"materials": [
|
||||
"palm_bark",
|
||||
"palm_leaf"
|
||||
"palm_leaf",
|
||||
"palm_leaf_dark"
|
||||
],
|
||||
"path": "assets/models/blender/props/palm_tree.glb",
|
||||
"triangles": 400,
|
||||
@@ -827,7 +975,7 @@
|
||||
"bounds_godot": {
|
||||
"max": [
|
||||
0.5,
|
||||
1.08,
|
||||
1.118,
|
||||
0.5
|
||||
],
|
||||
"min": [
|
||||
@@ -840,12 +988,13 @@
|
||||
"materials": [
|
||||
"stone_pot",
|
||||
"soil",
|
||||
"foliage"
|
||||
"foliage",
|
||||
"foliage_dark"
|
||||
],
|
||||
"path": "assets/models/blender/props/planter_box.glb",
|
||||
"replaces": "generated/planter_box.glb",
|
||||
"triangles": 1324,
|
||||
"vertices": 2780
|
||||
"triangles": 818,
|
||||
"vertices": 1701
|
||||
},
|
||||
"protest_sign": {
|
||||
"attach": "hand",
|
||||
@@ -900,24 +1049,25 @@
|
||||
"round_planter": {
|
||||
"bounds_godot": {
|
||||
"max": [
|
||||
0.432,
|
||||
1.12,
|
||||
0.399,
|
||||
1.175,
|
||||
0.36
|
||||
],
|
||||
"min": [
|
||||
-0.36,
|
||||
0,
|
||||
-0.363
|
||||
-0.376
|
||||
]
|
||||
},
|
||||
"category": "props",
|
||||
"materials": [
|
||||
"stone_pot",
|
||||
"foliage"
|
||||
"foliage",
|
||||
"foliage_dark"
|
||||
],
|
||||
"path": "assets/models/blender/props/round_planter.glb",
|
||||
"triangles": 1240,
|
||||
"vertices": 2418
|
||||
"triangles": 808,
|
||||
"vertices": 1522
|
||||
},
|
||||
"scba_tank": {
|
||||
"attach": "back",
|
||||
@@ -1071,14 +1221,14 @@
|
||||
"street_tree": {
|
||||
"bounds_godot": {
|
||||
"max": [
|
||||
1.179,
|
||||
3.62,
|
||||
1.102
|
||||
1.15,
|
||||
3.634,
|
||||
1.053
|
||||
],
|
||||
"min": [
|
||||
-0.941,
|
||||
-1.041,
|
||||
0,
|
||||
-1.082
|
||||
-1.08
|
||||
]
|
||||
},
|
||||
"category": "props",
|
||||
@@ -1090,21 +1240,21 @@
|
||||
],
|
||||
"path": "assets/models/blender/props/street_tree.glb",
|
||||
"replaces": "WorldBuilder cone trees",
|
||||
"triangles": 2592,
|
||||
"vertices": 5620
|
||||
"triangles": 1506,
|
||||
"vertices": 3330
|
||||
},
|
||||
"sunglasses": {
|
||||
"attach": "head",
|
||||
"bounds_godot": {
|
||||
"max": [
|
||||
0.101,
|
||||
0.059,
|
||||
0.158
|
||||
0.065,
|
||||
0.141,
|
||||
0.101
|
||||
],
|
||||
"min": [
|
||||
-0.101,
|
||||
0.011,
|
||||
0.003
|
||||
-0.065,
|
||||
0.11,
|
||||
0.002
|
||||
]
|
||||
},
|
||||
"category": "npc_gear",
|
||||
|
||||
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 73 KiB |
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 52 KiB |
@@ -0,0 +1,33 @@
|
||||
# Quaternius build sources (CC0 1.0)
|
||||
|
||||
These are the **build inputs** for the shipped NPC roster, not runtime assets.
|
||||
`blender_src/.gdignore` keeps Godot from importing this directory.
|
||||
|
||||
Source: Quaternius *Ultimate Modular Characters* and *Ultimate Modular Women*
|
||||
(<https://quaternius.com/packs/ultimatemodularcharacters.html>), licence CC0 1.0,
|
||||
attribution recorded in the repository `CREDITS.md`.
|
||||
|
||||
| File | SHA-256 | Bones | Meshes |
|
||||
| --- | --- | --- | --- |
|
||||
| `Casual.glb` | `bc2d84fba249ebaa0629cb9d133ad37234196e4b8004aa205a6397abed04e05c` | 62 | 4 skinned + Icosphere helper |
|
||||
| `Casual_Hoodie.glb` | `f5b722199f7628b24550989af4230f65d5230727df9c326fd2b3e360effe5249` | 62 | 4 skinned + Icosphere helper |
|
||||
| `Worker.glb` | `8d0f454336c2effc5c08f63a177af3a82d1a7af025ca9588b40e4c90c4703534` | 62 | 4 skinned + Icosphere helper |
|
||||
|
||||
Each file also carries 24 animation clips; the build exports **no** animation data, so
|
||||
the shipped GLBs contain the mesh, the 62-joint skin and the material slots only.
|
||||
|
||||
Reproducing the shipped characters:
|
||||
|
||||
flatpak run org.blender.Blender --background \
|
||||
--python "$PWD/tools/blender_assets.py" -- build --only npc
|
||||
|
||||
Upstream quirks the build compensates for (see `docs/assets/npc-model-sourcing.md`):
|
||||
|
||||
1. every mesh ships a **degenerate UV map** (all loops at `0,0`) with flat-colour
|
||||
materials, so the build Smart-UV-unwraps and repacks before export;
|
||||
2. the meshes must be joined **without welding** — `remove_doubles` corrupts the
|
||||
skin weights;
|
||||
3. the rest pose is a T-pose, so the arm-down rest is baked by
|
||||
`_bake_quaternius_rest()`;
|
||||
4. the upstream material names differ per file, so each source carries a slot map
|
||||
down to the project's five tint slots.
|
||||
@@ -0,0 +1,54 @@
|
||||
# Quaternius modular parts
|
||||
|
||||
Build inputs for outfit, hair and accessory variety. Committed like the three whole-body
|
||||
sources, so `build` works from a fresh checkout without the upstream pack.
|
||||
|
||||
## Where they come from
|
||||
|
||||
The upstream *Ultimate Modular Characters* pack is distributed as a Google Drive folder
|
||||
(<https://drive.google.com/drive/folders/1USAAquX2JJWuA2m6zol0KUkFe3UkZ8zX>, CC0 1.0). It cannot be
|
||||
fetched reproducibly by a script, so the owner downloads it **once** into the gitignored
|
||||
`tmp/quaternius-intake/`. Everything after that is scripted:
|
||||
|
||||
```sh
|
||||
python3 tools/quaternius_parts.py inventory --dir tmp/quaternius-intake
|
||||
python3 tools/quaternius_parts.py extract \
|
||||
--file tmp/quaternius-intake/<file>.glb --mesh <mesh> --part <part>
|
||||
python3 tools/quaternius_parts.py verify --dir assets/models/blender_src/quaternius/parts
|
||||
```
|
||||
|
||||
`inventory` and `verify` run outside Blender; `extract` needs Blender, because it rewrites the skin.
|
||||
The pack itself is never committed — only the parts that are actually used, each with its SHA-256
|
||||
recorded here and in `CREDITS.md`.
|
||||
|
||||
## Part contract
|
||||
|
||||
A part is **one skinned mesh on the 62-joint rig**:
|
||||
|
||||
- one mesh object, parented to the rig's armature, carrying `JOINTS_0`/`WEIGHTS_0`;
|
||||
- the standard joint names (`Hips`, `Chest`, `Head`, `UpperArm.L`, …). The rig check in
|
||||
`quaternius_parts.py verify` fails a part that is missing any of them, because
|
||||
`NpcAvatar` maps those bones;
|
||||
- materials named after a contract slot (`skin`, `cloth`, `pants`, `hair`, `accessory`) so the
|
||||
runtime tint reaches them, or a fixed-colour detail name that is deliberately not tinted;
|
||||
- triangles counted against the character budget: base body plus every joined part must stay
|
||||
inside 24,000 triangles and 24,000 glTF vertices.
|
||||
|
||||
The builder drops the part's own armature when it joins the mesh onto a base body, because the base
|
||||
already owns the skeleton and two armatures would duplicate every bone. Weights survive the join
|
||||
because Blender merges vertex groups by name.
|
||||
|
||||
## Assigning parts to a role
|
||||
|
||||
```python
|
||||
"npc_vest": {"layer": "vest", "base": "worker", "parts": ["hivis_vest"], ...}
|
||||
```
|
||||
|
||||
`build` joins those parts after the body join and before the material slot map, so the part's
|
||||
materials go through the same slot mapping as the base. The T-pose cache is keyed on the part list.
|
||||
|
||||
## Kept parts
|
||||
|
||||
| Part | Source file | SHA-256 | Tris |
|
||||
| --- | --- | --- | --- |
|
||||
| _(none yet — the pack has not been intaken)_ | | | |
|
||||
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 922 KiB |
|
After Width: | Height: | Size: 639 KiB |
|
After Width: | Height: | Size: 501 KiB |
|
After Width: | Height: | Size: 1.9 MiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 130 KiB |
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 47 KiB |