Files
settled-reach/docs/design/visual-grammar-v01.md
T
jpmschweitzerandClaude Fable 5 7d5a774fa5 docs(assets): Phase-4 visual style bible in palette.md (T-1052)
Authors the full style bible: camera table separating D-148 gameplay from
D-019 offline-renderer use; the delegated toon-vs-PBR ruling (environment
props share the character toon treatment, with a minimal-PBR carve-out for
glass/polished metal so sightlines read truthfully under occlusion-based
perception); a color/material register for every D-235 ObjectTag (hue,
grain, D-217-keyed weathering); and explicit supersession notes both ways
with visual-grammar-v01.md and the mood-board workshop transcript.
Includes branch-side pql changelog rows (T-1050/T-1052 -> review); the
worktree pre-commit export step failed benignly (write-through had
already refreshed the files) so they are staged explicitly here.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 20:20:21 +02:00

25 KiB
Raw Blame History

title, description, type, status, ticket, decision_refs, author, created, updated, superseded_by
title description type status ticket decision_refs author created updated superseded_by
v0.1 Visual Grammar Source of truth for all v0.1 visual decisions: zone palettes, entity colours, z-level stack, typography, and animation tiers design superseded
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
Araminta 2026-02-19 2026-02-20 D-235/D-228, docs/assets/visual/palette.md

SUPERSEDED (2026-06-12, cascade-refocus sweep): superseded by D-235/D-228 (generated-world visual grammar) + docs/design/character-visuals-spec.md (character rules). Kept as historical record; do not build against it.

Style-bible pointer (2026-07-25, T-1052): the live Phase-4 style bible is docs/assets/visual/palette.md. Its §4/§5 spell out exactly what survives from this document (D-033 colors, "functional warmth," the visual-hierarchy/saturation principles) versus what's superseded (the sprite-era production model: entity sprite sizing, the 8-layer sprite z-stack, sprite typography sizing, animation frame counts, the resolution chain, and — specifically — the three-construction-era material ladder in §1.2–§1.4, which D-235 retired by name: "Era is NOT a material filter here"). Read palette.md first; come back here only for historical attribution.

The Settled Reach — v0.1 Visual Grammar

Version: v0.1 (Sprint 12) Author: Araminta (Visual Designer) Date: 2026-02-19 Status: Active — unblocks #304, #311, #312, #313, #314, #315, #316, #317, #318, #334

This document is the source of truth for all visual decisions in v0.1. Every subsequent visual deliverable references this document. If a decision here conflicts with a local assumption, this document wins. Open a ticket to amend it if the assumption is right.

Core principle (D-043): "Sprites are shape templates that the lighting system completes." No baked shadows, no baked lighting, no baked mood. The world is lit by Godot's Light2D pipeline; sprites carry shape and saturation, not atmosphere.


1. Color Palette — Zone Palettes and Global Constants

1.1 What the Environment Communicates

Per D-045 (environmental neutrality), the world layer never shifts in response to narrative state, conspiracy activation, or investigation progress. Zone palettes are fixed. The only information signals that can change are entity colors (§3), insert overlay density (§7), and monologue urgency. A player walking into the bar after discovering the conspiracy finds it still warm and amber. That indifference is intentional.

What communicates narrative state: entities (D-033 colors). What communicates mood: lighting (D-046 three-reference model). The environment communicates location, not drama.

1.2 Zone 1 — Logistics Hub (The Terminal)

Character: cool grey-navy institutional. Era 1 and Era 2 construction. CanvasModulate is the global ambient between light pools; all visible floor and wall color is revealed by PointLight2D fixtures at cool white temperature.

Element Hex Notes
Floor tile #1a1e24 Dark cool grey-navy, Era 1 composite panels
Wall face #2a3040 Medium navy-grey, visible under tilt angle
Wall top #222838 Slightly darker than face; top surface of wall
Ambient (CanvasModulate) #0e1218 The darkness between light pools. Very dark cool blue-grey.
Fixture light color #c8d8f0 Cool institutional white-blue
Fixture radius 810 visual tiles Wide, efficient workplace coverage
Outline (global) #333340 Dark blue-grey. Applied at 48px at 256px working resolution.

Era 2 modifications (retrofits, junction boxes, modified partitions) share the same floor tile but use #6d7178 for surface-mounted elements — slightly warmer than Era 1's #7a7f85, reflecting different production run.

1.3 Zone 2 — Bar (The Last Shift)

Character: warm dark, amber-lit, Era 3 construction. Irregular by design (D-043, "functional warmth"). The warmth is Lera's accumulated decisions, not zone theming — placement and density carry the feeling.

Element Hex Notes
Floor tile #1e1912 Dark warm brown-grey, worn composite panels
Wall face #2c2018 Medium warm brown, Era 3 variation
Wall top #221810 Darker warm brown
Ambient (CanvasModulate) #100c08 Warm near-black. The bar is darker between pools — intimacy, not gloom.
Fixture light color #f0b840 Warm amber — social, inhabited (D-046 Blade Runner reference)
Fixture radius 56 visual tiles Pooled, intimate. Light doesn't reach every corner.
Outline (global) #333340 Same outline as all zones — consistency is non-negotiable

1.4 Zone 3 — Transition Corridors

Character: neutral dark, dim irregular lighting. Original Era 1 construction, maintained not renovated. Emptier because no one settled it (D-051 — "settling is placement").

Element Hex Notes
Floor tile #181818 Neutral dark grey, industrial grating
Wall face #242424 Medium neutral dark
Wall top #1a1a1a Marginally darker
Ambient (CanvasModulate) #0c0c0c Near-neutral black. The coldest ambient.
Fixture light color #d0d8e0 Cold dim white. Maintenance grade.
Fixture radius 45 visual tiles Sparse, uneven. Gaps between pools are wider.
Outline (global) #333340 Same as all zones

1.5 Global Color Constants

These are not zone-specific. They apply everywhere.

Constant Hex Usage
Outline standard #333340 All sprites, all zones, all layers
Insert chrome #c8d0e0 Default insert HUD color (cursor, grid lines, non-relationship data)
Unexplored wireframe #333340 Same as outline — geometric map app aesthetic
Unexplored (no map) #12141a Solid near-black. Information zero.

1.6 What Doesn't Get a Color

Danger, safety, tension, conspiracy — none of these get palette representation in the environment. They're carried by entities (§3) and insert density (§7). If you find yourself wanting to tint a tile orange because something bad happened there, that's the environment doing work it's not supposed to do.


2. Entity Sizing and Proportions

2.1 Grid Context

The dual-scale grid (D-066) separates simulation resolution from visual presentation:

  • Simulation tile: 0.5m. All server-side logic (movement, LOS, pathfinding, occupancy) operates here.
  • Visual tile: 1m = 2×2 sim tiles. All client-side art is authored at this scale. 1 visual tile = 64×64 pixels at runtime.
  • Retina factor: 2×. The simulation knows nothing about visual tiles — that's a client rendering convention.

2.2 Entity Sprite Dimensions

Property Value Notes
Sprite footprint 2×2 sim tiles Entities visually span one full visual tile (64×64px)
Sprite art area 24×32 px Active art within the 64px canvas. Clear figure-ground against tile.
Occupancy 1×1 sim tile Character occupies half a visual tile for sub-tile positioning precision
Player sprite 24×32 px art, 64×64 canvas Same as NPC — no special sizing
Named NPC 24×32 px art, 64×64 canvas + 1 silhouette feature Kael: vest ridge. Lera: apron shape. Sera: uniform collar.
Generic NPC 24×32 px art, 64×64 canvas, 34 template silhouettes Rotated/mirrored from template set

Why 24×32 and not 32×32 or 64×64: Entities must read clearly against the background without visually consuming the tile. Too large = visual clutter when multiple entities share an area. Too small = unreadable at a glance. 24×32 is the figure-ground minimum that keeps silhouette readable.

Tilt implication (D-019 amendment): The Rimworld shallow tilt (~1520° from vertical) means sprites are authored with south-facing front faces. Draw 2 sprite directions: front-facing (south) and back-facing (north). Left/right are mirrors of these. The Godot camera is purely orthographic; the tilt is a drawn convention in the art.

2.3 Static Object Sizing

Object type Minimum footprint Outline
Small items (mug, comm, datapad) 1×1 visual tile 1px #333340
Furniture (chair, terminal, crate) 1×1 to 2×2 visual tiles 1px #333340
Large furniture (bar counter, desk array) 2×1 to 3×1 visual tiles 1px #333340
Structural (walls, doors) 2×2 sim tile minimum (= 1×1 visual tile) Minimal to none

Hard rule (D-066): All walls, furniture, crates, and doors occupy a minimum of 2×2 sim tiles. This ensures visual truth and sim truth agree on cover and LOS occlusion. No structural element is narrower than one visual tile.

2.4 Player Indicator

Both player characters use their D-033 base color as primary identification (see §3). There is no separate player indicator sprite in v0.1 — the player character is just an entity with distinct D-033 coloring and, eventually, a distinctive silhouette.

Character Entity sprite color Notes
Detective #e0e8ff (cool, faint blue-white) Institutional, analytical register
Smuggler #e8e0d0 (warm, faint amber-cream) Social, camouflage register

These are deliberately desaturated. The player should read clearly but not dominate the palette.


3. Entity Color System

This section covers #304 content. Ticket #304 is closed by this document.

3.1 Core Principle

Entity color encodes the player character's subjective relationship to an NPC — not an objective property of the NPC. The same NPC can appear as different colors to the detective and the smuggler. Color is a client-side derivation from RelationshipState component + knowledge state (D-033). The server never sends "this NPC is red" — it sends the information that the client derives color from.

This is asymmetric information rendered visually. It's the most important system in the game to get right.

3.2 Relationship Color Palette

Relationship state Color Hex Visual quality
Unknown / Neutral Cool teal #4a9ebb Default. Unassessed. Player knows they exist.
Known / Friendly Soft green #6bc9a6 Trusted. Known person. Could still be THE FRIEND.
Person of Interest Warm amber #e8c547 Something flagged this person. Monologue or case file.
Hostile / Dangerous Muted red #d45d5d Player character perceives subjective danger. Not omniscient.
Static objects Muted grey #8b8ba0 Furniture, equipment, environmental. Non-person.

Red means danger to your character, not danger in the abstract. A detective might see amber (person of interest) where the smuggler sees green (trusted colleague) for the exact same NPC. Both are correct — from their position.

3.3 Player Characters

Character Color Hex
Detective Cool blue-white #e0e8ff
Smuggler Warm cream #e8e0d0

Player colors are deliberately near-neutral. They should read as "self" without the loaded meaning of the NPC colors.

3.4 Transition Behavior

Color shifts are 0.5-second smooth fades. Never instant. The visual transition IS the information delivery — the player reads the relationship changing, not a sudden color swap.

THE FRIEND's first shift (green → amber) must be the first relationship color change in the session. Stage the opening 2025 minutes so no other relationship state change precedes it. This is wow moment #3 (D-039); the visual punch depends on the player having already internalized what green means.

3.5 Interaction with Insert Overlay

In the insert overlay (z-layer 6, §7), entity D-033 colors gain soft halos (23px gaussian blur at ~40% blend). In the natural vision layer (z-layer 3), they're rendered with 2px outline in the relationship color — hard edge, no bloom. The bloom is the insert's interpretation; the hard edge is the player's naked eye.

3.6 Saturation Hierarchy

Entity D-033 colors are the most saturated elements in any scene. Object-layer favorite colors (D-052) must stay below D-033 entity saturation to preserve visual hierarchy.

Hierarchy tier Saturation range Examples
Entity (D-033) High: 4060% #4a9ebb, #6bc9a6, #e8c547, #d45d5d
Objects (D-052 favorites) Moderate: 1530% Dusty blue, warm terracotta, faded olive (muted register)
Structure (zone palette) Low: 515% Zone floors, wall faces, tiles

Never introduce an object color that competes with entity color saturation.


4. Z-Level Rendering Stack

4.1 The 8-Layer Stack

Per D-049. Layers are Godot CanvasLayer z-indices. Higher index = renders on top.

Z-index Name Contents Notes
0 Floor tiles Zone floor panels, grating, transition strips Muted zone palette. Lowest saturation. No outlines on floors.
1 Floor objects Cosmetic floor detail (dirt, markings, decals) Walked over. No gameplay interaction.
2 Furniture / placed objects Desks, chairs, crates, bar counter, terminals Y-sorted with z-layer 3 for overlap resolution
3 Entity sprites All characters (player + NPCs) Y-sorted with z-layer 2. D-033 colored. 2px outline.
4 Overhead / wall tops Pipes, ducts, signage, lighting fixtures, wall tops Semi-transparent partial occlusion (~70% opacity). Creates information gaps within known spaces.
5 Fog of perception Vision cone mask + fog shader + sound ping sprites Affects layers 04. Does NOT affect layers 67.
6 Insert overlay Lattice HUD elements, relationship markers, cursor, interaction labels Bloom-rendered. NOT masked by fog — computational, not perceptual.
7 Monologue / UI Internal monologue text, dialogue box, world menu, HUD chrome, cursor (D-056) Always visible. Top of stack.

4.2 Y-Sorting Rule

Layers 2 and 3 are y-sorted together. An entity moving behind a desk disappears correctly. An entity standing in front of a desk renders in front. The y-sort key is the entity's or object's bottom-most sim tile position.

Never override y-sort manually for specific entity/object pairs. The rule applies universally.

4.3 Wall Rendering

  • Structural walls (load-bearing, room dividers): Option B — visible top face + south-facing wall face (visible under tilt angle). Top face on z-layer 4, face on z-layer 2 boundary.
  • Interior partitions (half-walls, furniture dividers): Option A — boundary lines only. Minimal visual weight.

4.4 Overhead Occlusion

Layer 4 objects render at ~70% opacity when the player is beneath them. This creates local information gaps within otherwise known spaces (Gore's observation, D-049). An NPC behind a shelving unit in a fully explored room still partially disappears — the exploration context (fog state) doesn't grant omniscience about what's behind objects.

This is a thematic system as much as a rendering one. Don't eliminate it for "clarity."


5. Typography Baseline

5.1 Typeface

Michroma (Google Fonts, Regular 400, free for commercial use) is the sole typeface for all player-facing text in v0.1.

Michroma is geometric sans-serif — technical, clean, forward-facing without being aggressive. It fits the insert aesthetic: the character is reading their own neural lattice output. All text, including dialogue and environmental labels, renders as if through this lens. There is no "game UI font" vs "world font" — Michroma is both.

5.2 Text Size and Role Specifications

All sizes are in pixels at 1080p (1920×1080) base resolution. Godot 4 handles DPI scaling.

Text role Size Opacity Color Z-layer Notes
Dialogue — NPC speech 16px 100% #e8eaf0 7 Max width 640px (~33% at 1080p, per D-076). Left-aligned.
Dialogue — player response 14px 90% #c0c8d8 7 Below NPC speech. Up to 3 options visible.
Monologue (standard) 13px 85% #d0d4e0 7 Floats above dialogue box. Inner voice — slightly dimmer than dialogue.
Monologue (urgent) 13px 100% #e0e8f8 7 Same size, full opacity, slight bloom pulse. Urgent chime accompanies.
Environmental text 11px 70% #8899aa 24 Labels on terminals, signs, lockers. Part of the world. Muted.
HUD / insert chrome 12px 80% passive, 100% active #c8d0e0 6 Time display, insert labels, menu chrome
Interaction verbs 13px 95% D-033 color of target 6 Rendered on insert z-layer. Disappears when insert off.
Confrontation weight 15px 100% #e0e8f0 7 Same box as dialogue but heavier visual weight — wider, higher contrast frame

5.3 Dialogue Box Layout (D-061)

  • Position: Bottom of screen, full screen width (max-width)
  • Max height: 20% of screen height
  • Layout: NPC speech on top line, response options stacked below, left-aligned
  • Max visible response options: 3
  • Locked options: Invisible — player never sees what they can't access
  • No portraits: The NPC is on screen. A portrait is redundant.

Monologue on z-layer 7 floats above the dialogue box, not inside it. This spatial separation allows monologue to contradict dialogue visually — the character thinks one thing (above, inner) while the NPC speaks another (below, outer).

5.4 Text That Does NOT Get Michroma

Nothing. All text goes through Michroma. Handwritten signs, terminal readouts, personal notes — all render in Michroma at appropriate size and opacity. The fiction is that everything is mediated through the player character's neural insert perception layer.


6. Animation Tier Baseline

6.1 Two-Tier System (D-047)

The animation system has two tiers, and the boundary between them is invisible to the player. This invisibility is the mechanic: routine is readable, so deviation is noticeable, so the player can't be sure what they're seeing.

Tier 1 — Clear (Active NPCs): Publicly motivated behavior. Instantly readable from a glance. Player can determine intent.

Animation Frames Notes
Idle 23 frames Subtle breathing cycle. Not distracting.
Walk 8 frames (2 directions × 4 frames, mirrored for L/R) Interpretation of D-047's "46 directional frames" range: 4 frames per drawn direction (N/S), mirrored for E/W = 8 total frames in the animation strip.
Working at terminal 23 states Key-tap, pause, review. Readable as "doing their job."
Handling cargo 23 states Lift, carry, set down.
Eating / drinking 23 states Raise, consume, lower. Readable as "on break."
Talking 23 states Slight lean, gesture. Distinguishable from "standing near."
Sleeping 1 state Static prone. Unambiguous.

Tier 2 — Ambiguous (Background NPCs + deliberate Tier 1 ambiguity): Privately motivated behavior. Observable but not interpretable. The player sees the action but cannot determine the intention.

Behavior Appearance Ambiguity
Pausing Standing idle Break? Waiting? Watching?
Looking around Head turn (1 frame) Nervous? Checking for someone? Habit?
Lingering near location Idle near an object Interested? Positioned? Coincidence?
Changing direction Mid-path turn Remembered something? Avoiding someone?
Proximity without interaction Near entity, no Tier 1 state Protecting? Monitoring? Coincidence?

The line between tiers is the investigation mechanic. Tier 1 is the baseline everyone reads. Tier 2 is what creates the signal-from-noise problem that makes investigation interesting.

6.2 v0.1 Animation Scope

In v0.1, all entities start as colored rectangles with labels (D-014: "functional boxes with labels"). The animation system defines what gets built when we graduate past rectangles.

  • Phase 1 (current): Colored rectangle + name label. No animation.
  • Phase 2 (sprite replacement): Tier 1 walk cycle + idle for Active NPCs. Static sprite for Background NPCs.
  • Phase 4 (polish): Full Tier 1 set, Tier 2 behavioral states, player character expressions.

Background NPCs (Tier 2 only) never get animation in v0.1. They are static sprites. The cost of animating 5002,000 Background-tier NPCs is not justified when their visual presence is already deliberate and readable.


7. Neural Insert Overlay

7.1 Visual Language

The insert overlay (z-layer 6) is a geometric data layer rendered with an organic delivery:

  • Data structure: precise positioning, clean geometric lines, structured information layout
  • Neural delivery: ~23px gaussian blur at ~40% blend on the insert CanvasLayer
  • Result: "amber feels like a vague sense of concern, not a data flag" (Araminta, D-048)

The insert is not an HUD bolted onto a game. It IS the character's neural lattice. If switching it off would feel like going deaf rather than closing a window, it's working. After 10 minutes, the player should forget it's there.

7.2 Character Variants

Both characters use the same underlying system. The lattice_profile parameter on the ObserverSnapshot determines which variant renders.

Property Detective (lattice_augmented) Smuggler (lattice_baseline)
Line weight 12px 1px
Annotation density Dense — more markers, more connection lines Sparse — essential markers only
Passive opacity 80% 60%
Active opacity 100% 85%
Bloom intensity 40% blend at 23px gaussian 40% blend at 23px gaussian (same — different density, same feel)
Color D-033 relationship colors + #c8d0e0 chrome Same

The detective has augmented lattice hardware — they see more, more precisely. The smuggler has baseline — they see what they need, no more. The asymmetry isn't which colors appear, it's how much annotation the overlay generates from the same underlying data.

7.3 Fog Interaction

The insert overlay is NOT affected by the fog shader. Fog lives on z-layer 5 and masks z-layers 04. The insert (z-layer 6) and UI (z-layer 7) are not masked.

Insert markers can appear in fogged areas if the lattice has that data. A known-friendly NPC behind a wall can still appear as a green halo in the fog — the character's lattice tracks the last known position. This is insert data, not visual data. The character knows, even if they can't see.

7.4 Soft Degradation

At high perception load (multiple overlapping modes), the insert shows diegetic scan-line interference — subtle horizontal distortion at ~5% intensity. No hard cap on simultaneous perception modes. The degradation is visual warning, not mechanical punishment. Player reads it as "the insert is working hard." (D-059, D-048)

7.5 Insert-Off Behavior (D-056/D-057 — OQ-07 Resolution)

When insert_active == false:

  • Cursor shape still changes (entity hover → bracket shape, object hover → X-shape) — the character's body responds subconsciously to proximity
  • Interaction labels (z-layer 6) are suppressed — the insert doesn't process targets without activation
  • should_show_interactions() returns false
  • Insert markers in fog disappear — the lattice isn't running position tracking
  • Bloom disappears — no insert, no neural rendering pass

The character still moves and physically orients toward entities. The insert stops annotating.


Appendix A — Decision Cross-References

Decision Relevance
D-033 Entity color = relationship to player. Defines all NPC and player entity colors.
D-043 Art direction — "functional warmth." Style, asset pipeline, production principle.
D-044 Visual hierarchy (entity > object > structure). Outline weights, saturation rules.
D-045 Environmental neutrality — strict zero shift. Zone palettes never change.
D-046 Lighting — three-reference model (Darkwood, BR2049, Hopper). Zone light temperatures.
D-047 Two-tier animation system. Tier 1 clear / Tier 2 ambiguous.
D-048 Neural insert overlay visual design. Bloom spec, character variants.
D-049 Z-level rendering stack — 8 layers.
D-052 Character favorite colors — object-layer identification. Saturation constraint.
D-056 Cursor states — insert-styled geometric. Four states, 150ms transitions.
D-057 Entity interaction — vertical list, insert-styled.
D-059 Fog shader — 5 layers, knowledge-graph-driven. Fog entities spec.
D-061 Dialogue box — bottom screen, max 20% height, no portraits.
D-066 Dual-scale grid — 0.5m simulation, 1m visual, 64x64px visual tiles.

Appendix B — What This Document Does Not Cover

The following are out of scope for v0.1 visual grammar and will be specified in separate documents when unblocked:

  • Insert/HUD wireframe — dual character variants in detail (#314, blocked by this doc)
  • Monologue display system — typography animation, stacking, voice differentiation (#315)
  • Text display hierarchy — 4 content pipelines (#316)
  • Sound indicator visual design — fog-edge ping pulse (#317)
  • THE FRIEND visual treatment — after Paula's NPC profiles (#318)
  • Environmental text standards — sign conventions, terminal text (#334)
  • Spatial layouts — tile-level floor plans (#311, #312, #313, all blocked by this doc)