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_meshchild that05_Asset List & Delivery Specificationalready 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 & Scopedescribes 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.