Tile-level floor plans with sightline analysis for all three Sova Transit District locations. Unblocks copy team content packs #190, #191, #192. - spatial-layout-terminal-v01.md: The Terminal (44×28m), scanner bays, main corridor chokepoint, manifest processing, cargo floor, supervisor office with window, restricted storage. Sightline table, access tiers, NPC traffic density, Triangle 1 + 2 service notes. - spatial-layout-bar-v01.md: The Last Shift (28×22m + eastern extension). Corner booth sightline analysis (sees entrance, bar, card table, back room door simultaneously). Bathroom corridor as private exchange zone. Triangle 3 + 4 service notes. - spatial-layout-smuggling-corridors-v01.md: Ring infrastructure overlay — restricted storage staging, maintenance corridor network, three dead-drop locations with discovery vectors, transition corridor (40m) with camera constraint and traffic density. Full operation flow diagram. Also carries forward minor visual-grammar and placeholder-spec corrections from earlier in the sprint (wall_top tile spec, cursor D-056 attribution, transition strip procedural generation clarification). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
235 lines
11 KiB
Markdown
235 lines
11 KiB
Markdown
# 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.
|