Skip to content

Art Direction Style Bible

Document Type: Art & Audio Last Updated: 2026-08-29 Vault destination: 03_Art & Audio

Status: Section 1 (Palette) locked. Remaining sections pending. Vault destination: 03_Art & Audio Supersedes: Previous voxel + cel-shade art direction


1. Palette (LOCKED)

Values derived by k-means clustering of the three reference concepts, with background pixels removed. Where the three images disagreed, Image 3 (Genesis) takes precedence as the agreed surface standard.

1.1 Core palette

Role Hex Godot Color Usage
Panel Base #EBEDEC Color(0.922, 0.929, 0.925) Primary light panels. The dominant surface.
Panel Mid #CECAC6 Color(0.808, 0.792, 0.776) Secondary panels, subtle tonal breakup
Panel Shadow #A4A19D Color(0.643, 0.631, 0.616) Underside panels, occluded faces
Structure Grey #807F7E Color(0.502, 0.498, 0.494) Struts, frames, mechanical housings
Frame Dark #535E60 Color(0.325, 0.369, 0.376) Structural frames, joint housings. Slight cool cast.
Recess #2A3132 Color(0.165, 0.192, 0.196) Panel gaps, recessed channels, shadow lines
Void Black #0B0B0E Color(0.043, 0.043, 0.055) Vents, deepest recesses, open interiors only
Accent Orange #EC983A Color(0.925, 0.596, 0.227) Clamps, trim caps, mechanical joints, hazard trim
Emissive Cyan #2ED9E8 Color(0.180, 0.851, 0.910) All powered/active indicators

1.2 Derived colours (do NOT author these)

These appear in the reference images but are lighting results, not palette entries. Never paint them into a texture.

Appears as What it actually is
#94521C / #994A0D Accent Orange in shadow
#44F3F8 → white core Emissive Cyan with bloom applied
#6E4232 Warm bounce light on grey, from orange surfaces
#2C5260 Cyan bounce light on grey, from emissive surfaces

1.3 Emissive specification

The reference images show emissive strips clipping to a white core. This is bloom, not albedo. Authoring a white strip is wrong and will look flat in engine.

  • Material emission colour: #2ED9E8
  • Emission energy: 2.5 (starting value, tune per asset scale)
  • Let the post-process bloom produce the white-hot core and the halo
  • Emissive geometry should be recessed, never flush or proud. All three references inset the strips behind a lip.

1.6 The Four Signal Channels (LOCKED)

A building communicates four things at once. Each lives in its own physical location, so no signal can ever mask another.

Where Carries Healthy Fault
Machine body Alive / working Cyan working-lights on Off
Base ring Fault status Unlit Amber or red, pulsing
Base edge tabs Mk level Always visible Always visible
Port geometry Port direction Always visible Always visible

The inversion: healthy is glowing on top with a dark edge. Broken is dark on top with a glowing edge. The health of an entire factory is readable from the balance of cyan to amber on screen, without inspecting any single building.

Superseded: an earlier draft carried Mk level on a machine-body emissive ramp (cyan → violet → magenta). That is dropped. Level is now tab count (§1.7), which keeps the palette to a single accent and needs no second colour ramp.

1.7 Mk Level — Accent Tab Count (LOCKED)

Buildings have two independent upgrade tracks, each shown by its own row of Accent Orange tabs.

Track Upgrades Tab row
Base Mk Port throughput, port filtering Outer — protruding past the footprint edge
Machine Mk Processing speed, recipe capability, module slots Inner — flush on the machine roof edge
Level Tabs per side, per row
Mk1 1
Mk2 2
Mk3 3
Mk4 4, reserved

Both rows share the same anchor and pitch. When the two levels match, the tabs line up in neat pairs. When they differ, the rows go visibly ragged. A player reads the imbalance instantly without counting anything.

Alignment rules: - Left-aligned from each side's beginning, traversing the perimeter clockwise. This makes the arrangement rotationally symmetric rather than mirrored. - Fixed inset and fixed pitch. Spacing never scales with side length, so the count reads identically on a 1×1 Buffer Chest and a 4×5 Advanced Press. The player's eye learns one location and never re-learns it. - Tabs break the silhouette deliberately. A protruding shape stays countable at distances where surface detail has already dissolved.

Why count rather than colour: counting one to three is instant (subitising), works with no colour perception at all, and requires no second colour ramp, so §1.1 stays as locked with a single accent.

Cost: a Mk3 building is the same mesh as a Mk1. Both tab rows are instanced kit pieces placed by script. The entire upgrade system, across both tracks, adds no modelling time.

1.7a Working Lights — Cyan (LOCKED)

Cyan emissive on the machine body means this machine is alive and working.

It is diegetic, not an abstract marker: windows, viewports, readouts, control panels and indicator pips belonging to that specific machine. A Mining Drill's viewport glows while it cuts. A Smelter's furnace window glows while it melts.

  • Placement is designed per building, not a shared kit strip
  • Authored via the separate emissive_mesh child that 05_Asset List & Delivery Specification already requires on every building
  • On when powered and working. Off when unpowered or manually disabled.
  • Emission colour #2ED9E8, base energy 2.5, per §1.3

Brightness carries decay. A building degraded by pollution has visibly duller working lights. A well-maintained machine glows properly, a neglected one looks tired.

Condition Emission energy
Undecayed 2.5
Fully decayed ~0.9

Scaled continuously between the two, so decay reads as a gradient rather than a step.

  • This suits decay precisely, because decay is a continuous value and brightness is a continuous channel. Binary fault states stay on the ring where they belong.
  • Across a factory, a neglected district sits visibly duller than the rest, so the player notices before going looking.
  • Brightness became available when Mk moved from an emissive ramp to tab count (§1.7). It is otherwise unused.
  • Brightness is the ambient hint, not the readout. It is deliberately weak at distance and unreliable for players with low vision. The precise figure lives in the Analytics tab. Never make brightness the only way to learn something.

This is the one functional requirement on an otherwise purely aesthetic machine top. It already existed in the asset pipeline, so it adds no new burden.

1.7b Base Ring Status (LOCKED)

Status is carried by the entire base ring perimeter, lit as one continuous band.

Why the whole ring rather than small marks: because healthy is unlit, a working factory has zero lit rings. There is no rainbow to avoid, so the fault signal can afford to be as loud as possible. A full glowing perimeter is far easier to spot than four small indicators.

Core principle: healthy is unlit.

Colour identifies the system. Rhythm identifies the severity.

State Ring Colour Pattern Body cyan
Idle Unlit On
Processing Unlit On
Output full (backed up) Lit #F5A623 Amber Slow pulse (1.6s) On
Input starved Lit #F5A623 Amber Double-blink On
Under-voltage / brownout Lit #E8433A Red Slow pulse On
No power Lit #E8433A Red Fast pulse (0.55s) Off
Manually disabled Lit, dim #5A6A72 Grey-blue Steady Off

Amber means logistics. Red means power. The two systems have completely different fixes, so grouping them by colour tells the player where to look before they read anything else.

Backed up and starved must be distinguishable. They look identical in a screenshot and are opposite problems:

  • Output full is success. Every consumer is satisfied, storage is full, the line stopped because there is nowhere left to put things. Nothing is wrong.
  • Input starved is failure. Nothing is arriving.

With priority routing (20_Belt Logistics - The Router §3a), full storage becomes a normal steady state. If both shared one signal, a healthy factory would sit permanently amber and the alarm would stop meaning anything.

Rhythm is the primary channel for players who cannot separate amber from red, which is the most common form of colour vision deficiency. Slow pulse, double-blink and fast pulse remain distinguishable with no colour perception at all.

Decay is NOT a ring state. Building degradation from pollution reduces productivity on a continuous scale, and continuous values do not belong on a binary alarm light. Decay appears as a percentage in the Analytics tab. See 26_Pollution, Waste & Organic Systems Design §4.4.

No power fires two agreeing signals at once: the ring floods red and the body cyan goes dark. Two channels confirming each other makes the most urgent fault unmistakable. Stalled lights the ring but keeps cyan on, correctly signalling a machine that has power and is simply backed up.

Blink pattern is the colourblind fallback. Amber and red are distinguishable by rhythm alone. Never ship a status that relies on hue only.

Amber and red appear nowhere else in the building palette, so status can never be mistaken for anything else.

1.7c Port Geometry — Direction (LOCKED)

Port mode is shown by built geometry, not a drawn symbol. Ports sit in a 0.25 m band on the top face of the base ring, one per port cell.

Port mode Geometry
INPUT Recessed intake slot. A dark opening cut into the base, with a shadowed lip.
OUTPUT Protruding nozzle. A raised housing breaking past the footprint edge, with a dark mouth.
DISABLED Flush cover plate. Nothing open, a single seam line across it.

Why physical rather than graphic: a flat drawn symbol lives on the surface and dissolves as soon as the camera pulls back. Built geometry changes the silhouette and casts shadow, so it survives zoom-out. It is also diegetic: real machines already read this way, since intake grilles look nothing like output chutes. This matches the same principle applied to the working lights in §1.7a.

Colour is unavailable here, which is why geometry is doing the work. Orange is the accent and the Mk tabs, cyan means alive, amber and red mean fault. Port direction must read without any of them.

Port geometry is dark neutral / structure grey and never changes colour. When the ring lights during a fault, the recesses and nozzles read as shadowed forms against the glow, so port direction stays legible during a fault instead of competing with it.

Why the top face: at a top-down gameplay camera the ring's side faces are heavily foreshortened and partly occluded by the machine body. The top face is fully visible at all times.

Cost: three small mesh variants of one kit piece, swapped per port at runtime. The building mesh is untouched, so the same-mesh-across-Mk rule survives.

⚠️ Watch: output nozzles break the silhouette, and so do the orange Mk tabs. Two different things now protrude. They differ in colour and rhythm (tabs are left-aligned and clustered, nozzles sit at port cell centres), but verify at Base Mk3 with many outputs that it does not read as clutter.

Port configuration is readable from the gameplay camera without opening any panel.

1.7d Machine Footprint Coverage

The machine body fills the footprint minus the 0.25 m chevron band on each side.

Footprint Machine body Coverage
1×1 0.5 × 0.5 m 25%
2×2 1.5 × 1.5 m 56%
3×3 2.5 × 2.5 m 69%
4×5 3.5 × 4.5 m 79%

Open items for this document are tracked in docs/open-items.md.

1.8 Usage ratio

Measured from the reference set. Treat as a target, not a hard rule.

Band Share of visible surface
Light panels (Base + Mid + Shadow) 55 to 60%
Structure and dark (Structure Grey, Frame Dark, Recess) 25 to 30%
Accent Orange 5 to 8%
Emissive Cyan 3 to 5%

Guard rail: Orange above roughly 10% makes the asset read as a hazard/warning object rather than standard equipment. Keep it on joints and trim.

1.9 Surface finish

Matched to Image 3.

Property Value
Roughness (panels) 0.55 to 0.65
Roughness (orange accents) 0.45
Roughness (dark structure) 0.70
Metallic (panels) 0.0
Metallic (exposed mechanical) 0.8
Grime / wear layer None on standard buildings

Image 1 (drill) is out of spec on grime and gloss. When rebuilt, dial to Image 3 standard.


2. Form Language (LOCKED — derived from the real camera)

2.1 Camera facts

Read from src/world/CameraRig.gd and scenes/main.tscn, 2026-08-26.

Property Value
Projection Perspective (no fov override → Godot default 75° vertical, keep_height)
Pitch Fixed 50° from horizontal. Not top-down; oblique.
Zoom range 5 to 40, default 20, step 2
Rotation Yaw orbit exists — right-drag. Pitch is fixed.
World extent 200×200 plane centred at origin → −100 to +100, confirmed

⚠️ Doc correction: 01_Game Overview & Scope describes the camera as "pan and zoom". Orbit is implemented (right-drag, yaw only). This matters — it is what lets players see behind tall buildings.

2.2 Resolution budget

At 1920 px wide, 16:9:

Zoom Visible width Visible depth px per metre Smallest readable feature (3 px)
5 (max in) 13.6 m 10 m 141 0.02 m
20 (default) 54.6 m 40 m 35 0.085 m
40 (max out) 109 m 80 m 17.6 0.17 m

Width = 2·zoom·tan(37.5°)·(16/9). Depth = width/aspect ÷ sin(50°).

2.3 Minimum feature size

Rule Value
Absolute floor — must read at max zoom-out 0.17 m
Working target — must read at default zoom 0.085 m
Below 0.04 m at default zoom Shimmers as the camera moves. Worse than omitting it.

Anything smaller than 0.17 m exists for marketing renders and the Steam page only. It will not be visible in play at range.

2.4 Chamfers, panel lines, corner radius

Element Size Reasoning
Chamfer 0.04 m Does not need to resolve; it needs to catch light and break the silhouette edge. 1.4 px at default zoom is enough for a highlight.
Panel line width 0.08 – 0.10 m ~3 px at default zoom, the readable floor
Minimum panel line spacing 0.3 m Closer than this and adjacent lines merge into grey mush at default zoom
Corner radius (base ring) 0.15 m Reads as deliberately rounded rather than as a modelling artefact

2.5 Consequences for locked decisions

Decision Verdict at max zoom-out
0.25 m port band Survives. 4.4 px. Tight but above the floor.
Physical port geometry over chevrons Validated. A flat chevron would be 2–3 px and would dissolve. Silhouette and shadow survive where a drawn symbol does not.
Mk accent tabs ⚠️ At risk. Counting 1–3 requires visible gaps. At 17.6 px/m a 0.3 m pitch gives ~1.4 px gaps, which blur into a smear. Tab pitch must be ≥ 0.4 m so gaps are ≥ 0.18 m (3.2 px).
1×1 Silo Confirmed problem. The whole building is 17.6 px at max zoom. After a 0.25 m band each side the machine is 0.5 m = 8.8 px. That is a dot, not a building. 1×1 buildings need a reduced band — recommend 0.15 m.
Tall buildings occluding ⚠️ Real at 50° pitch, but mitigated: yaw orbit lets players look around. Not a blocker.

2.6 Silhouette rules

Because pitch is fixed at 50° and only yaw rotates, a building is always seen from an oblique angle, never from directly above. Therefore:

  • The top face and one or two side faces are always visible. Detail on the underside is wasted.
  • Height reads. Vertical extent contributes to silhouette in a way it would not at true top-down, which is why the Silo column works.
  • Because yaw is free, a building must read from all four sides. No "front".

3. Modular Kit

Pending. See Modular Kit Specification.md.


4. Concept Prompt Template

Pending. Must embed section 1 values plus a locked reference render.