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>
25 KiB
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 |
|
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 | 8–10 visual tiles | Wide, efficient workplace coverage |
| Outline (global) | #333340 |
Dark blue-grey. Applied at 4–8px 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 | 5–6 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 | 4–5 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, 3–4 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 (~15–20° 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 20–25 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 (2–3px 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: 40–60% | #4a9ebb, #6bc9a6, #e8c547, #d45d5d |
| Objects (D-052 favorites) | Moderate: 15–30% | Dusty blue, warm terracotta, faded olive (muted register) |
| Structure (zone palette) | Low: 5–15% | 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 0–4. Does NOT affect layers 6–7. |
| 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 |
2–4 | 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 | 2–3 frames | Subtle breathing cycle. Not distracting. |
| Walk | 8 frames (2 directions × 4 frames, mirrored for L/R) | Interpretation of D-047's "4–6 directional frames" range: 4 frames per drawn direction (N/S), mirrored for E/W = 8 total frames in the animation strip. |
| Working at terminal | 2–3 states | Key-tap, pause, review. Readable as "doing their job." |
| Handling cargo | 2–3 states | Lift, carry, set down. |
| Eating / drinking | 2–3 states | Raise, consume, lower. Readable as "on break." |
| Talking | 2–3 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 500–2,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: ~2–3px 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 | 1–2px | 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 2–3px gaussian | 40% blend at 2–3px 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 0–4. 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)