Review round (Hoshe + Tyre, both REQUEST_CHANGES) fully addressed: palette.md's glass carve-out re-keyed from retired never-shipped tokens (precision_glass/smart_facade) to the ratified glass_curtain_wall (wall) + industrial_glazing (facade); the toon/PBR treatment promoted from a docs-only ruling to D-257 (architecture, cross-refs D-235/D-244/D-043/ D-044/D-033) with palette.md §2 now citing it as authority; D-149 + D-257 added to decision_refs; manifest.json _comment gains the explicit underscore-prefix loader skip contract; master pipeline table Visual row Stub -> Active; conventions.md mask pointer Section 3 -> 5; pre-existing broken D-066 links in the mood-board transcript repaired (leave-cleaner). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
165 lines
7.9 KiB
Markdown
165 lines
7.9 KiB
Markdown
---
|
|
title: "Visual Asset Conventions"
|
|
description: "Model naming, mask sidecars, D-235-keyed texture naming, and multi-tile footprint metadata for the 3D asset pipeline"
|
|
type: design
|
|
status: active
|
|
---
|
|
|
|
# Visual Asset Conventions
|
|
|
|
Single home for 3D-model and texture naming conventions (D-244 — the in-world
|
|
view renders 3D objects directly; there is no per-object sprite layer). This
|
|
file is the cross-link target from `.claude/skills/glb-gen/SKILL.md` and the
|
|
catalog files in `docs/assets/visual/`.
|
|
|
|
---
|
|
|
|
## 1. Model naming
|
|
|
|
Format: `<category>_<descriptor>.glb`
|
|
|
|
Examples: `table_baroque.glb`, `chair_modernist.glb`, `door_sliding.glb`.
|
|
|
|
**Ruling (delegated to Araminta, art seat, batch-5 activation — T-1052):
|
|
category-first, not descriptor-first.** Rationale: category-first matches
|
|
the shipped, in-active-use character-asset clothing convention
|
|
(`<category>_<descriptor>` — `jacket_modern.glb`, `boots_modern.glb`,
|
|
`pants_formal.glb`, all live under `client/assets/characters/clothing/`) and
|
|
gives every future asset browser/manifest a stable alphabetical grouping by
|
|
type (all tables sort together, all chairs sort together). The 3dpipeline
|
|
spike's descriptor-first naming (`baroque_table.glb`, `modernist_chair.glb`,
|
|
`spikes/3dpipeline/README.md`) was pre-convention scratch work, not a
|
|
precedent to preserve — D-241 already treats spike naming as disposable at
|
|
promotion time. **Surfaced to Jeroen for cheap veto** (lead delegation note,
|
|
T-1050).
|
|
|
|
`category` is the subdirectory-agnostic object type (`table`, `chair`,
|
|
`door`, `lamp`, `statue`); `descriptor` distinguishes style/variant
|
|
(`baroque`, `modernist`, `sliding`). Category is not required to match the
|
|
`furniture`/`props` subdirectory name — a `statue` and a `table` can both be
|
|
`furniture` or both be `props` depending on where they land; the manifest's
|
|
`category` field, not the filename, is authoritative for that split.
|
|
|
|
---
|
|
|
|
## 2. Mask sidecars
|
|
|
|
Convention: `<model>_mask.png`, single-channel (R-only greyscale), sitting
|
|
next to the GLB — per the character-asset convention (Section 5,
|
|
`docs/architecture/character-asset-organization.md`). White = tintable
|
|
region, black = preserve original texture (`hint_default_black`: no mask
|
|
loaded = no tinting; assets without a mask render with their original
|
|
Trellis/authored texture).
|
|
|
|
Example: `table_baroque.glb` + `table_baroque_mask.png` (this is the existing
|
|
Trellis convention already proven in the 3dpipeline spike, just re-ordered to
|
|
category-first per Section 1's ruling).
|
|
|
|
**Multi-region tinting.** If a single-channel mask is insufficient (an item
|
|
needs more than one independently-tintable region), follow the RGBA
|
|
channel-routed convention from `character-asset-organization.md` Section 11
|
|
(T-1089) — R/G/B/A → four independent tints, cross-fading correctly under
|
|
bilinear filtering — rather than reinventing a greyscale-band scheme (that
|
|
approach was tried for clothing and rejected; see that doc's Section 5
|
|
correction). This is the same mechanism, not a parallel one: environment
|
|
props reuse the clothing pipeline's multi-region shader family rather than
|
|
inventing a props-specific one.
|
|
|
|
---
|
|
|
|
## 3. Texture naming (D-235 tokens)
|
|
|
|
PBR surface maps for building-exterior and environment surfaces are named by
|
|
the ratified **ObjectTag vocabulary** (D-235 amendment, T-995,
|
|
`wiki/economics/object_tag_vocabulary.toml`), **not** the retired
|
|
`renderer/README.md` `<model>_<direction>_<resolution>.png` scheme. That
|
|
scheme is direction-indexed for the retired 4-direction sprite render
|
|
(`renderer/README.md`'s now-legacy object-sprite mode) and does not apply to
|
|
PBR texture maps at all — there is no "direction" for a texture, only **map
|
|
type** (basecolor / normal / roughness).
|
|
|
|
Format: `<object_tag>_<map_type>.png`
|
|
|
|
Map types: `basecolor`, `normal`, `roughness`. (`metallic` and `ao` may be
|
|
added if a material needs them; keep the same `<object_tag>_<map_type>`
|
|
shape.)
|
|
|
|
Examples, drawn from the D-235 ratified tags:
|
|
- `concrete_wall_basecolor.png`, `concrete_wall_normal.png`, `concrete_wall_roughness.png`
|
|
- `pitched_roof_normal.png`
|
|
- `stone_wall_basecolor.png`
|
|
- `generic_wall_basecolor.png` (fallback-terminal placeholder — D-235's
|
|
fallback hierarchy: every specific tag degrades to a `generic_*` parent
|
|
until the specific texture ships, then upgrades in place)
|
|
|
|
The full ratified axis lists (wall/roof/facade/street + the four `generic_*`
|
|
fallback terminals) live in `wiki/economics/object_tag_vocabulary.toml` —
|
|
this doc does not duplicate that list; it names the file-naming convention
|
|
that keys off it.
|
|
|
|
---
|
|
|
|
## 4. Multi-tile footprint metadata
|
|
|
|
A table or couch spans multiple sim tiles regardless of whether it's
|
|
rendered as a sprite or a 3D model — this requirement survived the D-244
|
|
pivot unchanged. It is **not** expressed as a filename convention (a
|
|
sprite-era assumption); it is a `manifest.json` field:
|
|
|
|
```json
|
|
"footprint_tiles": [2, 1]
|
|
```
|
|
|
|
`[width, height]` in whole tiles (1 tile = 1m, D-243's voxel unit). Single
|
|
Sunday-tile props omit the field or set it to `[1, 1]`. See
|
|
`client/assets/models/manifest.json`'s `_fields` block for the authoritative
|
|
field definition alongside the rest of the per-asset schema.
|
|
|
|
---
|
|
|
|
## 5. Deferred — door state handling (NOT authored here)
|
|
|
|
**Do not port a state-frame suffix convention** (e.g. `door_open.glb` /
|
|
`door_closed.glb`). An earlier draft of this ticket (2026-06-16, since
|
|
superseded) proposed exactly that — baked open/closed GLB variants — which is
|
|
sprite-era thinking (baked state = baked frame) carried over from the retired
|
|
object-sprite model.
|
|
|
|
For a 3D object, the door's open/closed/locked/sealed state (T-979/T-998's
|
|
`DoorSpec`: `Open` / `Closed` / `TemporalWindow` / `Locked` / `Sealed`) is a
|
|
**runtime transform/animation on one door `.glb`**, not separate baked
|
|
models. The actual mechanism — `AnimationPlayer` swing vs. procedural hinge
|
|
rotation vs. a door-model convention with a named "open" bone — is a
|
|
**Phase-5 rendering decision** (player control + in-world rendering, per the
|
|
cascade), not a Phase-4 asset-catalog concern.
|
|
|
|
This doc records only the negative constraint above (no state-frame suffix
|
|
files). The positive mechanism is deferred to whichever Phase-5 ticket
|
|
handles door rendering — do not invent a runtime convention here.
|
|
|
|
---
|
|
|
|
## 6. Deferred — Godot TileSet resource organization (OUT OF SCOPE)
|
|
|
|
A `<tileset>/<tile_id>.tres` convention is **out of scope for this doc and
|
|
this phase**, removed from the ticket that spawned this file. Reason:
|
|
`client/scripts/rendering/tile_renderer.gd`'s `TileSet` is an
|
|
explicitly-labeled placeholder ("programmatic TileSet with placeholder
|
|
colored rectangles," D-014), and the cascade rule (`CLAUDE.md`) states the
|
|
current in-world rendering code is "left as-is until Phase 5 — do not build
|
|
on it or rip it out before then." Authoring a `.tres` resource-organization
|
|
convention now would mean building on Phase-5-owned code from Phase 4. This
|
|
section is intentionally not written; a future Phase-5 ticket owns it.
|
|
|
|
---
|
|
|
|
## Cross-References
|
|
|
|
- [D-244](../../../governance/decisions/architecture.md#d-244-asset-rendering--3d-objects-in-world-2d-limited-to-textures--flat-artwork) — 3D objects in-world; 2D limited to textures + flat artwork.
|
|
- [D-241](../../../governance/decisions/process.md#d-241-spike-binary-artifacts-are-local-only--gitignored-never-tracked) — spike binaries local-only; promotion = repo-canonical.
|
|
- [D-235](../../../governance/decisions/architecture.md#d-235-building-exterior-visual-grammar-and-material-vocabulary) — ObjectTag vocabulary, ratified in `wiki/economics/object_tag_vocabulary.toml` (T-995).
|
|
- [D-243](../../../governance/decisions/architecture.md#d-243) — spatial scale ladder (1m voxel/tile unit for `footprint_tiles`).
|
|
- `docs/architecture/character-asset-organization.md` — Sections 3, 5, 11 (mask sidecar precedent, multi-region RGBA convention).
|
|
- `client/assets/models/manifest.json` — the schema this doc's naming/metadata conventions feed.
|
|
- `.claude/skills/glb-gen/SKILL.md` — the production pipeline that writes to `client/assets/models/`.
|