docs(assets): PR #213 review fixes — DoorSpec fields, spike inventory, axis honesty, D-154

doors.md now presents D-231's actual struct shape (initial_state
Open/Closed/Locked/Sealed; TemporalWindow lives in the independent
credential field) and attaches the Phase-5 runtime bridge to
initial_state only. furniture-props.md inventories all five spike GLBs
— acceptance is 4 promotable (3 furniture + lion_statue), vw_beetle
explicitly excluded to the Q-067 deferral. deferred.md + station-walls
gain the axis-completeness note: roof/facade/street textures ride the
wall-brief convention as a same-family follow-on, so the register
accounts for all four D-235 axes. The briefing's D-257 pointer
corrected to palette.md §2.1–2.2, and both the briefing and palette.md
(leave-cleaner, gap inherited from PR #211) now carry D-154's amendment
to D-033 — relationship colors display only in the insert/perception
overlay; normal gameplay is a uniform #1a1a1a outline (D-150).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-25 23:10:09 +02:00
co-authored by Claude Fable 5
parent 2e9bbcaaf2
commit 660f4a703f
6 changed files with 100 additions and 44 deletions
+16
View File
@@ -51,6 +51,22 @@ mention. There is nothing to protect or unwind by waiting.
**Disposition.** Formal deferral, not a story. No brief is authored for any
of the four this batch.
**Note on axis completeness.** This register's exterior-texture examples in
`station-walls.md`/`rural-walls.md` cite the D-235 **wall** axis only — that
is deliberate scoping to this batch's two briefed classes, not a claim that
roof/facade/street are also deferred. `RoofForm` (7 tags), `FacadeRhythm`
(8 tags), and `StreetSurface` (7 tags) are the other three D-235 axes and
are **not** unbriefed set-dressing in the sense the four classes above are —
they are building-exterior surfaces that ride the **same** naming/generation
convention the wall briefs establish (`<object_tag>_<map_type>.png` per
`conventions.md` §3, `palette.md` §3.2–§3.4's register rows already exist
for all three). They are a natural follow-on brief/story within the
building-exterior asset-class family once station-walls/rural-walls prove
the pattern out — not named as their own class in T-1049's per-class list,
and not deferred for the exterior-not-walkable-yet reason the four classes
above are. No new brief is authored for them this batch; the accounting
above is complete once this note is read alongside the wall briefs.
## Cars (Q-067)
**Rationale, same shape, one added layer.** Cars are also set-dressing/
+14 -8
View File
@@ -26,8 +26,10 @@ Doors have **no D-235 ObjectTag axis** — wall/roof/facade/street are building-
exterior surface tags; a door is a discrete object that sits in a wall
opening. What DOES exist already: the **logical** `DoorSpec`/
`InteriorDescriptor` model (T-979/T-998, D-231) — door count derivation
(Main/Service/Emergency/Hidden) and initial-state derivation (`Open`/
`Closed`/`TemporalWindow`/`Locked`/`Sealed`) — but that work is server-side
(Main/Service/Emergency/Hidden) and **two separate derived fields**:
`initial_state` (`Open`/`Closed`/`Locked`/`Sealed`) and, independently,
`credential` (`None`/`TemporalWindow(hours)`/`Corporate(corp)`/
`Resident(block)`/`Authority`/`Social(f32)`) — but that work is server-side
struct definition only, not visual. This brief covers the **visual asset**
only; it does not touch T-979/T-998's derivation logic.
@@ -50,15 +52,19 @@ brief specifies.
`<category>_<descriptor>.glb` per `conventions.md` §1 — e.g. `door_sliding
.glb`, `door_hinged.glb`. **Negative constraint, binding (`conventions.md`
§5): do NOT author state-frame suffix files** (`door_open.glb`/
`door_closed.glb`). One door `.glb` per descriptor; the `DoorSpec` states
(`Open`/`Closed`/`TemporalWindow`/`Locked`/`Sealed`) are a **runtime
`door_closed.glb`). One door `.glb` per descriptor; `DoorSpec`'s
`initial_state` (`Open`/`Closed`/`Locked`/`Sealed`) is a **runtime
transform/animation** on that single model — the actual mechanism
(`AnimationPlayer` swing, procedural hinge rotation, or a named "open" bone
convention) is explicitly a **Phase-5 rendering decision**, out of scope for
this Phase-4 asset brief and for the story it gates. Mask sidecar
(`<model>_mask.png`) only if a tintable variant is wanted; footprint is
single-tile (`[1, 1]`, omit the field) — a door does not span multiple sim
tiles.
this Phase-4 asset brief and for the story it gates. The separate
`credential` field (`None`/`TemporalWindow(hours)`/`Corporate(corp)`/
`Resident(block)`/`Authority`/`Social(f32)`) is an access-control value, not a
door pose — it carries no visual-asset implication at all (no lock-indicator
variant, no separate model), so this brief's naming/negative-constraint
scope is `initial_state` only. Mask sidecar (`<model>_mask.png`) only if a
tintable variant is wanted; footprint is single-tile (`[1, 1]`, omit the
field) — a door does not span multiple sim tiles.
## 4. Generation Path
+47 -26
View File
@@ -26,14 +26,21 @@ ObjectTag axis applies (that vocabulary is building-exterior only); this
class is closest in spirit to D-235's incremental-content *mechanism*
(specific-to-generic fallback) without the ratified vocabulary itself — an
open question this brief does not resolve (see §5, T-995's ObjectTag
extension). **Real prior art exists and is unpromoted**: 3 GLBs at
`spikes/3dpipeline/models/furniture/` — this brief's first job is promoting
extension). **Real prior art exists and is unpromoted**: the spike's
`models/` tree holds **five** GLBs total — 3 at `spikes/3dpipeline/models/
furniture/` (`furniture`-category) and 2 at `spikes/3dpipeline/models/
props/` (`props`-category: `lion_statue.glb`, mode "fixed", non-tintable;
and `vw_beetle.glb`, a car). Of these five, **four are in this brief's
scope** (3 furniture + `lion_statue`) — this brief's first job is promoting
that spike output through the now-real production path (`client/assets/
models/`, `manifest.json`), not generating from zero. Out of scope: walls,
doors, floors (separate briefs); vehicles (Q-067, deferred); the four
`deferred.md` classes (lamp posts, TVs, billboards, barns — those are
furniture-*tier* objects but are formally deferred by name, not folded into
this brief).
models/`, `manifest.json`), not generating from zero. `vw_beetle.glb` is
explicitly **excluded**: it is a vehicle, covered by the Q-067 car deferral
in `deferred.md`, not this brief, regardless of sitting in the same spike
`props/` directory as `lion_statue.glb`. Out of scope: walls, doors, floors
(separate briefs); vehicles (Q-067, deferred — `vw_beetle.glb` per above);
the four `deferred.md` classes (lamp posts, TVs, billboards, barns — those
are furniture-*tier* objects but are formally deferred by name, not folded
into this brief).
## 2. Visual Reference
@@ -54,34 +61,47 @@ tier is where a saturation bump is permitted, unlike wall/roof/street).
## 3. Naming
`<category>_<descriptor>.glb` per `conventions.md` §1 — the spike's existing
files (`baroque_table.glb`, `modernist_chair.glb`) are **descriptor-first**
and must be **renamed to category-first** (`table_baroque.glb`,
`chair_modernist.glb`) at promotion time; `conventions.md` §1 explicitly
rules the spike naming "pre-convention scratch work, not a precedent to
preserve." Mask sidecar: `<model>_mask.png`, single-channel, per §2 — the
existing Trellis convention, just reordered. `footprint_tiles` in the
furniture files (`baroque_table.glb`, `modernist_chair.glb`) are
**descriptor-first** and must be **renamed to category-first**
(`table_baroque.glb`, `chair_modernist.glb`) at promotion time;
`conventions.md` §1 explicitly rules the spike naming "pre-convention scratch
work, not a precedent to preserve." `lion_statue.glb` is already
category-first as named and needs no rename. Mask sidecar: `<model>_mask
.png`, single-channel, per §2 — the existing Trellis convention, just
reordered for the renamed furniture items; `lion_statue.glb` is non-tintable
("fixed" mode in the spike) and ships with **no mask sidecar** at all, not an
empty one — `conventions.md` §2's `hint_default_black` default already
covers "no mask loaded = no tinting" for this case. `footprint_tiles` in the
manifest for any furniture with a real multi-tile footprint (a table spanning
`[2, 1]`); most `props`-category items omit the field or set `[1, 1]`.
`[2, 1]`); most `props`-category items, including `lion_statue`, omit the
field or set `[1, 1]`.
## 4. Generation Path
Two paths, depending on whether the spike asset is being promoted or a new
one generated: (a) **Promotion path** for the 3 existing spike GLBs — rename
per §3, run through Blender postprocess if not already toon-compatible,
place in `client/assets/models/furniture/` (or `props/` per actual category),
register in `manifest.json`. This IS the promotion act (D-241) — nothing
stays "promoted" in `spikes/`. (b) **New-asset path**, standard:
`/image-gen` concept → `/glb-gen` (Trellis) → Blender postprocess →
`client/assets/models/{furniture,props}/` + `manifest.json`. Both paths
one generated: (a) **Promotion path** for the 4 in-scope existing spike
GLBs (3 furniture + `props/lion_statue.glb`) — rename per §3 (furniture
items only; `lion_statue` keeps its name), run through Blender postprocess
if not already toon-compatible, place in `client/assets/models/furniture/`
or `client/assets/models/props/` per actual category, register in
`manifest.json`. This IS the promotion act (D-241) — nothing stays
"promoted" in `spikes/`. `props/vw_beetle.glb` does **not** take this path;
it stays out of scope per §1 (Q-067 car deferral). (b) **New-asset path**,
standard: `/image-gen` concept → `/glb-gen` (Trellis) → Blender postprocess
`client/assets/models/{furniture,props}/` + `manifest.json`. Both paths
converge on the same manifest registration step.
## 5. Acceptance
3 starter assets enter `models.md` + `manifest.json` at `planned`: the 3
existing spike GLBs (`spikes/3dpipeline/models/furniture/`), promoted and
renamed per §3 — this satisfies acceptance without generating anything new,
since the prior art already exists and simply hasn't crossed the promotion
boundary. Note for the story: whether a `generic_furniture`/`generic_prop`
**4 promotable GLBs** enter `models.md` + `manifest.json` at `planned`: the
3 existing spike furniture GLBs (`spikes/3dpipeline/models/furniture/`),
promoted and renamed per §3, plus `spikes/3dpipeline/models/props/
lion_statue.glb`, promoted as-is (no rename, no mask). This satisfies
acceptance without generating anything new, since the prior art already
exists and simply hasn't crossed the promotion boundary. **Excluded from
this count:** `spikes/3dpipeline/models/props/vw_beetle.glb` — a car, held
under the Q-067 deferral in `deferred.md`, not promoted by this brief's
story. Note for the story: whether a `generic_furniture`/`generic_prop`
placeholder parent becomes a formal fallback-chain member (mirroring D-235's
wall/roof/facade/street pattern) is exactly Q-119's open question ("generic
door/floor/furniture parents") — **milestone-0 IF Q-119 resolves yes**, not
@@ -96,4 +116,5 @@ resolved by this brief.
- `docs/assets/visual/models.md` — target catalog
- `client/assets/models/manifest.json`
- `spikes/3dpipeline/models/furniture/` — existing unpromoted prior art (3 GLBs)
- `spikes/3dpipeline/models/props/` — existing unpromoted prior art; `lion_statue.glb` in scope (this brief), `vw_beetle.glb` excluded (Q-067 car deferral, see `deferred.md`)
- D-241 — spike binaries local-only; promotion = repo-canonical
+6 -1
View File
@@ -33,7 +33,12 @@ _64.png` — all pre-D-244, sprite-era output. This brief's job is to re-run
that same wall through the current 3D-model pipeline (D-244), not sprite
renders, and register it as the class's first manifest entry. Out of scope:
rural walls (timber/stone/rammed-earth vernacular), doors, floors — separate
briefs.
briefs. Also out of scope, but a natural same-family follow-on once this
brief's pattern is proven: the other three D-235 building-exterior axes —
`RoofForm`, `FacadeRhythm`, `StreetSurface` — which ride this brief's own
`<object_tag>_<map_type>.png` texture convention (`conventions.md` §3) and
already have `palette.md` §3.2–§3.4 register rows; see `deferred.md`'s axis-
completeness note.
## 2. Visual Reference
+4 -3
View File
@@ -3,7 +3,7 @@ title: "Visual Palette"
description: "Phase-4 visual style bible — camera, entity colours, environmental neutrality, D-235 material register, toon/PBR rendering treatment"
type: design
status: active
decision_refs: [D-019, D-033, D-045, D-148, D-149, D-217, D-232, D-235, D-244, D-257]
decision_refs: [D-019, D-033, D-045, D-148, D-149, D-154, D-217, D-232, D-235, D-244, D-257]
author: "Araminta"
updated: 2026-07-25
---
@@ -228,7 +228,7 @@ terms they were originally written in:
| Inherited principle | Original source | Current expression |
|----------------------|------------------|----------------------|
| **D-033 entity color = relationship to player** | visual-grammar-v01.md §3 | Unchanged — still the live decision, still the single most important color system in the game. Applies to entities regardless of render fidelity (rectangle, sprite, or 3D mesh). |
| **D-033 entity color = relationship to player** | visual-grammar-v01.md §3 | **Amended by D-154 (2026-03-17):** D-033's relationship-color palette (`#4a9ebb`, `#6bc9a6`, etc.) is NOT the default entity render in normal gameplay — normal gameplay shows **uniform dark gray/black (#1a1a1a) character outlines** at all times (the outline is a pure silhouette-separation artifact, D-150's inverted-hull method, carrying zero semantic information). D-033's colors display only within the **insert/perception-mode overlay** (alongside the minimap and name bubbles) — that is the designed channel for relationship/social data, not the character outline. Applies, where it does apply (the insert/perception overlay), regardless of render fidelity. |
| **"Functional warmth"** — industrial infrastructure that people made livable, not military/not luxury | workshop-outcomes.md visual identity statements + Gore's naming | Standing mood target for the whole D-235 register above: hue ranges lean warm (terracotta, ochre, warm grey) rather than cool/clinical by default; the *cool* end of the palette is reserved for deliberately institutional template registers, not the default. |
| **Environmental neutrality — strict zero shift (D-045)** | workshop-outcomes.md §1.10 | Unchanged, still active. The D-235 material register above is diegetic/static — condition bands (D-217) shift with simulated `prosperity_score`, never with narrative/investigation state. This document adds no new exception to D-045. |
| **Entity always wins visual ties** (visual hierarchy: entity > object > structure) | visual-grammar-v01.md §1.4 / workshop-outcomes.md §1.4 | Survives as a rendering-order and saturation-hierarchy principle. In 3D terms: entity materials/outlines render at the highest effective saturation and are never occluded in a way that reads ambiguous against a similarly-toned prop. The saturation ceiling table (below) replaces the old sprite-outline-weight table. |
@@ -285,9 +285,10 @@ authored separately under T-1050).
| Decision | Relevance |
|----------|-----------|
| D-019 | Original top-down camera + offline-renderer 72.5° angle. Superseded for gameplay by D-148; survives for the offline 2D-artwork render rig. |
| D-033 | Entity color = relationship to player. Unchanged, still the primary information-bearing color system. |
| D-033 | Entity color = relationship to player. Still the primary relationship-information color system, but **amended by D-154** — displays only in the insert/perception-mode overlay, not as the default character render. |
| D-045 | Environmental neutrality — strict zero shift. Governs how the D-235 material register (§3) may and may not respond to game state. |
| D-148 | 30° low-angle gameplay `Camera3D`, supersedes D-019 for gameplay. |
| D-154 | Character outline is uniform dark gray/black at all times in normal gameplay — carries zero semantic information. Amends D-033: relationship colors move to the insert/perception-mode overlay only. See §4's corrected D-033 row. |
| D-149 | 3D characters rendered live in scene, not pre-rendered sprites. Backing precedent for §1's camera reasoning (no more sprites to render "at the angle" during play) and for §2's shared-shader-family argument (characters and environment props come off the same live-3D pipeline). |
| D-217 | Tile condition thresholds (prosperity_score bands) — the weathering-baseline mechanism referenced throughout §3. |
| D-232 | Trait-template catalog — era reframed as maintenance/wear + past-vogue holdover, not a material-tech ladder. Backing rationale for retiring the Era 1/2/3 ladder in §5. |
+13 -6
View File
@@ -67,10 +67,16 @@ Read `decisions/architecture.md` (primary) and `decisions/perception.md`
(secondary — the still-live camera/color/neutrality bedrock). Key decisions:
- **D-033:** Entity color = relationship to player (unknown teal, friendly
green, POI amber, hostile red) — active, unchanged since 2026-02-11. The
single most important color system in the game; applies at any render
fidelity. Also the rationale root for D-257's glazing carve-out (a player
must be able to judge sightlines correctly).
green, POI amber, hostile red) — active, amended by **D-154** (2026-03-17,
confirmed): the relationship-color palette displays **only within the
insert/perception-mode overlay**; normal gameplay renders all character
outlines as a uniform dark gray/black (`#1a1a1a`) that carries zero
semantic information (an inverted-hull silhouette, D-150). Read both
records together — D-033 defines the palette and its meaning, D-154
restricts *where* it's shown. Still the single most important color
system in the game; applies at any render fidelity, but only inside the
insert channel. Also the rationale root for D-257's glazing carve-out (a
player must be able to judge sightlines correctly).
- **D-045:** Environmental neutrality — strict zero shift. Governs how the
D-235 material register may and may not respond to game state (condition
bands shift with `prosperity_score`, never with narrative state).
@@ -143,7 +149,7 @@ be organized, this is the model to check against first.
deferral note, not briefs — they're Phase-6-adjacent set-dressing, not
blocking the walkable-exterior deliverable.
2. **D-257 glazing shader implementation — unassigned.** The ruling is
recorded (palette.md §2.3, D-257); nobody has yet built the minimal-PBR
recorded (palette.md §2.12.2, D-257); nobody has yet built the minimal-PBR
material variant for `glass_curtain_wall`/`industrial_glazing`. This is
implementation work waiting for an owner, not a design gap.
3. **T-1198 (backlog) — elevation-white vs ice-white grammar split.** Her own
@@ -169,6 +175,7 @@ running `/image-gen` or `/glb-gen` for real (non-spike) production assets.
- `docs/assets/briefs/` + `docs/assets/_templates/asset-brief.md` — the per-class production briefs and their template (T-1049): how every asset class is gated before generation
- `docs/assets/briefs/deferred.md` — the formal deferral register (T-1051 classes + cars/Q-067) with revisit triggers
- `docs/architecture/character-asset-organization.md` — the proven pipeline reference model
- `decisions/architecture.md` — D-148, D-149, D-217, D-228, D-232, D-235, D-244, D-255, D-257
- `decisions/architecture.md` — D-148, D-149, D-150, D-217, D-228, D-232, D-235, D-244, D-255, D-257
- `decisions/perception.md` — D-019 (superseded for gameplay), D-033, D-045
- `decisions/scope.md` — D-154 (D-033's insert-only display amendment)
- `docs/workshops/body-map-viewer/` — D-255 design record, measurement appendix, her co-design contribution