Decisions
Each entry: ID · iteration · decision, alternatives considered, rationale, status.
Status values: active, superseded by Dxx, under review.
D01 · i1 · Stack: TypeScript + Vite + raw WebGL2 (twgl.js allowed); Python for art tools
- Alternatives: Godot 4 (GDScript or C#); Rust with Bevy or macroquad; Love2D; TypeScript with PixiJS.
- Rationale:
- The build is done by an agent, so headless testing matters most. Vitest covers the sim and Playwright covers screenshots and palette compliance.
- The palette-index-plus-LUT renderer is a custom 2-pass pipeline, which a scene-graph engine would fight.
- A 32k-cell grid is cheap with typed arrays.
- Godot was a close second: good editor, desktop export. GDScript is slower for cellular passes and harder to make bit-deterministic. Rust is the fastest, but slower to iterate and heavier for an agent.
- Status: active.
D02 · i1 · 8 × 8 px tiles at 480 × 270 internal, integer scaling only
- Alternatives:
- 16 px tiles at 640 × 360: Terraria-like, more detail per asset. That means 4× the pixels to draw per sprite, makes AI cleanup harder, and shows less of the island.
- 8 px at 320 × 180: too cramped for UI text.
- Rationale: the brief asks for a small tile size and a strict palette. 8 px keeps assets cheap and code-friendly. The island surface (60–76 tiles) fits on about one screen like a diorama, and 5 × 7 text fits 80 columns.
- Status: active.
D03 · i1 · 64-color palette (8 ramps × 8) with palette-locked lighting via an offline LUT
- Alternatives:
- Free RGB lighting (multiplicative), then post-quantize. It looks smoother, but output leaves the palette and AI and procedural assets drift apart.
- A 32-color palette: too few for 5 strata plus flux.
- Per-stratum palettes swapped wholesale: they break continuity in shafts.
- Rationale: every pixel on screen is one of 64 colors, so cohesion is guaranteed by construction. That's the strongest lever for making code and AI assets look intentional. Dithered light levels keep the falloff soft.
- Risk: banding. Mockup m02 must test it.
- Status: active (m01 validated the ramps).
D04 · i1 · Two light channels: warm deters entities, cool suppresses flux
- Alternatives: a single light value; or three channels (adding a violet "unlight").
- Rationale:
- It creates a recurring decision (K3): the type of light becomes strategy.
- It ties the art directly to gameplay (warm against cool is the look).
- Safety light
Ls = max(warm, floor(0.6·cool))keeps cool light useful but weaker for defense. - The Heart's "inverse light" is a special case, not a third channel.
- Status: active.
D05 · i1 · Flux is a heavy, conserved integer gas, and lamps have suppression budgets
- Alternatives:
- Light deletes flux without limit: lamps would become a permanent answer.
- Flux as a light, non-pooling gas: it can't pool in low caverns.
- Float fields: not deterministic across JS engines.
- Rationale:
- Heavy gas gives the "pools in low caverns" fantasy and makes layout matter (K4).
- Budgets make lamp count scale with factory size and create strain as a readable warning.
- Integer conservation makes regression tests exact.
- Status: active, pending sims S01 and S02.
D06 · i1 · Buoyancy as an equilibrium altitude with a log model, normalized per seed, plus a rising tide
- Alternatives:
- A direct sink rate per crystal: no stable state, and it reads as a timer.
- A linear model: the early game gets punished as hard as the late game.
- Hard thresholds: a cliff, not a curve.
- Rationale:
- The log model makes the first ~25% of crystal nearly free and each crystal after that cost more, which gives escalating tension.
- Normalizing makes every seed start at 1000.
- The tide turns an abstract number into rising darkness in your own tunnels, and it links buoyancy to light, entities and the endings.
- Status: active, pending S03.
D07 · i1 · Endings are accumulators fed by sustained, mutually exclusive world states
- Alternatives:
- One-time triggers (build X): checklist-y.
- A choice prompt at the Heart: violates P3.
- Hidden scores: illegible.
- Rationale:
- "Sustained state" forces the player to live the ending's values for hours of game time.
- Exclusivity comes from physics: Mend needs a lit, clean chamber; Bind fills the chamber with pylon flux; Become needs darkness. No menu is needed.
- Status: active.
D08 · i1 · Seeded recipes are chosen from per-compound pools of 3 plausible parent pairs
- Alternatives:
- Fully random parent pairs: breaks theme (Growth = Ember + Hush).
- Fixed recipes: no replay puzzle.
- Random item compositions: makes the world unlearnable.
- Rationale:
- Pools preserve flavor and still give a large solution space.
- Fixing item compositions lets players learn materials across runs, and the puzzle is the graph.
- Status: active, pending S05 (solution-space size and difficulty spread).
D09 · i1 · Original primal names: Ember, Dew, Loam, Breath, Glim, Hush
- Alternatives: Thaumcraft-style Latin (Ignis, Aqua, …).
- Rationale: the game's own voice is cozy and English. It avoids reading as derivative, and the names are more legible to new players.
- Status: active.
D10 · i1 · No player health and no hunger; warp is the only player meter; the one fail state is Foundering
- Alternatives: survival meters; entity damage.
- Rationale:
- Pillars P1 and P5 apply, and the brief says no combat.
- Pressure lives in the world (items, layout, altitude), not in a death loop.
- Foundering is the honest consequence of the buoyancy system, and it's telegraphed for hours.
- Status: active.
D11 · i1 · Keeper Records: foundered and Become runs seed future worlds' fossil layers
- Alternatives: no legacy; full roguelite meta-progression.
- Rationale: it makes "the next keeper finds your skeleton" literal and adds replay texture cheaply (a JSON record plus one stored room).
- Status: active. It's on the cut list (§19 #2) if scope bites.
D12 · i1 · Tilt is rendered by rotating the procedural background, not the tile layer
- Alternatives:
- Rotating the whole island render: rotated pixel art jaggies.
- No visual tilt: the system is invisible.
- Rationale: background layers are procedural, so they can be evaluated in rotated coordinates and stay crisp. The player reads the horizon tilting.
- Status: active.
D13 · i1 · Power = Ember essence per cycle, plus crystal Resonance, plus Heartpower (Bind)
- Alternatives: Create-style rotational stress networks; an electricity grid.
- Rationale: "everything is essence" keeps one logistics language (pipes). Resonance ties power to crystal and therefore to buoyancy (P2). A second network type would double logistics complexity for little new decision space.
- Status: active.
D14 · i1 · Hallucinations have 6 consistent tells
The tells: no light occlusion, no flux wake, no reflection, the cat ignores them, the Clarity Lens removes them, and the Keeper's Log omits them.
- Alternatives: random tells; no tells (pure paranoia).
- Rationale: the brief says "telling them apart is a skill", and skills need consistent signals. The cat makes the tell cozy, and the reflection makes it beautiful.
- Status: active.
D15 · i1 · Custom bitmap fonts defined as data; no CC0 fonts
- Alternatives: Kenney Pixel (CC0); m5x7 (free-with-credit).
- Rationale: zero license questions, a font made to the 480 × 270 grid, and the agent can author it as data.
- Status: active.
D16 · i1 · Vented flux goes to a reservoir and returns with rain
- Alternatives: venting deletes flux; venting raises V only.
- Rationale: stops the degenerate "vent everything" strategy. Creates a delayed, spatially spread consequence (Factorio-pollution style) that ties weather to corruption (K2).
- Status: active, pending S08.
D17 · i1 · Light as walls: entities navigate only cells with Ls below their tolerance
- Alternatives: entities take light damage; entities flee within a radius.
- Rationale: literal pillar P1. It makes dark paths a visible, solvable layout problem (the light lens shows them), and it needs no combat semantics.
- Status: active.
D18 · i1 · Pipe networks carry one fluid type each and are modeled as logistics graphs (no pressure)
- Alternatives: mixed-fluid pipes; pressure and gravity simulation (Create-like).
- Rationale:
- Pressure sims are expensive to make legible and deterministic.
- Single-type networks give clear layout puzzles.
- Contamination at junctions creates a small, readable failure mode that leaks flux.
- Status: active.
D19 · i1 · Time: 24-minute Nights with three 8-minute Watches; no day
- Alternatives: a day/night cycle; continuous night with no structure.
- Rationale:
- "Endless night" is the premise, but rhythm is needed for pacing (Deep-watch danger, root movement, sleep).
- The 8-Night moon cycle adds a slower rhythm.
- Dawn is reserved for the Mend ending, which gives it emotional weight.
- Status: active.
D20 · i1 · Research is a deduction Ledger with costed experiments; no Thaumcraft-style hex "theory board" minigame
- Alternatives: a TC4 hex research minigame on top of discovery; Little-Alchemy-style free combining.
- Rationale:
- Scope: one research system, not two.
- The scrambled graph plus costed tests (flux, warp) plus world clues is a real information puzzle.
- The minigame would duplicate the "relationship" knowledge without new decisions.
- Status: active, pending S05. Revisit if S05 shows deduction is shallow.
D21 · i1 · Golems work only in light (each tier has a threshold); Root golems are the dark exception
- Alternatives: golems work anywhere; golems need a power network.
- Rationale: links automation to the light system, so logistics routes need lamp coverage (K12). The dark exception has a real cost: flux and wandering.
- Status: active.
D22 · i1 · Hearth sanctuary is a hard rule, and the hearth never fully goes out (embers = warm 6)
- Alternatives: the hearth can go out; the hearth is a normal lamp.
- Rationale: P5 ("the player can always retreat to warmth"). Fuel stays a chore with a reward (13 vs 6) without becoming a fail state.
- Status: active.
D23 · i1 · Only the AI Alembic sprite is required for the M1 pipeline test, and it gets no hand edit before the test
- Alternatives: test with the player sprite (harder, since it's animated).
- Rationale: a machine is static, mid-complexity and central to M1. If it passes the "sits naturally" test unedited, the pipeline is proven.
- Status: active.
D24 · i1 · Danger and warning color is violet (R4), never red; the palette has no true red
- Alternatives: a standard red warning.
- Rationale: red reads as gore and combat, which is off-tone. Violet is already the "wrongness" hue, so warnings and flux share a meaning.
- Status: active.
D25 · owner, after i1 · Audio is deferred: out of scope for M0–M5
- Alternatives: keep the brief audio direction in the M5 polish milestone (the i1 plan).
- Rationale: the owner asked to skip audio for now. To keep this safe, GDD §15.6 adds a hard visual-first rule: no information is carried by sound alone. Every i1 audio cue was converted to a visual one (lamp stutter, dust and shaking, whispers as handwriting, the Visitor telegraphed by dimming stars). The sim's event stream keeps a no-op audio hook so sound can be added later without touching the sim.
- Status: active.
D26 · owner, after i1 · The brief's written art direction is the canonical mood reference
- Alternatives: block art work until a reference image exists.
- Rationale: the owner confirmed the brief-derived mood (indigo night, amber windows, cyan
wisps and crystal, big moon, soft rain, drifting clouds). Art iterations score rubric #10
against the brief. If
docs/reference/inspiration.pngappears later, it takes precedence. - Status: active.
D27 · i2 · Flux is measured in Alembic-Equivalents (AE); 1 AE = 3 motes/s (emissions ×9 vs i1)
- Alternatives: keep i1 emissions and lower the thresholds (50/150/400/800 → ~6/17/44/89); keep raw motes/s everywhere.
- Rationale: S01 showed that at i1 scale one alembic makes 400 motes in 20 min, which can never foul a 24-cell room: a scale problem that no transport parameter can fix. Rescaling emission keeps the readable thresholds. Quoting every source and sink in AE gives players a single mental unit ("this lamp keeps 6 alembics clean"). Lamp capacities keep their i1 numbers, now read as AE, and S01 §3b confirmed each holds roughly that many alembics.
- Status: active.
D28 · i2 · Gleaners spawn at tinged flux (≥ 50); arrangers, whisperers and dimmers need fouled (≥ 150)
- Alternatives: all entities at ≥ 150 (i1); force one alembic to foul a room (would need soil absorption ~0, which kills pooling and soil saturation).
- Rationale: S01 found that a soil floor absorbs about as fast as one alembic emits, so a one-machine room settles at "tinged" until the ground saturates. That is a good emergent buffer. A tiered threshold keeps the first-hour gleaner reachable (the broken shed is tinged at 6.5 min) and makes bigger factories attract worse visitors.
- Status: active.
D29 · i2 · Flux engine: u32 millimotes, per-mille rates; tuned g=60, D=100, absorb=2, soil_diff=1, seep=5 above 80% of cap, dissolve=4
- Alternatives: i1 percent rates with 1 unit = 1 mote (S01 baseline passed 1 of 5 targets); floats (non-deterministic across engines).
- Rationale: an 18-combination sweep in S01; the chosen set meets all 5 targets.
docs/sims/fluxcore.pyis the reference implementation. - Status: active.
D30 · i2 · Lamp strain = utilisation + backlog (5 s units); flicker ≥ 0.8, gutter > 2 for 60 s
(Superseded by D34 within i2: with proportional suppression, strain = wanted ÷ capacity. The flicker and gutter thresholds stay.)
- Alternatives: i1 demand/per-step-budget (spiked to 20–2,000 instantly, so the warning band never existed); utilisation only (it can't distinguish 101% from 300% overload).
- Rationale: gives a real warning band (flicker while 80–100% loaded, with no failure) and a failure time that scales with the overload. Measured: 7 AE on a 6-AE wisp lantern → wisp flees at 1.7 min.
- Status: active.
D31 · i2 · Rain runoff follows each column's terrace-aware drain direction
- Alternatives: no runoff (i1: "rides the rain" meant only scrubbing); neighbour-only downhill flow (S01: it strands flux on every flat terrace, so 0% reached the pond).
- Rationale: makes "contamination washes downhill into the pond" a real, layout-dependent consequence. Basins hold flux like puddles.
- Status: active (rate under tuning in i2).
D32 · i2 · Plants hollow at soil flux ≥ 250 (not ≥ 400)
- Alternatives: raise the soil cap to 600.
- Rationale: i1's hollow threshold of 400 was above soil's 300 cap, so it was unreachable (found while building S09). 250 sits just above the seep threshold (240): only ground that is already saturated hollows plants.
- Status: active.
D33 · i2 · Dropped i1's "leeward vent deposits 5·s% less" modifier
- Alternatives: keep it.
- Rationale: unsimulated special case. S01 §3c shows wind already carries surface flux off the island (31% to R with wind 2 away from the shaft), so leeward venting emerges from the wind pass without a rule.
- Status: active.
D34 · i2 · Lamp suppression is proportional to light level and capped by capacity; strain = wanted ÷ capacity
- Alternatives: "clear everything in radius up to budget" (the i2 draft).
- Rationale: S09's first run showed the clear-all model is binary: factories are perfectly clean until they collapse, and lamp position is irrelevant. Proportional removal (30‰ per step × L/level) gives graded haze (S01 §3b: wisp-lantern peak 3 → 14 motes from 1 → 6 AE), dim corners, and placement that matters (S09 E5: 2.5× difference in leakage), and it keeps the tipping point (S09 E1).
- Status: active.
D35 · i2 · Scrubber capacity 10 AE (was 20), costs 1 Ember per 2 Taint; stored Taint counts toward Void Attention (90 motes per dram)
- Alternatives: leave the scrubber as is; make Taint jars leak.
- Rationale: the S09 E2 optimizer finding: the scrubber gave zero contamination for almost nothing (67k motes captured in 4 Nights). Counting stored Taint in V turns capture into a logistics obligation: spend it on Keels or Fetter, which is the Bind path, or carry the attention it draws. Vent, scrub and nothing now each have a real cost (K2).
- Status: active, pending S07 (V magnitudes).
D36 · i2 · The reservoir R is visible as violet-tinted clouds, and deposits are logged
- Alternatives: a HUD gauge for R.
- Rationale: the rain-return loop is delayed (S09 E2: about 24 min), so without a signal the player can't connect the vent to the dead pond. Tinting the clouds is diegetic, palette-only (R1 → R4 shade swap), and readable at a glance.
- Status: active.
D37 · i2 · Crystal Lamps burn 1 shard per Watch (3 per Night), not 1 per Night
- Alternatives: keep 1 per Night.
- Rationale: at 1 per Night, 20 crystal lamps (240 AE of suppression that never gutters) cost only 2.5 crystals per Night: a near-dominant answer to flux. At 3 per Night they cost about 7.5 crystals per Night, a real buoyancy price. To be verified in S02 and S03.
- Status: active, pending S02 and S03.
D38 · i3 · A compound's Correspondence (its 4 candidate pairs) is shown in the Ledger on first sight
- Alternatives: pools hidden and revealed only by journals (i1 implied); no pools at all.
- Rationale: S05 showed that without visible pools the synthesis-only compounds cost 40–70 failed tests each (about 100k motes in total), a brute-force grind and not a puzzle. Showing pools turns research into "which of four is true here", a cross-referenced deduction with overlapping candidates. The hidden-pool variant survives as the optional Lost Ledger charter.
- Status: active.
D39 · i3 · The Prism reveals one ancestry colour per scan (+1 T warp for T1–T2, +1 P warp for T3–T4)
- Alternatives: the full ancestry set per scan (i1).
- Rationale: S05 showed the full-set Prism is an answer key (73% of identifications free, nearly every held compound solved by one scan). One colour per scan turns it into an information purchase. It creates a frontier between flux (failed tests), warp (scans) and exploration (clues): guessing 24.3 failed tests at 0 warp; thinking with scans 12.4 failed tests at 42 warp; thinking plus clues 10.5 at 25. Permanent warp for deep scans keeps the frontier honest late in the game, when temporary warp is cheap to clear.
- Status: active.
D40 · i3 · Recipe pools grow from 3 to 4 candidates, with deliberate overlaps
- Alternatives: 3 candidates (i1); 5 or more.
- Rationale: S05 measured seed overlap 34% → 25%, brute-force failed tests 17.6 → 24.3, and deduction savings 58% → 49% (with the partial Prism). Four candidates keep the first chain gentle (with Ansel's clue, 3 left) while making the synthesis-only boss puzzles worth thinking about. Each 4th option was chosen to add an overlap (Ember+Breath links Glass and Ash; Dew+Loam links Growth, Salt and Ore).
- Status: active.
D41 · i4 · AI image generation is an owner step; the build uses code-drawn placeholders and a synthetic AI-like stand-in
- Alternatives: the build agent calls an image model (it may have none); block M1 until art exists.
- Rationale: no build step may depend on a tool the agent might lack. The build ships
prompts (
assets/prompts/) and a drop folder (assets/ai_raw/), andlanternforgeprocesses whatever is there. Placeholders keep every milestone playable. The pipeline is proven on a code-generated, anti-aliased, off-palette Alembic, and M1 acceptance 4 is re-run on the real AI asset. - Status: active. Owner action recorded as OPEN_QUESTIONS Q10.
D42 · i4 · 1.0 = core plus layers. Cut: Lure, Root Graft, Glowfruit Lamp. Post-1.0: Visitor gameplay, Root golem, Mist and Gale, charters (except Lost Ledger), Keeper Records, pair grid, tilt sliding, gamepad, desktop build, audio
- Alternatives: ship everything in the i1 design (S10 counted 226 assets and about 33 kLOC either way, but the content spread across M1 was unmanageable); cut deeper (Dimmers, wards).
- Rationale: each cut item duplicates a role another core system already plays (decoys vs light placement, grafts vs stakes plus flux feeding, glowfruit lamps vs candles). Layers are self-contained additions that don't change core rules. Dimmers stay because they're the only pressure on light itself; without them lamps become a permanent answer.
- Status: active.
D43 · i4 · M1 is defined by an exact manifest (GDD §19.3) and shipped in three deployable checkpoints
- Alternatives: the i1 prose list for M1; a single M1 drop.
- Rationale: the S10 audit showed loose milestone tags put 176 of 226 assets in M1. The manifest pins M1 at 79 assets and about 12 kLOC, with an explicit "not in M1" list. Checkpoints (Night island → The leak → The first machine) give demoable deploys, as the owner asked.
- Status: active.