Standardized YAML frontmatter on all 40 docs/design/ files with title, description, type, status, ticket, decision_refs, and author fields. Covers specs, wireframes, voice cards, spatial layouts, and system designs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
11 KiB
title, description, type, status, ticket, decision_refs, author, created, updated
| title | description | type | status | ticket | decision_refs | author | created | updated | |||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Placeholder Art Specification v0.1 | Technical requirements for procedural placeholder art assets with zero image files | design | active | #133 |
|
Araminta | 2026-02-19 | 2026-02-19 |
The Settled Reach — Placeholder Art Specification v0.1
Version: v0.1 (Sprint 12)
Author: Araminta (Visual Designer)
Date: 2026-02-19
Status: Active — unblocks #133 (placeholder art pipeline)
Cross-reference: docs/design/visual-grammar-v01.md (visual grammar — this document derives from it)
This specification defines the technical requirements for placeholder art assets. v0.1 target: zero image files. All placeholder art is procedural — colored rectangles, styled text, shader overlays. This spec defines what the placeholder pipeline must produce so it can be swapped for real art without architectural changes.
1. Grid and Tile Dimensions
1.1 Dual-Scale Grid (D-066)
| Scale | Unit | Size | Used by |
|---|---|---|---|
| Simulation tile | 0.5m per tile | 32×32px (internal) | Server: movement, LOS, pathfinding, occupancy |
| Visual tile | 1m per tile = 2×2 sim tiles | 64×64px at runtime | Client: all art authoring, tile placement |
Author all art at 1m visual tile scale = 64×64px per tile. The simulation subdivides automatically. The pipeline does not need to know about 32×32 sim tiles.
1.2 Runtime Resolution
| Context | Value |
|---|---|
| Visual tile size | 64×64 px |
| Game base resolution | 1920×1080 (1080p) |
| Godot camera | Orthographic, no DPI scaling applied to tile grid |
| Camera zoom | 1:1 at 1080p (1 viewport pixel = 1 art pixel) |
Do not target Retina/HiDPI resolutions with placeholder art — that's a production phase concern.
2. Tile Art Requirements
2.1 Structural Tiles (Floor, Wall, Door)
All structural tiles are solid colored rectangles in v0.1. No texture, no grain. Color palette from visual grammar §1.2–1.4.
| Tile type | Size | Color | Outline |
|---|---|---|---|
| Floor — Logistics Hub | 64×64 px | #1a1e24 |
None |
| Floor — Bar | 64×64 px | #1e1912 |
None |
| Floor — Corridor | 64×64 px | #181818 |
None |
| Wall face | 64×64 px | Zone wall face color (see visual grammar §1) | None (outlines added via LightOccluder2D geometry) |
| Wall top | 64×64 px | Zone wall top color (see visual grammar §1) | None. Rendered on z-layer 4 at ~70% opacity (D-049). Creates overhead occlusion. |
| Door (closed) | 64×64 px | Same as wall face, 4px lighter | 1px #333340 |
| Door (open) | 64×64 px | Same as floor | 1px #333340 threshold outline baked into the sprite at the doorway edge |
| Transition strip | 64×64 px | 50/50 horizontal split between adjacent zone floor colors | None. Procedurally generated per zone boundary — not a hand-authored asset. |
Transition strips (zone boundary tiles): generated procedurally at runtime as a horizontal 50/50 split between the two adjacent zone floor colors. No hand-authored asset required — the pipeline produces these from zone adjacency data. If a simple split reads poorly, upgrade to a 4-pixel dithered blend.
2.2 Object Tiles (Furniture, Equipment)
Objects are tinted rectangles with a text label in v0.1. Label identifies the object type.
| Object category | Size (visual tiles) | Fill color | Outline | Label |
|---|---|---|---|---|
| Small item | 1×1 | #8b8ba0 at 60% opacity |
1px #333340 |
Object name, 10px Michroma |
| Furniture | 1×1 or 2×1 | #8b8ba0 at 70% opacity |
1px #333340 |
Object name, 10px Michroma |
| Large furniture | 2×1 or 3×1 | #8b8ba0 at 70% opacity |
1px #333340 |
Object name, 10px Michroma |
| Terminal | 1×1 | #4a5a7a at 80% opacity |
1px #4a9ebb |
"TERMINAL", 10px Michroma |
| Cargo crate | 1×1 or 2×1 | #6a5a3a at 70% opacity |
1px #8b7a5a |
"CARGO", 10px Michroma |
Label placement: centered in the object rectangle. If the object is too small for a label, omit it. Legibility over completeness.
3. Entity Sprite Requirements
3.1 Sprite Canvas and Art Area
| Property | Value |
|---|---|
| Canvas size | 64×64 px (= 2×2 sim tiles, 1×1 visual tile footprint) |
| Art area | 24×32 px, centered within canvas |
| Dead space | 20px left, 20px right, 16px top, 16px bottom |
| Outline | 2px in D-033 relationship color |
Dead space is intentional — it provides clearance so entities don't visually merge when sharing adjacent tiles.
3.2 Placeholder Entity Shape
In v0.1, all entities are tinted rectangle + outline + name label:
- Rectangle: 24×32px, centered in 64×64 canvas
- Fill: D-033 relationship color at 90% opacity
- Outline: 2px D-033 relationship color at 100% opacity
- Label: NPC name or "Player", 11px Michroma,
#e8eaf0, centered below rectangle (within canvas dead space)
The label goes below the art rectangle, within the canvas — it's the name badge of the placeholder, not a floating HUD element. When sprites replace rectangles, labels are removed from the canvas and handled separately by the HUD.
3.3 Color Source
Entity fill and outline color are driven entirely by the client's derived relationship state — not baked into the asset. The placeholder pipeline produces one generic rectangle shape; color is applied as a Godot shader parameter at runtime. This ensures the placeholder and the sprite system are architecturally identical.
Implementation: entity_color shader uniform, set per entity per frame from ObserverSnapshot.relationship_state.
3.4 Player Character Placeholder
Same spec as NPC placeholder, with these overrides:
| Property | Detective | Smuggler |
|---|---|---|
| Fill color | #e0e8ff at 90% |
#e8e0d0 at 90% |
| Outline | 2px #e0e8ff |
2px #e8e0d0 |
| Label | "YOU (DET)" | "YOU (SMU)" |
4. Animation Frame Requirements
4.1 v0.1 Animation: None
All entities in v0.1 are static placeholder sprites — no animation. The animation tier system (D-047, visual grammar §6) defines what gets built for production art, not for placeholders.
The placeholder pipeline must produce single-frame sprites. Do not build animation infrastructure for placeholder sprites.
4.2 Production Target (for pipeline planning)
When placeholder sprites are replaced, the pipeline must support:
| Tier | Entity type | Frame budget | Directions |
|---|---|---|---|
| Tier 1 (Active NPC) | Named + generic | 8 frames walk, 2–3 idle | 2 drawn (N/S), 2 mirrored (E/W) |
| Tier 2 (Background NPC) | Generic only | 1 frame (static) | 1 direction, no mirroring needed |
| Player | Both characters | Same as Tier 1 NPC | 2 drawn + 2 mirrored |
Frame format for production sprites: PNG strip (horizontal), 64×64px per frame, filename convention: entity_{name}_{direction}_{action}.png (e.g., entity_kael_south_walk.png).
5. Color Palette Constraints
5.1 What the Placeholder Pipeline Produces
The pipeline does not bake colors into assets. It produces shape templates that accept color as a runtime parameter (shader uniform or Godot modulate). This matches the production principle from D-043: "Sprites are shape templates that the lighting system completes."
5.2 Color Sources
| Asset type | Color source |
|---|---|
| Entity fill + outline | entity_color uniform from RelationshipState (per entity, per frame) |
| Object fill | Fixed per object type (see §2.2 table) |
| Floor tiles | Fixed per zone (see visual grammar §1) |
| Insert overlay | #c8d0e0 chrome + D-033 relationship colors for entity markers |
| Fog shader | Driven by LOS mask, not a color constant |
5.3 What Not to Do
- Do not hardcode entity colors in art assets
- Do not add zone-specific color variants of the same object shape — zone lighting handles the emotional temperature
- Do not add object colors that compete with entity saturation (see visual grammar §3.6)
6. File Format and Asset Organization
6.1 Format
| Context | Format | Notes |
|---|---|---|
| All placeholder sprites | PNG | Alpha channel required for entity canvas dead space |
| Production sprites (future) | PNG | Same. DDS conversion deferred to Phase 4 |
| Shader assets | .gdshader in client/shaders/ |
Not part of placeholder art pipeline |
6.2 Asset Directory Structure
client/assets/
art/
placeholder/
tiles/
floor_logistics.png # 64×64px, solid #1a1e24
floor_bar.png # 64×64px, solid #1e1912
floor_corridor.png # 64×64px, solid #181818
wall_face.png # 64×64px, solid (zone-parameterized at runtime)
wall_top.png # 64×64px, solid (zone wall top color, rendered at ~70% opacity on z-layer 4)
door_closed.png # 64×64px
door_open.png # 64×64px (threshold outline baked in)
objects/
obj_generic.png # 64×64px grey rectangle (color via modulate)
obj_terminal.png # 64×64px tinted, "TERMINAL" label
obj_crate.png # 64×64px tinted, "CARGO" label
entities/
entity_generic.png # 64×64px, 24×32 art area (color via shader)
entity_player.png # 64×64px, same — player uses same shape
production/ # Empty in v0.1, populated in Phase 2–4
6.3 Naming Convention
{category}_{identifier}.png
- Category:
floor_,wall_,obj_,entity_,door_ - Identifier: zone or type name, lowercase, underscores
- No version suffixes in filename — versions are tracked by git
6.4 Source Dimensions
Placeholder art is authored at 64×64px final size — no resolution chain. Production art will use the 1024px → 256px → 64px resolution chain (D-043) when AI-generated assets enter the pipeline. The placeholder pipeline does not need to support this chain.
7. Lighting Constraints for Placeholder Art
Sprites must be authored as flat, neutral-lit shapes so Godot's Light2D pipeline completes the mood. Do not bake:
- Shadows (directional or point-source)
- Lighting gradients (bright on one side, dark on other)
- Ambient occlusion
- Any lighting that implies a specific light source direction
The PointLight2D pipeline (D-046) does all of this at runtime. Baked lighting in sprites will fight the runtime lighting and produce incoherent results as the player moves.
Test: Drop a placeholder tile into a dark Godot scene with a single PointLight2D. The tile should look correct — lit on the side facing the light, dark on the far side. If it looks wrong, the sprite has baked lighting.
8. Phases Reference
From the briefing — for pipeline planning:
| Phase | Focus | Target |
|---|---|---|
| Phase 1 (current) | Structural | Tile floor plans, entity rectangles, fog rendering. Blocks gameplay testing. |
| Phase 2 | Information | Insert overlay, monologue display, dialogue panel, sound indicators. Blocks content testing. |
| Phase 3 | Atmosphere | Zone palettes, lighting, span gate glow, character insert variants. Blocks experience testing. |
| Phase 4 | Polish | Sprite replacements, animations, particles. Pre-release. |
v0.1 target: Phases 1–3. Zero image files — everything procedural. This spec covers Phase 1 asset requirements. Phases 2 and 3 derive from the visual grammar and will be addressed in subsequent tickets.