diff --git a/docs/assets/README.md b/docs/assets/README.md index eca4af308..38d277540 100644 --- a/docs/assets/README.md +++ b/docs/assets/README.md @@ -26,6 +26,8 @@ docs/assets/ audio.md # Row template + detailed entry template for audio sprite.md # LEGACY object-sprite row template (D-244 retired sprites; model/texture/artwork rows are inline in each visual/*.md file, T-1050) video.md # Row template + detailed entry template for video + asset-brief.md # One-page per-class brief template (scope/visual reference/naming/gen path/acceptance) — T-1049 + briefs/ # Per-asset-class briefs gating T-961's child stories (T-1049) + deferred.md formal deferral note audio/ README.md # Audio pipeline index — categories, status summary palette.md # Sonic palette, aesthetic guide, generation approach @@ -62,3 +64,6 @@ docs/assets/ - Decision files: `decisions/` (D-038 audio scope, D-033 entity colors, D-019 camera angle) - Art direction workshop: `docs/workshops/art-direction-mood-board/` - Sprint briefings: `docs/sprints/sprint-N/{team}.md` +- Per-class asset briefs: [briefs/](briefs/) — station walls, rural walls, doors, floors, + furniture/props, each gating a T-961 child story (T-1049); [briefs/deferred.md](briefs/deferred.md) + records the formal deferral for lamp posts / TVs / billboards / barns (T-1051) + cars (Q-067). diff --git a/docs/assets/_templates/asset-brief.md b/docs/assets/_templates/asset-brief.md new file mode 100644 index 000000000..084c3e2f5 --- /dev/null +++ b/docs/assets/_templates/asset-brief.md @@ -0,0 +1,71 @@ +--- +title: "Asset Brief — {Class Name}" +description: "{One-line: which manifest category and D-235 axis (if any) this class covers}" +type: design +status: active +ticket: "" # e.g. "T-NNN" (the child story this brief gates) +decision_refs: [] # e.g. [D-235, D-244, D-257] +author: "Araminta" +created: YYYY-MM-DD +updated: YYYY-MM-DD +--- + +# Asset Brief — {Class Name} + +One page. Gates the story below — a story with no linked brief does not enter +`in_progress`. Cite standing conventions/palette rows; do not restate them. + +--- + +## 1. Scope + +{Which manifest category (`furniture` | `props`, or "N/A — building-exterior +texture, no manifest entry") and which D-235 ObjectTag axis (wall/roof/facade/ +street), if any. State plainly what this class IS and is NOT — e.g. "station +walls, not rural walls" — so the story can't scope-creep into a sibling +brief's territory.} + +## 2. Visual Reference + +{Cite `palette.md` §3's register row(s) for the relevant D-235 token(s) — +hue range, grain, weathering baseline — by tag name, no restating the table. +For classes with no D-235 token, cite `palette.md` §2 (toon default) or the +D-257 glazing carve-out if the class includes glass/polished metal. Note any +mood/reference touchstone specific to this class if palette.md doesn't +already cover it.} + +## 3. Naming + +{Cite `conventions.md` §1 (`_.glb` model naming), §2 +(mask sidecar, single-channel vs RGBA multi-region) if tintable, §4 +(`footprint_tiles` manifest field) if multi-tile. Give 1-2 concrete example +filenames for this class. Note any class-specific naming wrinkle (e.g. door +state handling — §5's negative constraint) rather than inventing new rules.} + +## 4. Generation Path + +{The standing path: `/image-gen` concept → `/glb-gen` (Trellis) → Blender +postprocess → promotion into `client/assets/models/{furniture,props}/` + +`manifest.json` entry. Note class-specific concept-prompt guidance only if +it differs from the standard `/image-gen` style-guide block (toon-shaded, +near-white base, plain dark background, 3/4 front view). Note whether this +class instead runs the `textures.md` (PBR standalone) or `artwork.md` (flat +2D) pipeline if it's not a `.glb` model.} + +## 5. Acceptance + +{N starter assets entering `models.md` (or `textures.md`/`artwork.md`) and +`manifest.json` at `planned` status. List them by name if known, or state +the count + selection principle (e.g. "the generic fallback parent + 2 +specific tokens"). Note the Q-119 milestone-0 caveat if relevant: generic +parents are milestone-0 IF Q-119 resolves yes — do not resolve Q-119 here.} + +--- + +## Cross-References + +- `docs/assets/visual/conventions.md` — naming/mask/footprint rules +- `docs/assets/visual/palette.md` — D-235 color/material register, toon/PBR treatment +- `docs/assets/visual/models.md` (or `textures.md`/`artwork.md`) — the catalog this brief feeds +- `client/assets/models/manifest.json` — the machine-readable registry +- `.claude/skills/glb-gen/SKILL.md`, `.claude/skills/image-gen/SKILL.md` — production pipeline diff --git a/docs/assets/briefs/deferred.md b/docs/assets/briefs/deferred.md new file mode 100644 index 000000000..3a05da6af --- /dev/null +++ b/docs/assets/briefs/deferred.md @@ -0,0 +1,107 @@ +--- +title: "Deferred Asset Classes" +description: "Formal deferral note — lamp posts, barns, TVs, billboards (T-1051), and cars (Q-067) — not briefed this batch" +type: design +status: active +ticket: "T-1051" +decision_refs: [D-166, D-235] +author: "Araminta" +created: 2026-07-25 +updated: 2026-07-25 +--- + +# Deferred Asset Classes + +This is the formal deferral record for five asset classes named in the T-750 +epic description that do **not** get a one-page brief this batch: **lamp +posts, TVs, billboards, barns** (T-1051's four classes) and **cars** +(Q-067). This note is what lets T-1051 close as delivered-by-deferral (its +own acceptance criterion — "author briefs, **or record formal deferral**" — +is satisfied by this file) and records the rationale so a future re-scope +pass doesn't have to re-derive it. + +--- + +## The four T-1051 classes: lamp posts, TVs, billboards, barns + +**Rationale.** Phase 4's cascade deliverable is "deterministic walkable-world +data + per-layer Atlas maps + asset catalog" (`CLAUDE.md` cascade table). +Outside-in generation (D-166) needs building **exterior templates** — the +D-235 wall/roof/facade/street axes — to make districts/blocks walkable and +Atlas-legible. None of these four classes are a wall/roof/facade/street axis +token: + +- **Lamp posts** (street furniture) and **TVs/billboards** (signage/screens) + are set-dressing objects that populate an *already-walkable* exterior or + interior — they read as Phase 6 "detail coloring / room-level population" + (cascade table), or at best late-Phase-4 polish once exteriors exist to + place them against. +- **Barns** are a rural *building type*, not a material/form/rhythm/surface + axis token — D-235's vocabulary describes what a wall/roof/facade/street + looks like, not what kind of building a set of walls forms. A barn's walls + and roof would draw from the same `rural-walls.md` brief's tags + (`timber_wall`, `rammed_earth_wall`) plus a roof tag; there is no separate + "barn" asset class to brief independent of that. + +**No partial work is lost by deferring.** T-1049's own 2026-06-12 audit +matrix confirms zero repo hits for any of the four beyond the T-750 epic +description text — no ticket, no brief, no produced asset, no style-guide +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. + +## Cars (Q-067) + +**Rationale, same shape, one added layer.** Cars are also set-dressing/ +transport infrastructure that presupposes walkable exteriors — same Phase-4- +vs-later argument as the four above. Cars additionally carry a genuinely +**open design question**: Q-067 ("Vehicle physics for in-world transport") +has not decided whether the game needs driveable vehicles, NPC-only traffic, +or neither, nor whether vehicle movement is client-side physics or +server-authoritative. A car asset brief would have to assume an answer to a +question that is explicitly still open — Q-067's own audit note (2026-06-12, +S-47) already flagged this: "Scope for v0.2: probably not" (and v0.2 is +dropped per `CLAUDE.md`), recommending the phase question be answered before +any car brief is written. + +**Distinction from the T-1051 four, in degree not kind.** The four above need +no open question resolved — their deferral is a pure scope/sequencing call +(exteriors first). Cars need Q-067 resolved *in addition to* that same +sequencing call. Only vehicle artifact today: `spikes/3dpipeline/models/ +props/vw_beetle.glb` (a spike binary, untracked per D-241 — not production +prior art). + +**Disposition.** Formal deferral. Blocked on Q-067 resolution in addition to +Phase-4 exterior-generation completion. + +--- + +## Revisit trigger + +**Revisit all five classes when Phase-4 exterior generation is complete** — +i.e. when the tile/chunk/block cascade is producing walkable districts/ +blocks with building exteriors drawn from the D-235 axes (the point at which +set-dressing has something real to populate). For cars specifically, revisit +is additionally gated on **Q-067 resolving** to a driveable-vehicles-in-scope +answer; if Q-067 resolves "no vehicles" or "NPC-traffic-only, no player +asset," the car brief may never be needed in the form this note anticipates. + +## Precedent + +This deferral treatment mirrors the **Q-067 precedent already established** +in T-1049's refinement history: file a scope note now, do not write a brief +against an undecided mechanic or an unwalkable world, and let the phase +cascade (D-166) — not a milestone label — be the thing that reopens the +question when its gating condition is met. + +--- + +## Cross-References + +- T-1051 — the ticket this note satisfies ("author briefs, or record formal deferral") +- T-1049 — parent refinement ticket; "Lead ratification" note ratifies this deferral disposition +- Q-067 — open question, vehicle physics/mechanic scope +- D-166 — outside-in generation cascade (geo → economic/exterior → building templates → door contracts → Phase-6 interiors) +- D-235 — building-exterior visual grammar (wall/roof/facade/street axes; barns/lamp-posts/TVs/billboards are not axis tokens) +- `docs/assets/briefs/rural-walls.md` — barns' actual wall/roof material draws from this brief's tags, when barns are eventually built diff --git a/docs/assets/briefs/doors.md b/docs/assets/briefs/doors.md new file mode 100644 index 000000000..fedfeb053 --- /dev/null +++ b/docs/assets/briefs/doors.md @@ -0,0 +1,91 @@ +--- +title: "Asset Brief — Doors" +description: "Door models — no D-235 ObjectTag axis; logical DoorSpec exists, runtime open/closed mechanism deferred to Phase 5" +type: design +status: active +ticket: "" +decision_refs: [D-231, D-244, D-257] +author: "Araminta" +created: 2026-07-25 +updated: 2026-07-25 +--- + +# Asset Brief — Doors + +One page. Gates its child story — the story does not enter `in_progress` +without this brief attached. + +--- + +## 1. Scope + +Door **models** (`furniture` or `props` manifest category — a door is a +fitted architectural object, closer to `props`; the manifest's `category` +field is authoritative regardless of subdirectory per `conventions.md` §1). +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 +struct definition only, not visual. This brief covers the **visual asset** +only; it does not touch T-979/T-998's derivation logic. + +## 2. Visual Reference + +No D-235 token to cite — doors take `palette.md` §2's toon default (same +shader family as characters/furniture: `toon.gdshader` or `toon_masked +.gdshader`, `roughness=1.0`/`specular=0.0`). A door with a glazed panel +(e.g. a station door with a window) falls under the §2.1 glazing carve-out +if the pane is gameplay-load-bearing for sightlines — treat that panel as a +separate material slot at minimal-PBR, the rest of the door stays flat toon. +No dedicated door row exists in palette.md §3's material register (that +table only covers wall/roof/facade/street) — if a door's finish should match +its host building's wall material (e.g. a timber door on a `timber_wall` +building), that is a future content-authoring choice, not something this +brief specifies. + +## 3. Naming + +`_.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 +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 +(`_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 + +Standard path: `/image-gen` (toon-shaded concept, 3/4 front view, closed-door +pose since there is no baked open state) → `/glb-gen` (Trellis) → Blender +postprocess → promotion into `client/assets/models/props/` + `manifest.json` +entry. No texture-only alternative here — a door is inherently a discrete +mesh, not a tileable surface. + +## 5. Acceptance + +2 starter assets enter `models.md` + `manifest.json` at `planned`: (1) +`door_hinged` — the generic single-leaf door, the closest thing this class +has to a D-235-style fallback default even though no `generic_door` tag is +formally ratified (Q-119's text lists "generic door/floor/furniture parents" +as a candidate milestone-0 set alongside the ratified `generic_wall/roof/ +facade/street` — **milestone-0 IF Q-119 resolves yes**, not resolved here); +(2) `door_sliding` — matches the `workshop-outcomes.md` §3.3 `door_sliding` +prior-art mention and a plausible station-context default. Both ship as one +model each, no state-frame variants, per §3's negative constraint. + +--- + +## Cross-References + +- `docs/assets/visual/conventions.md` §1, §2, §5 — model naming, mask sidecar, door-state negative constraint +- `docs/assets/visual/palette.md` §2 — toon default, glazing carve-out if applicable +- `docs/assets/visual/models.md` — target catalog +- `client/assets/models/manifest.json` +- T-979/T-998 (D-231) — the logical `DoorSpec`/`InteriorDescriptor` this brief's visual asset will eventually attach to (Phase 5, not this brief's scope) diff --git a/docs/assets/briefs/floors.md b/docs/assets/briefs/floors.md new file mode 100644 index 000000000..e0e62b88a --- /dev/null +++ b/docs/assets/briefs/floors.md @@ -0,0 +1,90 @@ +--- +title: "Asset Brief — Floors" +description: "Floor surface textures — D-228 FloorMaterial axis, no D-235 ObjectTag (interior/ground-surface, not building-exterior)" +type: design +status: active +ticket: "" +decision_refs: [D-228, D-244, D-257] +author: "Araminta" +created: 2026-07-25 +updated: 2026-07-25 +--- + +# Asset Brief — Floors + +One page. Gates its child story — the story does not enter `in_progress` +without this brief attached. + +--- + +## 1. Scope + +Floor **surface textures** — the D-228 `FloorMaterial` axis (built surface +over ground: `None`/`Concrete`/`Pavement`/`Carpet`/`Metal`/… — an open, +extensible vocabulary owned by the tile-fill layer, not D-235). This is a +**different axis than D-235's `StreetSurface`** (outdoor paved/cobble/ +packed-earth streets) — floors are the interior/indoor-adjacent ground +surface a character walks on inside a building footprint. No prior art +beyond `placeholder-art-spec-v01.md` §2.1's 4 sprite-era floor placeholders +and `workshop-outcomes.md` §3.3's mention (both pre-cascade, superseded +production model per D-244). Out of scope: street surfaces (D-235 axis, +folded into whichever wall/facade brief's district ends up owning street +dressing — not this brief), doors, furniture footprints. + +## 2. Visual Reference + +No D-235 register row exists for `FloorMaterial` (palette.md §3 only covers +wall/roof/facade/street) — floors take `palette.md` §2's toon default +(flat-lit, `roughness=1.0`/`specular=0.0`) with **one exception mirroring the +§2.1 glazing carve-out logic**: a `Metal` floor with a genuinely +polished/mirror finish (rare, e.g. a showroom) would need the same +minimal-PBR treatment for the same functional reason (a flat-toon mirror +floor misleads the player about reflections the way flat-toon glass misleads +about sightlines) — this is a narrow, judgment-call extension of an existing +carve-out, not a new rule; most `Metal` floors (deck plating, catwalk) stay +flat toon. `Concrete`/`Pavement` should read consistently with `palette.md` +§3.1's `concrete_wall` warm-neutral-grey register even though there is no +formal floor row — reuse that hue family for visual coherence between wall +and floor in the same room, rather than picking an unrelated grey. + +## 3. Naming + +Texture: `_.png` shape from `conventions.md` §3, +substituting the `FloorMaterial` value for the object_tag slot since floors +aren't D-235-vocabulary-keyed — e.g. `concrete_floor_basecolor.png`, +`carpet_floor_basecolor.png`, `metal_floor_normal.png`. No standalone floor +*model* — floors are always a tileable surface, texture-only, no Trellis +step. No mask sidecar (material register drives color, not tint); no +`footprint_tiles` (a floor texture tiles across the tile grid, it doesn't +have a discrete multi-tile footprint the way a piece of furniture does). + +## 4. Generation Path + +Texture-only path: `/image-gen` produces a flat, tileable concept at the +target hue/grain (no 3/4-view object framing — a floor concept should be a +top-down or straight-on flat material swatch) → lands directly in +`textures.md`, no `/glb-gen`/Trellis step (there is no mesh to convert). +Concept prompts should explicitly request a **seamlessly tileable** surface +pattern — the standard `/image-gen` style block doesn't cover tiling by +default and needs an explicit add-on instruction for this class. + +## 5. Acceptance + +3 starter assets enter `textures.md` at `planned`: (1) `concrete_floor` — +the most common interior default, reusing the `concrete_wall` warm-grey hue +family per §2; (2) `pavement_floor`; (3) `carpet_floor` — the class's first +non-hard-surface test case (different grain/weathering behavior than the +masonry-derived floors). No generic-fallback-parent entry applies here — the +Q-119 generic-parent question is scoped to the ratified D-235 axes plus "door/ +floor/furniture parents" it names as a candidate extension; if that +extension is adopted (Q-119 resolves yes), a `generic_floor` placeholder +becomes milestone-0 for this class too, but that decision is not made here. + +--- + +## Cross-References + +- `docs/assets/visual/conventions.md` §3 — texture naming shape (adapted for non-ObjectTag axis) +- `docs/assets/visual/palette.md` §2, §3.1 — toon default + glazing-carve-out logic, wall hue-family reuse +- `docs/assets/visual/textures.md` — target catalog +- D-228 — `FloorMaterial` axis definition (override-stack: wild → economic → user mutator) diff --git a/docs/assets/briefs/furniture-props.md b/docs/assets/briefs/furniture-props.md new file mode 100644 index 000000000..d1f017c7c --- /dev/null +++ b/docs/assets/briefs/furniture-props.md @@ -0,0 +1,99 @@ +--- +title: "Asset Brief — Furniture / Props" +description: "Interior furniture and small props — manifest categories furniture|props, spike prior art exists unpromoted" +type: design +status: active +ticket: "" +decision_refs: [D-241, D-244, D-257] +author: "Araminta" +created: 2026-07-25 +updated: 2026-07-25 +--- + +# Asset Brief — Furniture / Props + +One page. Gates its child story — the story does not enter `in_progress` +without this brief attached. + +--- + +## 1. Scope + +Freestanding interior objects — the manifest's two categories, `furniture` +(tables, chairs, storage — occupies a footprint, usually multi-tile) and +`props` (smaller/decorative objects — usually single-tile). No D-235 +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 +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). + +## 2. Visual Reference + +`palette.md` §2 — furniture and props are explicitly named as sharing the +character toon treatment (`toon.gdshader`/`toon_masked.gdshader`, +`roughness=1.0`/`specular=0.0` default from `postprocess_glb.py:: +setup_materials()`), **with the standing glazing/polished-metal carve-out** +(§2.1) applying to any prop that is deliberately glass or mirror-finish +(a display case, a chrome fixture) — minimal-PBR (`roughness` 0.05–0.2, +controlled specular), same rule as building glazing, not a new one. §4's +"functional warmth" mood target and the object-tier saturation ceiling +(entity > object > structure, §4 table) both apply directly: furniture/prop +colors stay moderate saturation, below entity color but the class is allowed +more personality than the structural material register (the +`shuttered_facade` accent-color precedent is the closest analogue — object- +tier is where a saturation bump is permitted, unlike wall/roof/street). + +## 3. Naming + +`_.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: `_mask.png`, single-channel, per §2 — the +existing Trellis convention, just reordered. `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]`. + +## 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 +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` +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 +resolved by this brief. + +--- + +## Cross-References + +- `docs/assets/visual/conventions.md` §1, §2, §4 — category-first naming ruling, mask sidecar, footprint metadata +- `docs/assets/visual/palette.md` §2, §4 — toon/PBR treatment, saturation-ceiling hierarchy +- `docs/assets/visual/models.md` — target catalog +- `client/assets/models/manifest.json` +- `spikes/3dpipeline/models/furniture/` — existing unpromoted prior art (3 GLBs) +- D-241 — spike binaries local-only; promotion = repo-canonical diff --git a/docs/assets/briefs/rural-walls.md b/docs/assets/briefs/rural-walls.md new file mode 100644 index 000000000..a8304becd --- /dev/null +++ b/docs/assets/briefs/rural-walls.md @@ -0,0 +1,90 @@ +--- +title: "Asset Brief — Rural Walls" +description: "Building-exterior wall models/textures for rural/vernacular settlement types — D-235 wall axis" +type: design +status: active +ticket: "" +decision_refs: [D-235, D-244, D-257] +author: "Araminta" +created: 2026-07-25 +updated: 2026-07-25 +--- + +# Asset Brief — Rural Walls + +One page. Gates its child story — the story does not enter `in_progress` +without this brief attached. + +--- + +## 1. Scope + +Building-exterior **wall** surfaces for rural/vernacular/frontier settlement +types — the D-235 `WallMaterial` axis tags a rural-type template's `allow` +filter selects (`stone_wall`, `timber_wall`, `rammed_earth_wall`, +`stucco_wall`, `brick_wall` — the "vernacular/agrarian" register). No prior +art exists for this class beyond the T-961 epic text mention (2026-06-12 +audit matrix) — unlike `station-walls.md`'s sibling, this is a clean-slate +brief. Out of scope: station/urban walls (`concrete_wall`, `steel_frame`, +`glass_curtain_wall`, `composite_panel` — sibling brief), barns (a rural +building *type*, not a wall-axis token — deferred, see `deferred.md`), doors, +floors. + +## 2. Visual Reference + +`palette.md` §3.1 rows for `stone_wall`, `timber_wall`, `rammed_earth_wall`, +`stucco_wall`, `brick_wall` — every one of these tags is explicitly warm-hued +(warm grey-tan, warm mid-brown, ochre-to-umber banding, warm off-white sand, +warm terracotta-to-ochre) and the table is explicit that `stone_wall` is +D-235's flagship "gets it wrong if literal" case — **never render it cool +grey**. This is the register where the "functional warmth" mood target +(`palette.md` §4) reads most directly — rural walls are the class most likely +to be mistaken for a generic cool-grey default if a generation pass isn't +told otherwise. `generic_wall` (§3.5) is the shared fallback terminal with +`station-walls.md` — one placeholder texture serves both siblings until +specific tags ship. + +## 3. Naming + +Texture: `_.png` per `conventions.md` §3 — e.g. +`stone_wall_basecolor.png`, `stone_wall_normal.png`, `timber_wall_basecolor.png`, +`rammed_earth_wall_basecolor.png`. If a standalone wall-segment model is +produced (rural walls are more likely to need a discrete model than station +walls, given rammed-earth's strong horizontal banding reads better as +geometry+texture than texture-only), it follows §1's `_ +.glb` (e.g. `wall_structural_timber.glb`) with the same `props`-category +placement as its station sibling. No tint mask — material register (not +player-favorite color) drives these hues. + +## 4. Generation Path + +Standard path: `/image-gen` → `/glb-gen` (Trellis) → Blender postprocess → +`client/assets/models/props/` + `manifest.json`, OR the texture-only path +(`/image-gen` concept, no Trellis step) landing in `textures.md` — same +choice as `station-walls.md` §4, decided per-tag based on whether the +material's character (rammed-earth banding, stone coursing) needs real +geometry or reads fine as a flat PBR map. Concept prompts for this class +should explicitly state the target hue family from §2 (warm, not cool-grey) +since Gemini's default "concrete/stone" association skews cool without that +steer. + +## 5. Acceptance + +3 starter assets enter `models.md`/`textures.md` + `manifest.json` at +`planned`: (1) `stone_wall` texture — the flagship warm-hue worked example, +highest risk of a cool-grey miss without explicit review; (2) `timber_wall` +texture; (3) `rammed_earth_wall` texture (the banding signature makes it a +good early test of whether the texture-only path is sufficient or a modeled +relief is needed). `generic_wall` is shared with `station-walls.md` — do not +duplicate it in this class's count; **milestone-0 IF Q-119 resolves yes** +(not resolved here). + +--- + +## Cross-References + +- `docs/assets/visual/conventions.md` §1, §3 — model naming, D-235-keyed texture naming +- `docs/assets/visual/palette.md` §3.1, §4 — wall material register, "functional warmth" mood target +- `docs/assets/visual/models.md`, `docs/assets/visual/textures.md` — target catalogs +- `client/assets/models/manifest.json` +- `docs/assets/briefs/station-walls.md` — sibling brief, shares `generic_wall` fallback diff --git a/docs/assets/briefs/station-walls.md b/docs/assets/briefs/station-walls.md new file mode 100644 index 000000000..b2996452d --- /dev/null +++ b/docs/assets/briefs/station-walls.md @@ -0,0 +1,95 @@ +--- +title: "Asset Brief — Station Walls" +description: "Building-exterior wall models/textures for station (urban/industrial) settlements — D-235 wall axis" +type: design +status: active +ticket: "" +decision_refs: [D-235, D-244, D-257] +author: "Araminta" +created: 2026-07-25 +updated: 2026-07-25 +--- + +# Asset Brief — Station Walls + +One page. Gates its child story — the story does not enter `in_progress` +without this brief attached. + +--- + +## 1. Scope + +Building-exterior **wall** surfaces for station/urban/industrial settlement +types — the D-235 `WallMaterial` axis, specifically the tags a station-type +template's `allow` filter selects (`concrete_wall`, `steel_frame`, +`glass_curtain_wall`, `composite_panel` — the "built infrastructure" register, +not the rural/vernacular tags owned by the sibling `rural-walls.md` brief). +This is **prior-art territory**: `wall_structural.tscn` +(`renderer/models/wall_structural.tscn`) already exists as an unrendered GLB, +plus rendered PNG samples at `docs/workshops/art-direction-mood-board/ +pipeline-samples/wall_structural_south_{64,256,1024}.png` and the promoted +sprite set at `client/assets/sprites/wall_structural_{north,south,east,west} +_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. + +## 2. Visual Reference + +`palette.md` §3.1 rows for `concrete_wall`, `steel_frame`, +`glass_curtain_wall`, `composite_panel` — warm-leaning neutral greys (never +cool-grey), fine aggregate speckle / riveted-joint / seam-grid textures per +tag, D-217 weathering ladder per row. `glass_curtain_wall` is the §2.1 +minimal-PBR carve-out (roughness 0.05–0.2, controlled specular) — every other +tag in this set stays flat toon (`roughness=1.0`/`specular=0.0`, +`postprocess_glb.py::setup_materials()` default). `generic_wall` (§3.5) is the +flat neutral-grey, no-grain fallback terminal for whichever specific tag +hasn't shipped yet. + +## 3. Naming + +Model: `_.glb` — this class is a building-exterior +surface, so it more commonly ships as a **texture**, not a standalone prop: +`concrete_wall_basecolor.png` / `_normal.png` / `_roughness.png` +(`conventions.md` §3), plus `generic_wall_basecolor.png` as the fallback +placeholder. If a standalone wall-segment **model** is also produced (as +`wall_structural` already is, pending re-promotion), it follows §1's +`_.glb` (e.g. `wall_structural_concrete.glb`) with a +`_mask.png` sidecar only if a tintable variant is needed (most station +walls are not tinted — material register drives color, not player-favorite +tint). No `footprint_tiles` metadata applies to a wall texture; a wall +*segment model*, if produced, is single-tile. + +## 4. Generation Path + +Standard path: `/image-gen` (toon-shaded concept, 3/4 front view, near-white +base) → `/glb-gen` (Trellis) → Blender postprocess → promotion into +`client/assets/models/props/` (a wall segment is a `props`-category model +per `conventions.md` §1's category-is-manifest-authoritative rule) + +`manifest.json` entry. If shipping as a standalone **texture** instead +(the more likely first deliverable, since walls are usually a tiled surface +not a discrete mesh), the target file is `textures.md`, not `models.md` — +author a flat concept via `/image-gen` at the material's hue/grain per §2, +no Trellis step needed for a pure 2D PBR map. + +## 5. Acceptance + +3 starter assets enter `models.md`/`textures.md` + `manifest.json` (as +applicable) at `planned`: (1) `generic_wall` fallback placeholder texture — +flat neutral grey, no grain, per palette.md §3.5 — **milestone-0 IF Q-119 +resolves yes** (not resolved here); (2) `concrete_wall` texture, the most +common station tag; (3) re-promotion of the existing `wall_structural` model +through the current (non-sprite) pipeline, closing out the only piece of +partial prior art this class has. Status flips to `in-progress`/`final` as +each is actually produced. + +--- + +## Cross-References + +- `docs/assets/visual/conventions.md` §1, §3 — model naming, D-235-keyed texture naming +- `docs/assets/visual/palette.md` §2, §3.1 — toon/PBR treatment, wall material register +- `docs/assets/visual/models.md`, `docs/assets/visual/textures.md` — target catalogs +- `client/assets/models/manifest.json` +- `renderer/models/wall_structural.tscn` — existing unrendered prior art (this class) diff --git a/docs/assets/visual/README.md b/docs/assets/visual/README.md index c5500d3a5..9fd1d3542 100644 --- a/docs/assets/visual/README.md +++ b/docs/assets/visual/README.md @@ -26,6 +26,17 @@ Per **[D-244](../../../governance/decisions/architecture.md#d-244)**: the in-wor Naming, mask-sidecar, D-235-keyed texture, and multi-tile footprint conventions: [conventions.md](conventions.md). +## Per-Class Briefs + +Each asset class entering production is gated on a one-page brief — +[../briefs/](../briefs/) — covering scope, visual reference, naming, +generation path, and acceptance (template: [../_templates/asset-brief.md](../_templates/asset-brief.md)). +Briefed this batch (T-1049): [station walls](../briefs/station-walls.md), +[rural walls](../briefs/rural-walls.md), [doors](../briefs/doors.md), +[floors](../briefs/floors.md), [furniture/props](../briefs/furniture-props.md). +Formally deferred (not briefed): lamp posts, TVs, billboards, barns, cars — +see [../briefs/deferred.md](../briefs/deferred.md). + ## Palette See [palette.md](palette.md) for art direction: camera (D-148 gameplay / D-019