Delivers #303 (v0.1 Visual Grammar Document) and #252 (Placeholder Art Spec). #303 — visual-grammar-v01.md - 7 sections: zone color palettes (hex values, Zone 1/2/3), entity sizing/proportions (24x32px art area in 64x64px canvas, dual-scale grid per D-066), entity color system (D-033 relationship colors, transition behavior, saturation hierarchy), z-level rendering stack (8 layers, y-sort rules, wall rendering, overhead occlusion), typography baseline (Michroma at 4 role sizes, dialogue layout per D-061), animation tier baseline (D-047 Tier 1/Tier 2 with frame budgets), neural insert overlay (D-048 geometric/bloom spec, detective vs smuggler variants, fog interaction, insert-off behavior per D-056/D-057 OQ-07). - Closes #304 (entity color system spec — covered in §3). - Unblocks #311, #312, #313, #314, #315, #316, #317, #318, #334. #252 — placeholder-art-spec-v01.md - Tile dimensions: 64x64px visual tile, 32x32px sim tile, 1080p base resolution. - Structural tile colors per zone, object tile spec (tinted rectangles + labels). - Entity sprite spec: 24x32px art in 64x64px canvas, color-via-shader (no baked colors). - Animation scope: static placeholder in v0.1, production frame budgets documented. - File format (PNG with alpha), asset directory structure, naming convention. - Lighting constraints: no baked lighting, Light2D pipeline does all atmosphere. - Unblocks #133 (placeholder art pipeline). Cross-references: D-033, D-043, D-044, D-045, D-046, D-047, D-048, D-049, D-052, D-056, D-057, D-059, D-061, D-066. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
10 KiB
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) |
| Door (closed) | 64×64 px | Same as wall face, 4px lighter | 1px #333340 |
| Door (open) | 64×64 px | Same as floor | 1px #333340 at threshold edge |
Transition strips (zone boundary tiles): blend between zone floor colors over 1 tile width. Simple 50/50 split or gradient between the two zone floor colors.
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)
door_closed.png # 64×64px
door_open.png # 64×64px
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.