From e3327a0d01b7b7c1c8f395bcc0596609567adecf Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Tue, 16 Jun 2026 16:03:49 +0200 Subject: [PATCH 1/3] =?UTF-8?q?chore(meta):=20hold=20asset=20track=20?= =?UTF-8?q?=E2=80=94=20T-1049/T-1050=20->=20backlog=20(needs=20sprite->3D?= =?UTF-8?q?=20re-scope)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Separated the asset pipeline from the cascade work. T-1049/T-1050 assume a sprite-centric catalog; direction is 3D objects (Trellis .glb) in-world with textures as the only flattened content. Held for re-scope. Cascade track (T-1044/T-1047) continues. Co-Authored-By: Claude Opus 4.8 (1M context) --- .pql/changelog/ticket_history/2026-06.sql | 152 +++++++++++++++++++ .pql/changelog/tickets/2026-06.sql | 170 ++++++++++++++++++++++ 2 files changed, 322 insertions(+) diff --git a/.pql/changelog/ticket_history/2026-06.sql b/.pql/changelog/ticket_history/2026-06.sql index e0837abe8..f57de6d88 100644 --- a/.pql/changelog/ticket_history/2026-06.sql +++ b/.pql/changelog/ticket_history/2026-06.sql @@ -2460,3 +2460,155 @@ INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, chang INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXP5N42SSGW300FEDTS3M', 'status', 'backlog', 'in_progress', NULL, '2026-06-16 13:42:26', '2026-06-16 13:42:26', '2026-06-16 13:42:26', NULL, 'c31076efc012fb05c5f0976f00aa91b5', 2) ON CONFLICT(hash) DO NOTHING; INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXPE8FR7TGEM7X6QVPV4M', 'status', 'backlog', 'in_progress', NULL, '2026-06-16 13:42:26', '2026-06-16 13:42:26', '2026-06-16 13:42:26', NULL, 'e9eec22ee21e54104fb9ce92ea89c65a', 2) ON CONFLICT(hash) DO NOTHING; INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPQ0381QWDAQABZAY7MRD8M', 'status', 'backlog', 'in_progress', NULL, '2026-06-16 13:42:26', '2026-06-16 13:42:26', '2026-06-16 13:42:26', NULL, 'f92fd6c43fc29463faf961bc33407957', 2) ON CONFLICT(hash) DO NOTHING; +INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXPE8FR7TGEM7X6QVPV4M', 'description', '(description follows in first append) + +Filed 2026-06-12 from the fable-ous.md audit (S-43; citations adversarially verified). +T-961 (two-sentence description, no acceptance criteria, no brief links) is the only asset-production ticket under T-750, while the epic names eight classes; cars, barns, TVs, billboards appear in NO ticket at all (verified against the full corpus). Refine into child stories per class — station walls, rural walls, doors, floors, furniture/props, street furniture (lamp posts), signage/screens (billboards/TVs), rural structures (barns) — each gated on a one-page brief; explicitly record which classes are deferred (cars: see Q-067 audit note). Decide Q-119 (generic-parent placeholder set as first milestone) before sequencing. +Audit per-class status matrix (verified 2026-06-12): +# docs/assets/ survey (13 files + downloads/) + +| File | One-line summary | +|---|---| +| README.md | Master index: audio/visual/video pipelines, status vocabulary (planned/in-progress/placeholder/final), structure that promises visual/{sprites,furniture,tilesets,icons,effects}.md | +| _templates/audio.md | Row + detailed-entry template for audio assets | +| _templates/sprite.md | Row + detailed-entry template for sprites (ID prefixes SPR/FUR/TILE/ICO/FX, status, method, directions columns) | +| _templates/video.md | Row + detailed-entry template for video | +| audio/README.md | ACTIVE production-status catalog — per-category counts table (12 assets tracked), generation tools, bus architecture | +| audio/palette.md | Sonic style bible | +| audio/ambient.md / sfx.md / ui.md | Per-category audio asset tables | +| visual/README.md | STUB — links 5 category files that do not exist, all counts 0 | +| visual/palette.md | STUB — 4 bullet decisions (D-019/D-033/D-045, "functional warmth"), defers to art-direction workshop | +| video/README.md / palette.md | Stubs | +| downloads/ | Purchased character sources (Quaternius Universal Base Characters, Modular Character Outfits FBX) — characters only | + +# Per-asset-class matrix + +| Class | Written brief | Style guide | Naming/res conventions | Gen path | Produced assets | Tickets | +|---|---|---|---|---|---|---| +| Walls (station) | art-direction workshop-outcomes.md §3.3 (v0.1.1 set, pre-cascade) + docs/design/placeholder-art-spec-v01.md §2.1 | visual-grammar-v01.md §1/§4.3, workshop-outcomes §1.8 era palette (partly superseded by D-235), D-235 WallMaterial vocab | renderer/README.md:80-95 (`__.png`, 1024→256→64 chain) | working — renderer/models/wall_structural.tscn rendered | wall_structural ×4 dirs in client/assets/sprites/; wall_bar_green model unrendered; 2 textures | T-961 (backlog), T-988 (token vocab, backlog) | +| Walls (rural) | none found | D-235 tokens only (timber/rammed-earth etc.) | renderer/README.md (generic) | same path, unused | none | T-961 text mention only | +| Doors | placeholder-art-spec-v01.md §2.1 (procedural rects, v0.1) + workshop-outcomes §3.3 `door_sliding` | none for generated world | none for open/closed state frames | same path, unused | none | T-979/T-998 (DoorSpec — logical only), T-961 | +| Floors | placeholder-art-spec-v01.md §2.1 + workshop-outcomes §3.3 (4 floor sprites) | D-228 FloorMaterial axis (open vocab) | 64px visual tile (placeholder-art-spec §1) | same path, unused | none — client/assets/tilesets/ is .gitkeep only | T-959 (tile fill, logical), T-961 | +| Styled buildings | D-232 + D-235 + wiki/economics/architecture_trait_catalog.toml (T-1005 done, ~35 visual bundles) | D-235 material/color-register grammar — tokens only, no rendered art direction | token→fallback-parent chain (catalog header :34-44) | no model/texture path defined for building exteriors | none | T-977, T-988, T-994, T-1004 (all backlog), T-1005 (done) | +| Furniture | docs/assets/visual/furniture.md MISSING (linked); workshop-outcomes §3.3 lists 8-10 objects (pre-cascade) | era table §1.8 only | character-asset-organization.md explicitly excludes furniture ("follow Trellis spike conventions") | proven in spike | spikes/3dpipeline/models/furniture/ ×3 GLB (unpromoted); zero in client/assets | T-961, T-995 (ObjectTag vocab, backlog) | +| Items | docs/design/icon-set-v01.md (HUD/inventory icons only) | D-086 icon constraints | SVG icon_ prefix (client/assets/icons/) | n/a for icons | 13 SVGs in client/assets/icons/ | none for in-world item sprites | +| Cars/vehicles | none found | none | none | spike only | spikes/3dpipeline/models/props/vw_beetle.glb (spike) | none — Q-067 open ("driveable vs NPC traffic?") | +| Lamp posts | none found (zero repo hits) | none | none | unused | none | T-961 text mention only | +| Barns | none found (only T-750 epic text) | none | none | unused | none | none | +| TVs | none found (only T-750 epic text) | none | none | unused | none | none | +| Billboards | none found (only T-750 epic text; other hits = LOD impostors) | none | none | unused | none | none | +| Characters (reference class — the working model) | docs/architecture/character-asset-organization.md + docs/design/character-visuals-spec.md | yes | full (manifest.json, seg_ naming, body-type keys) | proven end-to-end | 1002 files in client/assets/characters/ | done | + +# Generation path (verified files) +image-gen (.claude/skills/image-gen/SKILL.md + scripts/image_connector.py, Gemini) → glb-gen (SKILL.md + tooling/db/trellis_connector.py + tooling/trellis-batch.sh + Blender postprocess scripts) → sprite-gen (SKILL.md + scripts/render.sh) → renderer/ (project.godot, render_scene.tscn, render_export.gd; D-019 camera, 3-light rig, 1024/256/64 chain) → client/assets/sprites/. renderer/output/ holds only .gdignore (intermediates gitignored). + +# Produced assets in client/assets (non-.import files) +audio 16 · characters 1002 · fonts 3 · icons 13 · planets 7 · sprites 9 (npc_generic ×4, wall_structural ×4, .gitkeep) · theme 1 · tilesets 1 (.gitkeep only) + +--- +Refinement (2026-06-16, /whats-next Si pass) — READY. This is a PLANNING task: break T-961 into per-class child stories. + +CLASS LIST (8 stories, parented under T-961, each gated on a one-page brief): station walls, rural walls, doors, floors, furniture/props, street furniture (lamp posts), signage/screens (TVs/billboards), rural structures (barns). +- CARS (9th class named in T-750): DEFERRED — Q-067 needs a phase decision (Phase-4 deliverable vs Phase-5+) before any car story. File a deferral note, not a story. +- Q-119 (generic-parent placeholder set as milestone-0): NOT a blocker — sequencing only. On each relevant story note that the generic parents (generic_wall/roof/facade/street + generic_door/floor/furniture; D-235 / wiki/economics/architecture_trait_catalog.toml:33-41) are milestone-0 IF Q-119 resolves "yes". + +BRIEF TEMPLATE: none exists. Create docs/assets/_templates/asset-brief.md (scope · visual reference · naming/resolution conventions · generation path · acceptance), or adopt docs/_templates/design.md. Each story states where its brief + catalog file live under docs/assets/visual/. +READ before filing: docs/assets/README.md, docs/design/{placeholder-art-spec-v01,visual-grammar-v01}.md, docs/workshops/art-direction-mood-board/workshop-outcomes.md, D-235/D-228/D-232, docs/architecture/character-asset-organization.md (the reference model). +NOTE: T-1050 (sibling) owns the catalog + naming conventions these stories reference — sequence T-1049 to consume T-1050''s conventions where they overlap.', '(description follows in first append) + +Filed 2026-06-12 from the fable-ous.md audit (S-43; citations adversarially verified). +T-961 (two-sentence description, no acceptance criteria, no brief links) is the only asset-production ticket under T-750, while the epic names eight classes; cars, barns, TVs, billboards appear in NO ticket at all (verified against the full corpus). Refine into child stories per class — station walls, rural walls, doors, floors, furniture/props, street furniture (lamp posts), signage/screens (billboards/TVs), rural structures (barns) — each gated on a one-page brief; explicitly record which classes are deferred (cars: see Q-067 audit note). Decide Q-119 (generic-parent placeholder set as first milestone) before sequencing. +Audit per-class status matrix (verified 2026-06-12): +# docs/assets/ survey (13 files + downloads/) + +| File | One-line summary | +|---|---| +| README.md | Master index: audio/visual/video pipelines, status vocabulary (planned/in-progress/placeholder/final), structure that promises visual/{sprites,furniture,tilesets,icons,effects}.md | +| _templates/audio.md | Row + detailed-entry template for audio assets | +| _templates/sprite.md | Row + detailed-entry template for sprites (ID prefixes SPR/FUR/TILE/ICO/FX, status, method, directions columns) | +| _templates/video.md | Row + detailed-entry template for video | +| audio/README.md | ACTIVE production-status catalog — per-category counts table (12 assets tracked), generation tools, bus architecture | +| audio/palette.md | Sonic style bible | +| audio/ambient.md / sfx.md / ui.md | Per-category audio asset tables | +| visual/README.md | STUB — links 5 category files that do not exist, all counts 0 | +| visual/palette.md | STUB — 4 bullet decisions (D-019/D-033/D-045, "functional warmth"), defers to art-direction workshop | +| video/README.md / palette.md | Stubs | +| downloads/ | Purchased character sources (Quaternius Universal Base Characters, Modular Character Outfits FBX) — characters only | + +# Per-asset-class matrix + +| Class | Written brief | Style guide | Naming/res conventions | Gen path | Produced assets | Tickets | +|---|---|---|---|---|---|---| +| Walls (station) | art-direction workshop-outcomes.md §3.3 (v0.1.1 set, pre-cascade) + docs/design/placeholder-art-spec-v01.md §2.1 | visual-grammar-v01.md §1/§4.3, workshop-outcomes §1.8 era palette (partly superseded by D-235), D-235 WallMaterial vocab | renderer/README.md:80-95 (`__.png`, 1024→256→64 chain) | working — renderer/models/wall_structural.tscn rendered | wall_structural ×4 dirs in client/assets/sprites/; wall_bar_green model unrendered; 2 textures | T-961 (backlog), T-988 (token vocab, backlog) | +| Walls (rural) | none found | D-235 tokens only (timber/rammed-earth etc.) | renderer/README.md (generic) | same path, unused | none | T-961 text mention only | +| Doors | placeholder-art-spec-v01.md §2.1 (procedural rects, v0.1) + workshop-outcomes §3.3 `door_sliding` | none for generated world | none for open/closed state frames | same path, unused | none | T-979/T-998 (DoorSpec — logical only), T-961 | +| Floors | placeholder-art-spec-v01.md §2.1 + workshop-outcomes §3.3 (4 floor sprites) | D-228 FloorMaterial axis (open vocab) | 64px visual tile (placeholder-art-spec §1) | same path, unused | none — client/assets/tilesets/ is .gitkeep only | T-959 (tile fill, logical), T-961 | +| Styled buildings | D-232 + D-235 + wiki/economics/architecture_trait_catalog.toml (T-1005 done, ~35 visual bundles) | D-235 material/color-register grammar — tokens only, no rendered art direction | token→fallback-parent chain (catalog header :34-44) | no model/texture path defined for building exteriors | none | T-977, T-988, T-994, T-1004 (all backlog), T-1005 (done) | +| Furniture | docs/assets/visual/furniture.md MISSING (linked); workshop-outcomes §3.3 lists 8-10 objects (pre-cascade) | era table §1.8 only | character-asset-organization.md explicitly excludes furniture ("follow Trellis spike conventions") | proven in spike | spikes/3dpipeline/models/furniture/ ×3 GLB (unpromoted); zero in client/assets | T-961, T-995 (ObjectTag vocab, backlog) | +| Items | docs/design/icon-set-v01.md (HUD/inventory icons only) | D-086 icon constraints | SVG icon_ prefix (client/assets/icons/) | n/a for icons | 13 SVGs in client/assets/icons/ | none for in-world item sprites | +| Cars/vehicles | none found | none | none | spike only | spikes/3dpipeline/models/props/vw_beetle.glb (spike) | none — Q-067 open ("driveable vs NPC traffic?") | +| Lamp posts | none found (zero repo hits) | none | none | unused | none | T-961 text mention only | +| Barns | none found (only T-750 epic text) | none | none | unused | none | none | +| TVs | none found (only T-750 epic text) | none | none | unused | none | none | +| Billboards | none found (only T-750 epic text; other hits = LOD impostors) | none | none | unused | none | none | +| Characters (reference class — the working model) | docs/architecture/character-asset-organization.md + docs/design/character-visuals-spec.md | yes | full (manifest.json, seg_ naming, body-type keys) | proven end-to-end | 1002 files in client/assets/characters/ | done | + +# Generation path (verified files) +image-gen (.claude/skills/image-gen/SKILL.md + scripts/image_connector.py, Gemini) → glb-gen (SKILL.md + tooling/db/trellis_connector.py + tooling/trellis-batch.sh + Blender postprocess scripts) → sprite-gen (SKILL.md + scripts/render.sh) → renderer/ (project.godot, render_scene.tscn, render_export.gd; D-019 camera, 3-light rig, 1024/256/64 chain) → client/assets/sprites/. renderer/output/ holds only .gdignore (intermediates gitignored). + +# Produced assets in client/assets (non-.import files) +audio 16 · characters 1002 · fonts 3 · icons 13 · planets 7 · sprites 9 (npc_generic ×4, wall_structural ×4, .gitkeep) · theme 1 · tilesets 1 (.gitkeep only) + +--- +Refinement (2026-06-16, /whats-next Si pass) — READY. This is a PLANNING task: break T-961 into per-class child stories. + +CLASS LIST (8 stories, parented under T-961, each gated on a one-page brief): station walls, rural walls, doors, floors, furniture/props, street furniture (lamp posts), signage/screens (TVs/billboards), rural structures (barns). +- CARS (9th class named in T-750): DEFERRED — Q-067 needs a phase decision (Phase-4 deliverable vs Phase-5+) before any car story. File a deferral note, not a story. +- Q-119 (generic-parent placeholder set as milestone-0): NOT a blocker — sequencing only. On each relevant story note that the generic parents (generic_wall/roof/facade/street + generic_door/floor/furniture; D-235 / wiki/economics/architecture_trait_catalog.toml:33-41) are milestone-0 IF Q-119 resolves "yes". + +BRIEF TEMPLATE: none exists. Create docs/assets/_templates/asset-brief.md (scope · visual reference · naming/resolution conventions · generation path · acceptance), or adopt docs/_templates/design.md. Each story states where its brief + catalog file live under docs/assets/visual/. +READ before filing: docs/assets/README.md, docs/design/{placeholder-art-spec-v01,visual-grammar-v01}.md, docs/workshops/art-direction-mood-board/workshop-outcomes.md, D-235/D-228/D-232, docs/architecture/character-asset-organization.md (the reference model). +NOTE: T-1050 (sibling) owns the catalog + naming conventions these stories reference — sequence T-1049 to consume T-1050''s conventions where they overlap. + +--- +HELD 2026-06-16 (separated from the cascade batch; needs re-scoping before resuming). +The asset pipeline this ticket assumes is sprite-centric (docs/assets/visual/sprites.md +"Entities", _templates/sprite.md, SPR/FUR/TILE/ICO/FX prefixes, the /sprite-gen +render-3D->2D-sprites step). Direction correction: we are NOT producing sprites — Trellis +produces 3D objects (.glb) displayed in-world; the only flattened 2D content is TEXTURES. +Re-scope this ticket around a 3D-model + texture catalog (not a sprite catalog) before +activating. See the sprite-vs-3D root-cause note (this session).', NULL, '2026-06-16 14:01:36', '2026-06-16 14:01:36.325', '2026-06-16 14:01:36.325', NULL, 'a58e68e3da1bd6cb1e026134cd3f4d56', 2) ON CONFLICT(hash) DO NOTHING; +INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXPJ910NNR5T2R9F9NWQR', 'description', '(description follows in first append) + +--- +Refinement (2026-06-16, /whats-next Si pass) — FULL scope (user decision). Two deliverables + conventions. + +(1) CATALOG: instantiate the 5 docs/assets/visual/*.md files (sprites, furniture, tilesets, icons, effects) with per-category status tables. Template: docs/assets/_templates/sprite.md (SPR/FUR/TILE/ICO/FX prefixes); status vocab planned/in-progress/placeholder/final (docs/assets/README.md). Audio side (docs/assets/audio/README.md) is the working model. + +(2) glb-gen PRODUCTION PATH: SKILL.md:115 names client/assets/models/ which does NOT exist. Create it + furniture/ + props/ subdirs (mirror the spike) + .gitkeep. Define client/assets/models/manifest.json schema MIRRORING the character manifest (docs/architecture/character-asset-organization.md) — per-asset entries: name, category, source-model path, subdirectory. Promotion convention per D-241 (promotion = repo-canonical). Update SKILL.md to point at the new path + reference the manifest. + +(3) CONVENTIONS (author NOW, full scope): door state-frame suffixes (e.g. _open / _closed), Godot TileSet resource organization (/.tres), multi-tile footprint metadata, and renderer/textures/ naming keyed to D-235 tokens (current renderer/README.md:80-95 covers sprites only: __.png). Author these in docs/assets/visual/conventions.md (single home) and cross-link from the SKILL. + +OVERLAP: T-1053 (rewrite araminta briefing) softly depends on this catalog — note the edge. T-1049''s per-class stories will reference these conventions — do T-1050 first / concurrently so T-1049 can cite them.', '(description follows in first append) + +--- +Refinement (2026-06-16, /whats-next Si pass) — FULL scope (user decision). Two deliverables + conventions. + +(1) CATALOG: instantiate the 5 docs/assets/visual/*.md files (sprites, furniture, tilesets, icons, effects) with per-category status tables. Template: docs/assets/_templates/sprite.md (SPR/FUR/TILE/ICO/FX prefixes); status vocab planned/in-progress/placeholder/final (docs/assets/README.md). Audio side (docs/assets/audio/README.md) is the working model. + +(2) glb-gen PRODUCTION PATH: SKILL.md:115 names client/assets/models/ which does NOT exist. Create it + furniture/ + props/ subdirs (mirror the spike) + .gitkeep. Define client/assets/models/manifest.json schema MIRRORING the character manifest (docs/architecture/character-asset-organization.md) — per-asset entries: name, category, source-model path, subdirectory. Promotion convention per D-241 (promotion = repo-canonical). Update SKILL.md to point at the new path + reference the manifest. + +(3) CONVENTIONS (author NOW, full scope): door state-frame suffixes (e.g. _open / _closed), Godot TileSet resource organization (/.tres), multi-tile footprint metadata, and renderer/textures/ naming keyed to D-235 tokens (current renderer/README.md:80-95 covers sprites only: __.png). Author these in docs/assets/visual/conventions.md (single home) and cross-link from the SKILL. + +OVERLAP: T-1053 (rewrite araminta briefing) softly depends on this catalog — note the edge. T-1049''s per-class stories will reference these conventions — do T-1050 first / concurrently so T-1049 can cite them. + +--- +HELD 2026-06-16 (separated from the cascade batch; needs re-scoping before resuming). +The asset pipeline this ticket assumes is sprite-centric (docs/assets/visual/sprites.md +"Entities", _templates/sprite.md, SPR/FUR/TILE/ICO/FX prefixes, the /sprite-gen +render-3D->2D-sprites step). Direction correction: we are NOT producing sprites — Trellis +produces 3D objects (.glb) displayed in-world; the only flattened 2D content is TEXTURES. +Re-scope this ticket around a 3D-model + texture catalog (not a sprite catalog) before +activating. See the sprite-vs-3D root-cause note (this session).', NULL, '2026-06-16 14:01:36', '2026-06-16 14:01:36.350', '2026-06-16 14:01:36.350', NULL, '1d10d3452316fcc41f4ed669d28e67b5', 2) ON CONFLICT(hash) DO NOTHING; +INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXPE8FR7TGEM7X6QVPV4M', 'status', 'in_progress', 'backlog', NULL, '2026-06-16 14:01:36', '2026-06-16 14:01:36.369', '2026-06-16 14:01:36.369', NULL, '1b6f54b4815c27985c5a1a7d8c983bb1', 2) ON CONFLICT(hash) DO NOTHING; +INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXPJ910NNR5T2R9F9NWQR', 'status', 'in_progress', 'backlog', NULL, '2026-06-16 14:01:36', '2026-06-16 14:01:36.371', '2026-06-16 14:01:36.371', NULL, 'd5b4d3133cd7d9428a028121e862bd07', 2) ON CONFLICT(hash) DO NOTHING; diff --git a/.pql/changelog/tickets/2026-06.sql b/.pql/changelog/tickets/2026-06.sql index ae603478a..a5901f764 100644 --- a/.pql/changelog/tickets/2026-06.sql +++ b/.pql/changelog/tickets/2026-06.sql @@ -3305,3 +3305,173 @@ SERIALIZE decision: TerrainAnalysis derives Debug+Clone only (features.rs:65); L COMPOSE WITH T-1047 (same batch): T-1047 aggregates a per-district dominant-D8-direction in the SAME run_layer1 pass — do both together to avoid double-touching layer1.rs/cascade.rs. Acceptance: T-1031 harness cost drops toward ~45ms/body; T-952 golden-seed byte-identity UNCHANGED. Files: layer1.rs, cascade.rs (+ CascadeSnapshot if transient).', 'in_progress', 'medium', NULL, 'server', 'D-203', '2026-06-12 10:23:50', '2026-06-16 13:42:26', NULL, 'acb7bf02efc3a7d7f4418f7d6c151204', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash); +INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXPE8FR7TGEM7X6QVPV4M', 'task', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Refine T-961 into per-asset-class stories, each gated on a written brief', '(description follows in first append) + +Filed 2026-06-12 from the fable-ous.md audit (S-43; citations adversarially verified). +T-961 (two-sentence description, no acceptance criteria, no brief links) is the only asset-production ticket under T-750, while the epic names eight classes; cars, barns, TVs, billboards appear in NO ticket at all (verified against the full corpus). Refine into child stories per class — station walls, rural walls, doors, floors, furniture/props, street furniture (lamp posts), signage/screens (billboards/TVs), rural structures (barns) — each gated on a one-page brief; explicitly record which classes are deferred (cars: see Q-067 audit note). Decide Q-119 (generic-parent placeholder set as first milestone) before sequencing. +Audit per-class status matrix (verified 2026-06-12): +# docs/assets/ survey (13 files + downloads/) + +| File | One-line summary | +|---|---| +| README.md | Master index: audio/visual/video pipelines, status vocabulary (planned/in-progress/placeholder/final), structure that promises visual/{sprites,furniture,tilesets,icons,effects}.md | +| _templates/audio.md | Row + detailed-entry template for audio assets | +| _templates/sprite.md | Row + detailed-entry template for sprites (ID prefixes SPR/FUR/TILE/ICO/FX, status, method, directions columns) | +| _templates/video.md | Row + detailed-entry template for video | +| audio/README.md | ACTIVE production-status catalog — per-category counts table (12 assets tracked), generation tools, bus architecture | +| audio/palette.md | Sonic style bible | +| audio/ambient.md / sfx.md / ui.md | Per-category audio asset tables | +| visual/README.md | STUB — links 5 category files that do not exist, all counts 0 | +| visual/palette.md | STUB — 4 bullet decisions (D-019/D-033/D-045, "functional warmth"), defers to art-direction workshop | +| video/README.md / palette.md | Stubs | +| downloads/ | Purchased character sources (Quaternius Universal Base Characters, Modular Character Outfits FBX) — characters only | + +# Per-asset-class matrix + +| Class | Written brief | Style guide | Naming/res conventions | Gen path | Produced assets | Tickets | +|---|---|---|---|---|---|---| +| Walls (station) | art-direction workshop-outcomes.md §3.3 (v0.1.1 set, pre-cascade) + docs/design/placeholder-art-spec-v01.md §2.1 | visual-grammar-v01.md §1/§4.3, workshop-outcomes §1.8 era palette (partly superseded by D-235), D-235 WallMaterial vocab | renderer/README.md:80-95 (`__.png`, 1024→256→64 chain) | working — renderer/models/wall_structural.tscn rendered | wall_structural ×4 dirs in client/assets/sprites/; wall_bar_green model unrendered; 2 textures | T-961 (backlog), T-988 (token vocab, backlog) | +| Walls (rural) | none found | D-235 tokens only (timber/rammed-earth etc.) | renderer/README.md (generic) | same path, unused | none | T-961 text mention only | +| Doors | placeholder-art-spec-v01.md §2.1 (procedural rects, v0.1) + workshop-outcomes §3.3 `door_sliding` | none for generated world | none for open/closed state frames | same path, unused | none | T-979/T-998 (DoorSpec — logical only), T-961 | +| Floors | placeholder-art-spec-v01.md §2.1 + workshop-outcomes §3.3 (4 floor sprites) | D-228 FloorMaterial axis (open vocab) | 64px visual tile (placeholder-art-spec §1) | same path, unused | none — client/assets/tilesets/ is .gitkeep only | T-959 (tile fill, logical), T-961 | +| Styled buildings | D-232 + D-235 + wiki/economics/architecture_trait_catalog.toml (T-1005 done, ~35 visual bundles) | D-235 material/color-register grammar — tokens only, no rendered art direction | token→fallback-parent chain (catalog header :34-44) | no model/texture path defined for building exteriors | none | T-977, T-988, T-994, T-1004 (all backlog), T-1005 (done) | +| Furniture | docs/assets/visual/furniture.md MISSING (linked); workshop-outcomes §3.3 lists 8-10 objects (pre-cascade) | era table §1.8 only | character-asset-organization.md explicitly excludes furniture ("follow Trellis spike conventions") | proven in spike | spikes/3dpipeline/models/furniture/ ×3 GLB (unpromoted); zero in client/assets | T-961, T-995 (ObjectTag vocab, backlog) | +| Items | docs/design/icon-set-v01.md (HUD/inventory icons only) | D-086 icon constraints | SVG icon_ prefix (client/assets/icons/) | n/a for icons | 13 SVGs in client/assets/icons/ | none for in-world item sprites | +| Cars/vehicles | none found | none | none | spike only | spikes/3dpipeline/models/props/vw_beetle.glb (spike) | none — Q-067 open ("driveable vs NPC traffic?") | +| Lamp posts | none found (zero repo hits) | none | none | unused | none | T-961 text mention only | +| Barns | none found (only T-750 epic text) | none | none | unused | none | none | +| TVs | none found (only T-750 epic text) | none | none | unused | none | none | +| Billboards | none found (only T-750 epic text; other hits = LOD impostors) | none | none | unused | none | none | +| Characters (reference class — the working model) | docs/architecture/character-asset-organization.md + docs/design/character-visuals-spec.md | yes | full (manifest.json, seg_ naming, body-type keys) | proven end-to-end | 1002 files in client/assets/characters/ | done | + +# Generation path (verified files) +image-gen (.claude/skills/image-gen/SKILL.md + scripts/image_connector.py, Gemini) → glb-gen (SKILL.md + tooling/db/trellis_connector.py + tooling/trellis-batch.sh + Blender postprocess scripts) → sprite-gen (SKILL.md + scripts/render.sh) → renderer/ (project.godot, render_scene.tscn, render_export.gd; D-019 camera, 3-light rig, 1024/256/64 chain) → client/assets/sprites/. renderer/output/ holds only .gdignore (intermediates gitignored). + +# Produced assets in client/assets (non-.import files) +audio 16 · characters 1002 · fonts 3 · icons 13 · planets 7 · sprites 9 (npc_generic ×4, wall_structural ×4, .gitkeep) · theme 1 · tilesets 1 (.gitkeep only) + +--- +Refinement (2026-06-16, /whats-next Si pass) — READY. This is a PLANNING task: break T-961 into per-class child stories. + +CLASS LIST (8 stories, parented under T-961, each gated on a one-page brief): station walls, rural walls, doors, floors, furniture/props, street furniture (lamp posts), signage/screens (TVs/billboards), rural structures (barns). +- CARS (9th class named in T-750): DEFERRED — Q-067 needs a phase decision (Phase-4 deliverable vs Phase-5+) before any car story. File a deferral note, not a story. +- Q-119 (generic-parent placeholder set as milestone-0): NOT a blocker — sequencing only. On each relevant story note that the generic parents (generic_wall/roof/facade/street + generic_door/floor/furniture; D-235 / wiki/economics/architecture_trait_catalog.toml:33-41) are milestone-0 IF Q-119 resolves "yes". + +BRIEF TEMPLATE: none exists. Create docs/assets/_templates/asset-brief.md (scope · visual reference · naming/resolution conventions · generation path · acceptance), or adopt docs/_templates/design.md. Each story states where its brief + catalog file live under docs/assets/visual/. +READ before filing: docs/assets/README.md, docs/design/{placeholder-art-spec-v01,visual-grammar-v01}.md, docs/workshops/art-direction-mood-board/workshop-outcomes.md, D-235/D-228/D-232, docs/architecture/character-asset-organization.md (the reference model). +NOTE: T-1050 (sibling) owns the catalog + naming conventions these stories reference — sequence T-1049 to consume T-1050''s conventions where they overlap. + +--- +HELD 2026-06-16 (separated from the cascade batch; needs re-scoping before resuming). +The asset pipeline this ticket assumes is sprite-centric (docs/assets/visual/sprites.md +"Entities", _templates/sprite.md, SPR/FUR/TILE/ICO/FX prefixes, the /sprite-gen +render-3D->2D-sprites step). Direction correction: we are NOT producing sprites — Trellis +produces 3D objects (.glb) displayed in-world; the only flattened 2D content is TEXTURES. +Re-scope this ticket around a 3D-model + texture catalog (not a sprite catalog) before +activating. See the sprite-vs-3D root-cause note (this session).', 'in_progress', 'high', NULL, 'visual', NULL, '2026-06-12 10:40:58', '2026-06-16 14:01:36.325', NULL, '038b6bd5130fced6f3038983a03a709b', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash); +INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXPJ910NNR5T2R9F9NWQR', 'task', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Create the visual production-status catalog; fix glb-gen production path + naming conventions', '(description follows in first append) + +--- +Refinement (2026-06-16, /whats-next Si pass) — FULL scope (user decision). Two deliverables + conventions. + +(1) CATALOG: instantiate the 5 docs/assets/visual/*.md files (sprites, furniture, tilesets, icons, effects) with per-category status tables. Template: docs/assets/_templates/sprite.md (SPR/FUR/TILE/ICO/FX prefixes); status vocab planned/in-progress/placeholder/final (docs/assets/README.md). Audio side (docs/assets/audio/README.md) is the working model. + +(2) glb-gen PRODUCTION PATH: SKILL.md:115 names client/assets/models/ which does NOT exist. Create it + furniture/ + props/ subdirs (mirror the spike) + .gitkeep. Define client/assets/models/manifest.json schema MIRRORING the character manifest (docs/architecture/character-asset-organization.md) — per-asset entries: name, category, source-model path, subdirectory. Promotion convention per D-241 (promotion = repo-canonical). Update SKILL.md to point at the new path + reference the manifest. + +(3) CONVENTIONS (author NOW, full scope): door state-frame suffixes (e.g. _open / _closed), Godot TileSet resource organization (/.tres), multi-tile footprint metadata, and renderer/textures/ naming keyed to D-235 tokens (current renderer/README.md:80-95 covers sprites only: __.png). Author these in docs/assets/visual/conventions.md (single home) and cross-link from the SKILL. + +OVERLAP: T-1053 (rewrite araminta briefing) softly depends on this catalog — note the edge. T-1049''s per-class stories will reference these conventions — do T-1050 first / concurrently so T-1049 can cite them. + +--- +HELD 2026-06-16 (separated from the cascade batch; needs re-scoping before resuming). +The asset pipeline this ticket assumes is sprite-centric (docs/assets/visual/sprites.md +"Entities", _templates/sprite.md, SPR/FUR/TILE/ICO/FX prefixes, the /sprite-gen +render-3D->2D-sprites step). Direction correction: we are NOT producing sprites — Trellis +produces 3D objects (.glb) displayed in-world; the only flattened 2D content is TEXTURES. +Re-scope this ticket around a 3D-model + texture catalog (not a sprite catalog) before +activating. See the sprite-vs-3D root-cause note (this session).', 'in_progress', 'high', NULL, 'visual', NULL, '2026-06-12 10:40:59', '2026-06-16 14:01:36.350', NULL, 'f6a5625e47450d6e4a37c65e3165c904', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash); +INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXPE8FR7TGEM7X6QVPV4M', 'task', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Refine T-961 into per-asset-class stories, each gated on a written brief', '(description follows in first append) + +Filed 2026-06-12 from the fable-ous.md audit (S-43; citations adversarially verified). +T-961 (two-sentence description, no acceptance criteria, no brief links) is the only asset-production ticket under T-750, while the epic names eight classes; cars, barns, TVs, billboards appear in NO ticket at all (verified against the full corpus). Refine into child stories per class — station walls, rural walls, doors, floors, furniture/props, street furniture (lamp posts), signage/screens (billboards/TVs), rural structures (barns) — each gated on a one-page brief; explicitly record which classes are deferred (cars: see Q-067 audit note). Decide Q-119 (generic-parent placeholder set as first milestone) before sequencing. +Audit per-class status matrix (verified 2026-06-12): +# docs/assets/ survey (13 files + downloads/) + +| File | One-line summary | +|---|---| +| README.md | Master index: audio/visual/video pipelines, status vocabulary (planned/in-progress/placeholder/final), structure that promises visual/{sprites,furniture,tilesets,icons,effects}.md | +| _templates/audio.md | Row + detailed-entry template for audio assets | +| _templates/sprite.md | Row + detailed-entry template for sprites (ID prefixes SPR/FUR/TILE/ICO/FX, status, method, directions columns) | +| _templates/video.md | Row + detailed-entry template for video | +| audio/README.md | ACTIVE production-status catalog — per-category counts table (12 assets tracked), generation tools, bus architecture | +| audio/palette.md | Sonic style bible | +| audio/ambient.md / sfx.md / ui.md | Per-category audio asset tables | +| visual/README.md | STUB — links 5 category files that do not exist, all counts 0 | +| visual/palette.md | STUB — 4 bullet decisions (D-019/D-033/D-045, "functional warmth"), defers to art-direction workshop | +| video/README.md / palette.md | Stubs | +| downloads/ | Purchased character sources (Quaternius Universal Base Characters, Modular Character Outfits FBX) — characters only | + +# Per-asset-class matrix + +| Class | Written brief | Style guide | Naming/res conventions | Gen path | Produced assets | Tickets | +|---|---|---|---|---|---|---| +| Walls (station) | art-direction workshop-outcomes.md §3.3 (v0.1.1 set, pre-cascade) + docs/design/placeholder-art-spec-v01.md §2.1 | visual-grammar-v01.md §1/§4.3, workshop-outcomes §1.8 era palette (partly superseded by D-235), D-235 WallMaterial vocab | renderer/README.md:80-95 (`__.png`, 1024→256→64 chain) | working — renderer/models/wall_structural.tscn rendered | wall_structural ×4 dirs in client/assets/sprites/; wall_bar_green model unrendered; 2 textures | T-961 (backlog), T-988 (token vocab, backlog) | +| Walls (rural) | none found | D-235 tokens only (timber/rammed-earth etc.) | renderer/README.md (generic) | same path, unused | none | T-961 text mention only | +| Doors | placeholder-art-spec-v01.md §2.1 (procedural rects, v0.1) + workshop-outcomes §3.3 `door_sliding` | none for generated world | none for open/closed state frames | same path, unused | none | T-979/T-998 (DoorSpec — logical only), T-961 | +| Floors | placeholder-art-spec-v01.md §2.1 + workshop-outcomes §3.3 (4 floor sprites) | D-228 FloorMaterial axis (open vocab) | 64px visual tile (placeholder-art-spec §1) | same path, unused | none — client/assets/tilesets/ is .gitkeep only | T-959 (tile fill, logical), T-961 | +| Styled buildings | D-232 + D-235 + wiki/economics/architecture_trait_catalog.toml (T-1005 done, ~35 visual bundles) | D-235 material/color-register grammar — tokens only, no rendered art direction | token→fallback-parent chain (catalog header :34-44) | no model/texture path defined for building exteriors | none | T-977, T-988, T-994, T-1004 (all backlog), T-1005 (done) | +| Furniture | docs/assets/visual/furniture.md MISSING (linked); workshop-outcomes §3.3 lists 8-10 objects (pre-cascade) | era table §1.8 only | character-asset-organization.md explicitly excludes furniture ("follow Trellis spike conventions") | proven in spike | spikes/3dpipeline/models/furniture/ ×3 GLB (unpromoted); zero in client/assets | T-961, T-995 (ObjectTag vocab, backlog) | +| Items | docs/design/icon-set-v01.md (HUD/inventory icons only) | D-086 icon constraints | SVG icon_ prefix (client/assets/icons/) | n/a for icons | 13 SVGs in client/assets/icons/ | none for in-world item sprites | +| Cars/vehicles | none found | none | none | spike only | spikes/3dpipeline/models/props/vw_beetle.glb (spike) | none — Q-067 open ("driveable vs NPC traffic?") | +| Lamp posts | none found (zero repo hits) | none | none | unused | none | T-961 text mention only | +| Barns | none found (only T-750 epic text) | none | none | unused | none | none | +| TVs | none found (only T-750 epic text) | none | none | unused | none | none | +| Billboards | none found (only T-750 epic text; other hits = LOD impostors) | none | none | unused | none | none | +| Characters (reference class — the working model) | docs/architecture/character-asset-organization.md + docs/design/character-visuals-spec.md | yes | full (manifest.json, seg_ naming, body-type keys) | proven end-to-end | 1002 files in client/assets/characters/ | done | + +# Generation path (verified files) +image-gen (.claude/skills/image-gen/SKILL.md + scripts/image_connector.py, Gemini) → glb-gen (SKILL.md + tooling/db/trellis_connector.py + tooling/trellis-batch.sh + Blender postprocess scripts) → sprite-gen (SKILL.md + scripts/render.sh) → renderer/ (project.godot, render_scene.tscn, render_export.gd; D-019 camera, 3-light rig, 1024/256/64 chain) → client/assets/sprites/. renderer/output/ holds only .gdignore (intermediates gitignored). + +# Produced assets in client/assets (non-.import files) +audio 16 · characters 1002 · fonts 3 · icons 13 · planets 7 · sprites 9 (npc_generic ×4, wall_structural ×4, .gitkeep) · theme 1 · tilesets 1 (.gitkeep only) + +--- +Refinement (2026-06-16, /whats-next Si pass) — READY. This is a PLANNING task: break T-961 into per-class child stories. + +CLASS LIST (8 stories, parented under T-961, each gated on a one-page brief): station walls, rural walls, doors, floors, furniture/props, street furniture (lamp posts), signage/screens (TVs/billboards), rural structures (barns). +- CARS (9th class named in T-750): DEFERRED — Q-067 needs a phase decision (Phase-4 deliverable vs Phase-5+) before any car story. File a deferral note, not a story. +- Q-119 (generic-parent placeholder set as milestone-0): NOT a blocker — sequencing only. On each relevant story note that the generic parents (generic_wall/roof/facade/street + generic_door/floor/furniture; D-235 / wiki/economics/architecture_trait_catalog.toml:33-41) are milestone-0 IF Q-119 resolves "yes". + +BRIEF TEMPLATE: none exists. Create docs/assets/_templates/asset-brief.md (scope · visual reference · naming/resolution conventions · generation path · acceptance), or adopt docs/_templates/design.md. Each story states where its brief + catalog file live under docs/assets/visual/. +READ before filing: docs/assets/README.md, docs/design/{placeholder-art-spec-v01,visual-grammar-v01}.md, docs/workshops/art-direction-mood-board/workshop-outcomes.md, D-235/D-228/D-232, docs/architecture/character-asset-organization.md (the reference model). +NOTE: T-1050 (sibling) owns the catalog + naming conventions these stories reference — sequence T-1049 to consume T-1050''s conventions where they overlap. + +--- +HELD 2026-06-16 (separated from the cascade batch; needs re-scoping before resuming). +The asset pipeline this ticket assumes is sprite-centric (docs/assets/visual/sprites.md +"Entities", _templates/sprite.md, SPR/FUR/TILE/ICO/FX prefixes, the /sprite-gen +render-3D->2D-sprites step). Direction correction: we are NOT producing sprites — Trellis +produces 3D objects (.glb) displayed in-world; the only flattened 2D content is TEXTURES. +Re-scope this ticket around a 3D-model + texture catalog (not a sprite catalog) before +activating. See the sprite-vs-3D root-cause note (this session).', 'backlog', 'high', NULL, 'visual', NULL, '2026-06-12 10:40:58', '2026-06-16 14:01:36.369', NULL, '24d0abe148f4ebd5536619cc12c94c06', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash); +INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPTXPJ910NNR5T2R9F9NWQR', 'task', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Create the visual production-status catalog; fix glb-gen production path + naming conventions', '(description follows in first append) + +--- +Refinement (2026-06-16, /whats-next Si pass) — FULL scope (user decision). Two deliverables + conventions. + +(1) CATALOG: instantiate the 5 docs/assets/visual/*.md files (sprites, furniture, tilesets, icons, effects) with per-category status tables. Template: docs/assets/_templates/sprite.md (SPR/FUR/TILE/ICO/FX prefixes); status vocab planned/in-progress/placeholder/final (docs/assets/README.md). Audio side (docs/assets/audio/README.md) is the working model. + +(2) glb-gen PRODUCTION PATH: SKILL.md:115 names client/assets/models/ which does NOT exist. Create it + furniture/ + props/ subdirs (mirror the spike) + .gitkeep. Define client/assets/models/manifest.json schema MIRRORING the character manifest (docs/architecture/character-asset-organization.md) — per-asset entries: name, category, source-model path, subdirectory. Promotion convention per D-241 (promotion = repo-canonical). Update SKILL.md to point at the new path + reference the manifest. + +(3) CONVENTIONS (author NOW, full scope): door state-frame suffixes (e.g. _open / _closed), Godot TileSet resource organization (/.tres), multi-tile footprint metadata, and renderer/textures/ naming keyed to D-235 tokens (current renderer/README.md:80-95 covers sprites only: __.png). Author these in docs/assets/visual/conventions.md (single home) and cross-link from the SKILL. + +OVERLAP: T-1053 (rewrite araminta briefing) softly depends on this catalog — note the edge. T-1049''s per-class stories will reference these conventions — do T-1050 first / concurrently so T-1049 can cite them. + +--- +HELD 2026-06-16 (separated from the cascade batch; needs re-scoping before resuming). +The asset pipeline this ticket assumes is sprite-centric (docs/assets/visual/sprites.md +"Entities", _templates/sprite.md, SPR/FUR/TILE/ICO/FX prefixes, the /sprite-gen +render-3D->2D-sprites step). Direction correction: we are NOT producing sprites — Trellis +produces 3D objects (.glb) displayed in-world; the only flattened 2D content is TEXTURES. +Re-scope this ticket around a 3D-model + texture catalog (not a sprite catalog) before +activating. See the sprite-vs-3D root-cause note (this session).', 'backlog', 'high', NULL, 'visual', NULL, '2026-06-12 10:40:59', '2026-06-16 14:01:36.371', NULL, '21d429fe79add1fb53ca64a8113c8a82', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash); -- 2.54.0 From dae1498a6fb1bc270be1476e26f5396910d6afe8 Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Tue, 16 Jun 2026 22:36:13 +0200 Subject: [PATCH 2/3] docs(assets): ratify 3D asset direction (D-244); repurpose sprite-gen as 2D-artwork generator D-244 ratifies what the character architecture (D-159..D-164, runtime CharacterVisualDescriptor compositing) and the Trellis env pipeline already implied but no decision had recorded: the in-world view renders 3D objects directly; the only flattened 2D content is textures + flat 2D artwork (paintings/flags/billboards/signage). There is no per-object sprite layer. Roots out the drift: the early-spike 3D->2D sprite pipeline (#541) and the sprite-centric docs/assets/visual catalog were never cleaned out when the project went 3D, so the 2026-06-12 fable-ous audit read them as live and re-injected the dead sprite model into T-1049/T-1050. Fix: - docs/assets/visual/README.md + docs/assets/README.md re-scoped to 3D models + textures + flat artwork (dropped the sprites/tilesets-as-entities framing). - /sprite-gen + renderer/README repurposed as the 2D-artwork generator (paintings/flags/ billboards/signage), not the in-world object format; legacy 4-direction object-sprite mode flagged as retired. - T-961/T-1049/T-1050 already held in backlog pending this. Co-Authored-By: Claude Opus 4.8 (1M context) --- .claude/skills/sprite-gen/SKILL.md | 72 +++++++++++++--------------- docs/assets/README.md | 14 +++--- docs/assets/visual/README.md | 30 +++++++----- governance/README.md | 1 + governance/decisions/architecture.md | 13 ++++- renderer/README.md | 13 ++++- 6 files changed, 80 insertions(+), 63 deletions(-) diff --git a/.claude/skills/sprite-gen/SKILL.md b/.claude/skills/sprite-gen/SKILL.md index be40ebf6f..63e5406f1 100644 --- a/.claude/skills/sprite-gen/SKILL.md +++ b/.claude/skills/sprite-gen/SKILL.md @@ -1,55 +1,47 @@ --- name: sprite-gen description: > - Render a 3D model to 2D sprites via the Godot render pipeline. Produces - sprites at 3 resolutions (1024, 256, 64) from 4 cardinal directions (north, - east, south, west) with outline applied at working resolution. Use when the - user says "render sprite", "render model", "run the render pipeline", - "test the pipeline", "/sprite-gen", or asks to render a specific model - (e.g., "render wall_structural"). Output: 12 PNG files in renderer/output/. + 2D-artwork generator for The Settled Reach — produces flat 2D art (paintings, + flags, billboards, signage, screen content) as PNG textures/decals applied to + flat surfaces in the otherwise-3D world (D-244). Use when the user says "render + artwork", "make a painting/flag/billboard", "2d art", "/sprite-gen", or asks to + produce flat decorative art. NOT for game objects or characters — those are 3D + (.glb via /glb-gen; characters via the Quaternius pipeline). Output: PNG files + in renderer/output/. --- +## What this is (D-244) + +Per **D-244**, the in-world view renders **3D objects directly**. The only flattened +2D content is **textures** (PBR maps on 3D surfaces) and **flat 2D artwork** — +paintings, flags, billboards, signage, screen content. This skill produces that flat +artwork via the Godot render pipeline at `renderer/`. + +**This is NOT the in-world object format.** Game objects/props are 3D `.glb` +(`/glb-gen`); characters are 3D meshes composited at runtime +(`CharacterVisualDescriptor`). This tool began as the #541 spike that rendered 3D +models to 4-direction sprites for a 2D view — that role is **retired** (D-244). It now +serves flat 2D artwork only. + ## Render Pipeline -Run the render script with the model name: - ```bash -.claude/skills/sprite-gen/scripts/render.sh +.claude/skills/sprite-gen/scripts/render.sh ``` -### Available Models +Scenes live at `renderer/models/.tscn`. The script still emits the legacy spike +layout — 12 PNGs in `renderer/output/` (4 cardinal directions × 3 resolutions: +1024/256/64). For **flat artwork** the relevant output is the single front (south) +view; the multi-direction output is legacy object-sprite behaviour. A flat-artwork +(single-view) mode for the render script is the natural follow-up. -Models live at `renderer/models/.tscn`. List them: +### After rendering -```bash -ls renderer/models/*.tscn | xargs -I{} basename {} .tscn -``` - -### Output - -12 files per model in `renderer/output/`: - -``` -_north_1024.png _north_256.png _north_64.png -_east_1024.png _east_256.png _east_64.png -_south_1024.png _south_256.png _south_64.png -_west_1024.png _west_256.png _west_64.png -``` - -### After Rendering - -1. Read the 64x64 output files to visually inspect the runtime sprites -2. Read the 256x256 files to check outline quality -3. Report: does it read as the intended object at runtime scale? +1. Inspect the output PNG — does it read as the intended artwork at in-world scale? +2. Promote the final PNG to `client/assets/` as the surface texture/decal. ### Troubleshooting -- **No output files**: Godot needs a display. If running headless, prefix with `xvfb-run`. -- **Model not found**: Check the model .tscn exists in `renderer/models/`. -- **Godot not found**: Pass path as second arg: `render.sh wall_structural /path/to/godot` - -### Adding New Models - -1. Create model scene at `renderer/models/.tscn` -2. Apply texture from `renderer/textures/` via StandardMaterial3D -3. Run: `.claude/skills/sprite-gen/scripts/render.sh ` +- **No output files:** Godot needs a display. If running headless, prefix with `xvfb-run`. +- **Scene not found:** check the `.tscn` exists in `renderer/models/`. +- **Godot not found:** pass the Godot path as the second arg: `render.sh /path/to/godot`. diff --git a/docs/assets/README.md b/docs/assets/README.md index d808c1ca7..48513aea2 100644 --- a/docs/assets/README.md +++ b/docs/assets/README.md @@ -24,7 +24,7 @@ docs/assets/ README.md # This file — master index _templates/ audio.md # Row template + detailed entry template for audio - sprite.md # Row template + detailed entry template for sprites + sprite.md # Row template for 2D artwork rows (paintings/flags/billboards — see /sprite-gen) video.md # Row template + detailed entry template for video audio/ README.md # Audio pipeline index — categories, status summary @@ -32,14 +32,14 @@ docs/assets/ ambient.md # All ambient loops (station, planet, biome, weather) sfx.md # All SFX (footsteps, doors, impacts, events) ui.md # All UI sounds (cursor, chimes, insert-tech) - visual/ + visual/ # 3D models + textures + flat artwork (D-244 — no per-object sprites) README.md # Visual pipeline index palette.md # Art direction, "the angle", color relationships - sprites.md # Entities (NPCs, player, creatures) - furniture.md # Furniture items (hundreds, by location/type) - tilesets.md # Floor/wall tiles by biome/planet - icons.md # UI icons, status indicators - effects.md # Fog shaders, particles, overlays + models.md # 3D objects/props (.glb via Trellis /glb-gen) + textures.md # PBR surface maps (BaseColor/Normal/Roughness) for 3D models + artwork.md # Flat 2D art — paintings, flags, billboards, signage (via /sprite-gen) + icons.md # UI icons, status indicators (UI layer) + effects.md # Shaders, particles, overlays video/ README.md # Video pipeline index palette.md # Motion/editing style guide diff --git a/docs/assets/visual/README.md b/docs/assets/visual/README.md index 1e5d885c0..f42bf8a6b 100644 --- a/docs/assets/visual/README.md +++ b/docs/assets/visual/README.md @@ -1,6 +1,6 @@ --- title: "Visual Asset Pipeline" -description: "Visual pipeline index covering sprites, furniture, tilesets, icons, and effects with render pipeline overview" +description: "Visual pipeline index — 3D models, textures, and flat 2D artwork (D-244)" type: design status: active --- @@ -9,28 +9,32 @@ status: active Status: **Stub** — awaiting first visual sprint. +Per **[D-244](../../../governance/decisions/architecture.md#d-244)**: the in-world view renders **3D objects directly**. The only flattened 2D content is **textures** (PBR maps on 3D surfaces) and **flat 2D artwork** (paintings, flags, billboards, signage) applied as textures/decals on flat surfaces *within* the 3D world. **There is no per-object sprite layer** — game objects are not pre-rendered to sprites. + ## Categories | Category | File | Count | Description | |----------|------|-------|-------------| -| Sprites | [sprites.md](sprites.md) | 0 | Entity sprites via 3D render pipeline | -| Furniture | [furniture.md](furniture.md) | 0 | Furniture items by location/type | -| Tilesets | [tilesets.md](tilesets.md) | 0 | Floor/wall tiles by biome/planet | -| Icons | [icons.md](icons.md) | 0 | UI icons, status indicators | -| Effects | [effects.md](effects.md) | 0 | Fog shaders, particles, overlays | +| Models | [models.md](models.md) | 0 | 3D objects/props (`.glb`) via Trellis (`/glb-gen`), promoted per [D-241] | +| Characters | — | — | 3D meshes composited at runtime via `CharacterVisualDescriptor` — see [character-asset-organization.md](../../architecture/character-asset-organization.md) | +| Textures | [textures.md](textures.md) | 0 | PBR surface maps (BaseColor / Normal / Roughness) for 3D models | +| Artwork | [artwork.md](artwork.md) | 0 | Flat 2D art — paintings, flags, billboards, signage, screen content — applied as textures/decals (via the `/sprite-gen` 2D-artwork generator) | +| Icons | [icons.md](icons.md) | 0 | UI icons, status indicators (2D, UI layer only) | +| Effects | [effects.md](effects.md) | 0 | Shaders, particles, overlays | ## Palette -See [palette.md](palette.md) for art direction, "the angle", color relationships, and render pipeline specs. +See [palette.md](palette.md) for art direction, "the angle", and colour relationships. ## Pipeline -- **3D render pipeline:** Blender model → Godot Camera3D at -72.5deg → orthographic render → outline pass → resolution downscale -- **Render skill:** `/sprite-gen` produces 12 PNGs (4 directions x 3 resolutions) -- **Art direction workshop:** `docs/workshops/art-direction-mood-board/` +- **3D objects / props:** concept image (`/image-gen`) → Trellis image→3D (`/glb-gen`) → `.glb` → promoted to `client/assets/models/`. +- **Characters:** Quaternius source meshes, segmented + rigged, composited at runtime from slots (`CharacterVisualDescriptor`); see the character-asset doc. +- **Textures:** PBR maps authored/generated for 3D surfaces. +- **2D artwork** (paintings / flags / billboards / signage): the `/sprite-gen` **2D-artwork generator** → flat PNG → applied as a texture/decal on a flat surface in the 3D world. ## Decision References -- D-019: Top-down camera, 15-20deg from vertical ("the angle") -- D-033: Entity color = relationship to player -- D-045: Environmental neutrality +- **[D-244](../../../governance/decisions/architecture.md#d-244):** 3D objects in-world; 2D limited to textures + flat artwork. +- D-159–D-164: character 3D pipeline. D-241: asset promotion. +- D-019: top-down camera, "the angle". D-033: entity colour = relationship to player. D-045: environmental neutrality. diff --git a/governance/README.md b/governance/README.md index 83569f231..77556b834 100644 --- a/governance/README.md +++ b/governance/README.md @@ -309,6 +309,7 @@ line in place — keep the Q-record for the audit trail rather than deleting it. - [D-241: Spike binary artifacts are local-only — gitignored, never tracked](decisions/process.md#d-241-spike-binary-artifacts-are-local-only--gitignored-never-tracked) — _process_ - [D-242: Corp HQ settlement model — HQs are not cities; separate from the name pool, specialization-keyed, install-baked](decisions/architecture.md#d-242-corp-hq-settlement-model--hqs-are-not-cities-separate-from-the-name-pool-specialization-keyed-install-baked) — _architecture_ - [D-243: Spatial scale ladder — nested absolute containment with a single elastic planetary seam (resolves Q-110)](decisions/architecture.md#d-243-spatial-scale-ladder--nested-absolute-containment-with-a-single-elastic-planetary-seam-resolves-q-110) — _architecture_ +- [D-244: Asset rendering — 3D objects in-world; 2D limited to textures + flat artwork](decisions/architecture.md#d-244-asset-rendering--3d-objects-in-world-2d-limited-to-textures--flat-artwork) — _architecture_ ## Open questions diff --git a/governance/decisions/architecture.md b/governance/decisions/architecture.md index 3a87c4b06..a352134ef 100644 --- a/governance/decisions/architecture.md +++ b/governance/decisions/architecture.md @@ -1842,4 +1842,15 @@ Technical foundation decisions that constrain implementation: engine, client-ser --- -*100 decisions (D-001 through D-243, excluding gaps). Last updated: 2026-06-14 (spatial scale ladder — D-243 resolves Q-110: nested absolute containment voxel→chunk→block→quarter→district→region with a single elastic region↔planet seam; region is the climate/weather lockdown scale + planetary grid, edge-fuzzed; the 1 km RegionProfile is dropped onto the district; D-201 tier-4 Region→Province; ladder recorded in CLAUDE.md).* +### D-244: Asset rendering — 3D objects in-world; 2D limited to textures + flat artwork +- **Date:** 2026-06-16 +- **Decision:** The in-world view renders **3D objects directly**. Environment and props come from the Trellis image→3D `.glb` pipeline (`/glb-gen`, promoted per [D-241](#d-241)); characters come from the Quaternius 3D-mesh pipeline composited at runtime via `CharacterVisualDescriptor` ([D-159](#d-159)–[D-164](#d-164): 11 body types, segmented regions, separate head mesh, slot system, shape keys, region tints). The **only flattened 2D content** is **(a) textures** (PBR maps on 3D surfaces) and **(b) flat 2D artwork** — paintings, flags, billboards, signage, screen content — images that live as textures/decals on flat surfaces *within* the 3D world. There is **no per-object sprite layer**: game objects are not pre-rendered to 2D sprites for display. +- **Rationale:** The character system is irreducibly 3D — runtime slot compositing across body × head × hair × clothing × skin-tone × colour-overrides × shape-keys × directions × animation-frames cannot be expressed as pre-rendered sprites without combinatorial explosion. The 3D direction was already implicit in the character architecture (the 2026-03-19 character-asset doc states "no mesh work from the spikes carries over") and the Trellis environment pipeline, but was never ratified — so the retired 2D-sprite assumption drifted on in tooling and docs. +- **What this retires / repurposes:** the early-spike **3D→2D-sprite render pipeline** (`renderer/`, the `/sprite-gen` skill, added in #541) is **not** the in-world format. It is **repurposed as the 2D-artwork generator** — producing the flat paintings/flags/billboards/signage assets in (b). The sprite-centric asset catalog (`docs/assets/visual/` sprites/tilesets framing, `_templates/sprite.md`) is re-scoped to a **3D-model + texture + artwork** catalog. +- **Root-cause note:** T-1049/T-1050 (the 2026-06-12 `fable-ous.md` audit) re-injected the dead sprite model because the retired spike scaffolding sat in the repo as live ground truth with no decision marking it dead. This record is that marker; T-961/T-1049/T-1050 are held in backlog pending re-scope. +- **Cross-reference:** [D-159](#d-159)–[D-164](#d-164) (character 3D pipeline), [D-241](#d-241) (asset promotion), [D-227](#d-227) (derive/synthesise, don't store). Phase 5 (in-world rendering) builds on this. +- **Dissent:** None + +--- + +*101 decisions (D-001 through D-244, excluding gaps). Last updated: 2026-06-16 (D-244 — asset rendering direction: 3D objects in-world (Trellis environment + Quaternius characters via CharacterVisualDescriptor); 2D limited to textures + flat artwork (paintings/flags/billboards/signage); the early-spike sprite-render pipeline is repurposed as the 2D-artwork generator, not the in-world format; re-scopes T-961/T-1049/T-1050).* diff --git a/renderer/README.md b/renderer/README.md index 1725f24ab..9b57a18b0 100644 --- a/renderer/README.md +++ b/renderer/README.md @@ -1,6 +1,15 @@ -# Settled Reach — Sprite Render Pipeline +# Settled Reach — 2D Artwork Render Pipeline -Offline Godot 4 renderer for the 3D-to-2D sprite pipeline. Produces entity and structural sprites at three resolutions from a fixed camera angle, with outlines applied at working resolution. +> **Repurposed (D-244).** This offline Godot renderer is **not** the in-world object +> format. Per [D-244] the in-world view renders 3D objects directly (props via Trellis +> `.glb` / `/glb-gen`; characters via the Quaternius pipeline + `CharacterVisualDescriptor`); +> the only flattened 2D content is **textures** and **flat 2D artwork** (paintings, flags, +> billboards, signage). This pipeline began as the #541 3D-to-2D *sprite* spike and now +> serves that flat artwork. The "render every entity/object/wall to sprites" framing below +> is **legacy** (the retired object-sprite use); the camera / lighting / resolution mechanics +> remain usable for flat-artwork rendering. + +Offline Godot 4 renderer. Produces flat 2D artwork (and, in its legacy mode, 3D-to-2D sprites) at three resolutions from a fixed camera angle, with outlines applied at working resolution. ## Camera Specification (D-019) -- 2.54.0 From ae7606ed8384f444c30585099515bb2397770574 Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Wed, 17 Jun 2026 09:40:41 +0200 Subject: [PATCH 3/3] =?UTF-8?q?docs(governance):=20address=20PR=20#169=20r?= =?UTF-8?q?eview=20=E2=80=94=20reconcile=20sprite-era=20decisions=20+=20do?= =?UTF-8?q?c=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tyre: D-244 now references its precedent (D-148 3D camera / D-149 live 3D characters — D-244 completes that pivot for objects + assets) and reconciles the 5 sprite-era decisions it touched, all amended 2026-06-17: - D-043: 'not 3D' / Light2D scoped to overlay layers; in-world is 3D. - D-044: sprite footprint retired (sim occupancy + visual hierarchy survive). - D-049: z-stack logical model survives; sprite/CanvasLayer implementation language retired. - D-066: dual-scale coordinate model + 2x2 geometry minimum survive; sprite-footprint language legacy. Hoshe (doc QA): - D-244 broken cross-file anchors fixed ([D-159]->scope.md, [D-241]->process.md). - renderer/README: bare [D-244] linked; D-019->D-148 camera note; legacy banner over the object-sprite workflow sections; resolution-chain output path qualified. - docs/assets/_templates/sprite.md + README: marked the template legacy object-sprite schema (model/texture/artwork template TBD). Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/assets/README.md | 2 +- docs/assets/_templates/sprite.md | 2 ++ governance/decisions/architecture.md | 7 ++++--- governance/decisions/perception.md | 3 +++ renderer/README.md | 12 +++++++++--- 5 files changed, 19 insertions(+), 7 deletions(-) diff --git a/docs/assets/README.md b/docs/assets/README.md index 48513aea2..991a0d03e 100644 --- a/docs/assets/README.md +++ b/docs/assets/README.md @@ -24,7 +24,7 @@ docs/assets/ README.md # This file — master index _templates/ audio.md # Row template + detailed entry template for audio - sprite.md # Row template for 2D artwork rows (paintings/flags/billboards — see /sprite-gen) + sprite.md # LEGACY object-sprite row template (D-244 retired sprites; model/texture/artwork template TBD) video.md # Row template + detailed entry template for video audio/ README.md # Audio pipeline index — categories, status summary diff --git a/docs/assets/_templates/sprite.md b/docs/assets/_templates/sprite.md index 52dd0bef9..9c72c2280 100644 --- a/docs/assets/_templates/sprite.md +++ b/docs/assets/_templates/sprite.md @@ -7,6 +7,8 @@ status: active # Sprite Asset Template +> **Legacy (D-244).** This is the retired **object-sprite** row schema (4-direction, resolution variants). Per [D-244](../../../governance/decisions/architecture.md#d-244-asset-rendering--3d-objects-in-world-2d-limited-to-textures--flat-artwork), game objects are 3D (not sprites) and the only flat 2D content is textures + artwork — so a model / texture / artwork row template is TBD (tracked with the visual-catalog re-scope, T-961/T-1049/T-1050). This schema is kept for reference and for the 2D-artwork (paintings/flags/billboards) use of `/sprite-gen`. + ## Table Row Format ``` diff --git a/governance/decisions/architecture.md b/governance/decisions/architecture.md index a352134ef..5c6d30e84 100644 --- a/governance/decisions/architecture.md +++ b/governance/decisions/architecture.md @@ -176,6 +176,7 @@ Technical foundation decisions that constrain implementation: engine, client-ser - **Cursor/interaction:** No change — cursor already resolves to sim tile from pixel position. Interaction range of ~2 sim tiles = 1m (arm's length). - **Map authoring:** Author at 1m visual scale. Subdivision tool expands each visual tile to 4 sim tiles (2x2). Validation enforces 2x2 minimum on all world geometry layers. - **Amends:** OQ-01 resolution (ticket T-444). Sim tile size remains 0.5m; visual presentation changes from 1:1 to 2:1 retina factor. +- **Amendment (2026-06-17):** The dual-scale coordinate model (0.5 m Subtile / 1 m Tile) and the 2×2-sim-tile **geometry minimum** are unchanged and load-bearing for the 3D architecture — cover/LOS/collision still map 1:1 to what the player sees. The "**Sprites: 2×2 sim tile footprint**" bullet and the "sprites look right" rationale are pre-Sprint-28 sprite-era: in-world entities/objects are now rendered as 3D ([D-149](#d-149-3d-characters-rendered-live-in-scene--not-pre-rendered-sprites) / [D-244](#d-244-asset-rendering--3d-objects-in-world-2d-limited-to-textures--flat-artwork)), so there is no pixel sprite footprint — the 2×2 figure persists only as the visual-tile proportionality the 3D entity occupies. The spatial math survives; only the rendering technology changed. - **Cross-reference:** Tile-based movement ([D-054](#d-054-tile-based-movement-with-same-tile-occupancy)), shadowcasting ([D-238](perception.md#d-238-symmetric-shadowcasting-albert-ford-selected-for-los-computation)), fog ([D-059](perception.md#d-059-fog--shader-based-five-layers-knowledge-graph-driven)), art direction ([D-043](perception.md#d-043-art-direction--visual-style-functional-warmth)), z-stack ([D-049](perception.md#d-049-z-level-rendering-stack-8-layers)), stance system ([D-053](scope.md#d-053-movement-as-stance-toggle-system)) - **Rationale:** 0.5m sim tiles give stealth-grade granularity for movement stances, cover peeking, and interaction range. 1m visual tiles make spaces feel proportional, sprites look right, and world geometry readable. The 2x2 minimum on geometry eliminates visual/sim mismatch for cover and LOS — the only sub-visual-tile positioning is entity movement, which is communicated through fog feedback, not tile counting. Analogous to macOS Retina: logical resolution (visual) differs from physical resolution (sim), but the system is coherent because both agree on where solid objects are. - **Raised by:** Team Leader (Jeroen) — proposed retina scaling analogy and 2x2 geometry constraint. Tyre (feasibility: trivial, half-day integration). Gestalt (approved with 2x2 constraint resolving LOS readability concern). Ozzie (approved: solves sprite scale without uncanny mismatch). @@ -1844,13 +1845,13 @@ Technical foundation decisions that constrain implementation: engine, client-ser ### D-244: Asset rendering — 3D objects in-world; 2D limited to textures + flat artwork - **Date:** 2026-06-16 -- **Decision:** The in-world view renders **3D objects directly**. Environment and props come from the Trellis image→3D `.glb` pipeline (`/glb-gen`, promoted per [D-241](#d-241)); characters come from the Quaternius 3D-mesh pipeline composited at runtime via `CharacterVisualDescriptor` ([D-159](#d-159)–[D-164](#d-164): 11 body types, segmented regions, separate head mesh, slot system, shape keys, region tints). The **only flattened 2D content** is **(a) textures** (PBR maps on 3D surfaces) and **(b) flat 2D artwork** — paintings, flags, billboards, signage, screen content — images that live as textures/decals on flat surfaces *within* the 3D world. There is **no per-object sprite layer**: game objects are not pre-rendered to 2D sprites for display. +- **Decision:** The in-world view renders **3D objects directly**. Environment and props come from the Trellis image→3D `.glb` pipeline (`/glb-gen`, promoted per [D-241](process.md#d-241-spike-binary-artifacts-are-local-only--gitignored-never-tracked)); characters come from the Quaternius 3D-mesh pipeline composited at runtime via `CharacterVisualDescriptor` ([D-159](scope.md#d-159-character-body-type-enum-5-types--2-genders--1-child-skeleton-11-total)–[D-164](#d-164): 11 body types, segmented regions, separate head mesh, slot system, shape keys, region tints). The **only flattened 2D content** is **(a) textures** (PBR maps on 3D surfaces) and **(b) flat 2D artwork** — paintings, flags, billboards, signage, screen content — images that live as textures/decals on flat surfaces *within* the 3D world. There is **no per-object sprite layer**: game objects are not pre-rendered to 2D sprites for display. This **completes** the 3D pivot already ratified for the camera ([D-148](#d-148-30-low-angle-camera-with-45-map-rotation--supersedes-d-019), supersedes D-019) and live 3D characters ([D-149](#d-149-3d-characters-rendered-live-in-scene--not-pre-rendered-sprites)), extending it to all objects and the asset pipeline. - **Rationale:** The character system is irreducibly 3D — runtime slot compositing across body × head × hair × clothing × skin-tone × colour-overrides × shape-keys × directions × animation-frames cannot be expressed as pre-rendered sprites without combinatorial explosion. The 3D direction was already implicit in the character architecture (the 2026-03-19 character-asset doc states "no mesh work from the spikes carries over") and the Trellis environment pipeline, but was never ratified — so the retired 2D-sprite assumption drifted on in tooling and docs. - **What this retires / repurposes:** the early-spike **3D→2D-sprite render pipeline** (`renderer/`, the `/sprite-gen` skill, added in #541) is **not** the in-world format. It is **repurposed as the 2D-artwork generator** — producing the flat paintings/flags/billboards/signage assets in (b). The sprite-centric asset catalog (`docs/assets/visual/` sprites/tilesets framing, `_templates/sprite.md`) is re-scoped to a **3D-model + texture + artwork** catalog. - **Root-cause note:** T-1049/T-1050 (the 2026-06-12 `fable-ous.md` audit) re-injected the dead sprite model because the retired spike scaffolding sat in the repo as live ground truth with no decision marking it dead. This record is that marker; T-961/T-1049/T-1050 are held in backlog pending re-scope. -- **Cross-reference:** [D-159](#d-159)–[D-164](#d-164) (character 3D pipeline), [D-241](#d-241) (asset promotion), [D-227](#d-227) (derive/synthesise, don't store). Phase 5 (in-world rendering) builds on this. +- **Cross-reference:** **Builds on** [D-148](#d-148-30-low-angle-camera-with-45-map-rotation--supersedes-d-019) (3D camera, supersedes D-019) and [D-149](#d-149-3d-characters-rendered-live-in-scene--not-pre-rendered-sprites) (live 3D characters, not sprites) — D-244 extends both to all objects + the asset pipeline. [D-159](scope.md#d-159-character-body-type-enum-5-types--2-genders--1-child-skeleton-11-total)–[D-164](#d-164) (character 3D pipeline), [D-241](process.md#d-241-spike-binary-artifacts-are-local-only--gitignored-never-tracked) (asset promotion), [D-227](#d-227) (derive/synthesise, don't store). **Reconciles the sprite-era decisions** (all amended 2026-06-17): [D-043](perception.md#d-043-art-direction--visual-style-functional-warmth) ("not 3D"/Light2D scoped to overlay layers), [D-044](perception.md#d-044-art-direction--visual-hierarchy-entity--object--structure) (sprite footprint retired; sim occupancy + hierarchy survive), [D-049](perception.md#d-049-z-level-rendering-stack-8-layers) (z-stack logical model survives; sprite implementation language retired), [D-066](#d-066-dual-scale-grid--05m-simulation-1m-visual-2x-retina-factor) (coordinate model + 2×2 geometry minimum survive; sprite-footprint language legacy); [D-019] is already superseded by D-148. Phase 5 (in-world rendering) builds on this. - **Dissent:** None --- -*101 decisions (D-001 through D-244, excluding gaps). Last updated: 2026-06-16 (D-244 — asset rendering direction: 3D objects in-world (Trellis environment + Quaternius characters via CharacterVisualDescriptor); 2D limited to textures + flat artwork (paintings/flags/billboards/signage); the early-spike sprite-render pipeline is repurposed as the 2D-artwork generator, not the in-world format; re-scopes T-961/T-1049/T-1050).* +*101 decisions (D-001 through D-244, excluding gaps). Last updated: 2026-06-17 (D-244 — asset rendering direction: 3D objects in-world (Trellis environment + Quaternius characters via CharacterVisualDescriptor); 2D limited to textures + flat artwork; repurposes the early-spike sprite pipeline as the 2D-artwork generator; builds on D-148/D-149 and reconciles the sprite-era decisions D-043/D-044/D-049/D-066 (all amended); re-scopes T-961/T-1049/T-1050).* diff --git a/governance/decisions/perception.md b/governance/decisions/perception.md index b9b577203..039531521 100644 --- a/governance/decisions/perception.md +++ b/governance/decisions/perception.md @@ -146,6 +146,7 @@ How the player observes and interacts with the world: camera, fog, line-of-sight - **Canonical reference:** `docs/workshops/art-direction-mood-board/workshop-outcomes.md` §1.1, §9.1-9.3 - **Raised by:** Araminta (lead), unanimously endorsed. Art Direction & Mood Board Workshop (3 rounds + closing). - **Dissent:** None. All four agents independently converged on the same style. +- **Amendment (2026-06-17):** The "not 3D" and Light2D-pipeline clauses describe the **overlay** layers (insert, fog, UI). The **in-world** view renders in 3D: camera per [D-148](architecture.md#d-148-30-low-angle-camera-with-45-map-rotation--supersedes-d-019), live 3D characters per [D-149](architecture.md#d-149-3d-characters-rendered-live-in-scene--not-pre-rendered-sprites), all objects + the asset pipeline per [D-244](architecture.md#d-244-asset-rendering--3d-objects-in-world-2d-limited-to-textures--flat-artwork). The "functional warmth" aesthetic, bold silhouettes, outline language, and the resolution chain survive — the chain now serves 2D textures + flat artwork (paintings/flags/billboards/signage), not per-object sprites. ### D-044: Art direction — visual hierarchy (entity > object > structure) - **Date:** 2026-02-12 @@ -155,6 +156,7 @@ How the player observes and interacts with the world: camera, fog, line-of-sight - **Raised by:** Araminta (outline spec), Ozzie (readability priority). Unanimously endorsed. - **Dissent:** None - **Amendment (2026-04-05):** The "D-033 relationship color" outline spec for entities applies only in perception mode overlay. [D-154](scope.md#d-154-character-outline-is-not-a-relationship-indicator--uniform-dark) (2026-03-17) establishes uniform dark outlines (#1a1a1a) for all characters in normal gameplay. The visual hierarchy layers remain valid; the entity outline color rule changes from always-on to perception-mode-only. +- **Amendment (2026-06-17):** The three-layer visual *hierarchy* (entity > object > structure; entity-wins-ties readability rule) and the 1×1 simulation occupancy survive. The **2×2 subtile sprite footprint** and the **24×32px pixel footprint** are sprite-era specs, retired for in-world objects/entities per [D-149](architecture.md#d-149-3d-characters-rendered-live-in-scene--not-pre-rendered-sprites) / [D-244](architecture.md#d-244-asset-rendering--3d-objects-in-world-2d-limited-to-textures--flat-artwork) — live 3D characters/objects have no pixel sprite footprint. The silhouette-as-identity principle carries to the 3D character silhouette. ### D-045: Art direction — environmental neutrality (strict zero shift) - **Date:** 2026-02-12 @@ -196,6 +198,7 @@ How the player observes and interacts with the world: camera, fog, line-of-sight - **Canonical reference:** `docs/workshops/art-direction-mood-board/workshop-outcomes.md` §1.14 - **Raised by:** Araminta (8-layer spec), Gore (overhead as thematic tool). Unanimously endorsed. - **Dissent:** None +- **Amendment (2026-06-17):** The z-stack as a **logical** layering model — what occludes what; overhead/fog/insert/UI ordering — survives. Its implementation language ("entity sprites", CanvasLayer y-sort) is sprite-era: in-world layers 2–3 are now 3D scene nodes per [D-149](architecture.md#d-149-3d-characters-rendered-live-in-scene--not-pre-rendered-sprites) / [D-244](architecture.md#d-244-asset-rendering--3d-objects-in-world-2d-limited-to-textures--flat-artwork), z-ordered by the 3D renderer (camera per [D-148](architecture.md#d-148-30-low-angle-camera-with-45-map-rotation--supersedes-d-019)). Layers 5–7 (fog, insert, UI) remain 2D overlays. ### D-052: Character favorite colors — object-layer identification - **Date:** 2026-02-12 diff --git a/renderer/README.md b/renderer/README.md index 9b57a18b0..93ba152ba 100644 --- a/renderer/README.md +++ b/renderer/README.md @@ -1,7 +1,7 @@ # Settled Reach — 2D Artwork Render Pipeline > **Repurposed (D-244).** This offline Godot renderer is **not** the in-world object -> format. Per [D-244] the in-world view renders 3D objects directly (props via Trellis +> format. Per [D-244](../governance/decisions/architecture.md#d-244-asset-rendering--3d-objects-in-world-2d-limited-to-textures--flat-artwork) the in-world view renders 3D objects directly (props via Trellis > `.glb` / `/glb-gen`; characters via the Quaternius pipeline + `CharacterVisualDescriptor`); > the only flattened 2D content is **textures** and **flat 2D artwork** (paintings, flags, > billboards, signage). This pipeline began as the #541 3D-to-2D *sprite* spike and now @@ -18,7 +18,9 @@ Offline Godot 4 renderer. Produces flat 2D artwork (and, in its legacy mode, 3D- - **Position**: `(0, 3, 1)` — above and slightly in front of the model origin - **Godot Transform3D**: `Transform3D(1, 0, 0, 0, 0.30071, 0.95372, 0, -0.95372, 0.30071, 0, 3, 1)` -This is "the angle" per D-019 amendment (2026-02-12). All entity, object, and wall sprites for v0.1 are rendered at this angle. The Godot gameplay camera is purely orthographic — this tilt is an art convention expressed through the 3D render. +**Note (D-244):** D-019 is superseded by D-148 (30° low-angle Camera3D) for the **gameplay** camera. The −72.5° angle here is the **offline render** camera used for 2D-artwork generation (and the retired object-sprite mode) — not the in-world gameplay camera. + +This is "the angle" per the D-019 amendment (2026-02-12); v0.1 object-sprite rendering used it, now retired. The offline renderer keeps this fixed camera for flat-artwork output. ## Lighting Rig @@ -39,11 +41,15 @@ Three-point studio rig. All lights have `shadow_enabled = false` — sprites are ↓ bilinear resize 256×256 — working PNG, outline applied at 4-8px, color #333340 ↓ bilinear resize -64×64 — runtime PNG, deployed to client/assets/sprites/ +64×64 — runtime PNG (legacy object-sprite output → client/assets/sprites/; for flat artwork, promote to client/assets/textures or .../artwork) ``` Outline implementation: alpha-mask dilation + flat color fill. Outline width in `render_export.gd`: `outline_width_px = 4` (at 256px = 1px effective at 64px). +## ⚠️ Legacy: object-sprite workflow (retired per D-244) + +Everything from here down describes the **retired** object-sprite pipeline (#541 spike) — entity/object/wall sprites are no longer the in-world format (objects are 3D `.glb`; characters are 3D meshes). It is kept for reference, and because the camera / lighting / resolution mechanics above are reused for **2D-artwork** rendering. When generating flat artwork, promote outputs to `client/assets/textures` or `client/assets/artwork` (**not** `client/assets/sprites/`) and ignore the entity-sprite footprint / material / deployment specifics below. + ## Entity Footprint Spec (D-044, D-066) - Entity sprites occupy a **24×32px footprint** within the 64×64 visual tile -- 2.54.0