Game design document · v0.1

OVERFLOW.

A grid-building factory roguelite. Place machines, route the belts, run the shift. Every round the quota doubles — so your factory has to do more than grow, it has to compound.

2D · top-down grid Rust core · Bevy renderer Run length ≈ 45 min 12 rounds · 3 acts Deterministic seeded sim

1 · Engine decision

Rust core, Bevy renderer — decided 2026-08-10, by measurement

The game lives in an engine-free Rust crate (rust/core). The browser build ships today through an ~85 KB wasm bridge under a canvas shell; Bevy arrives as a renderer over the identical crate once the design has proven it deserves one.

The critical architectural point survives from the first draft of this document: this game has no physics and no per-item scene objects. The factory is a deterministic tick simulation over a 2D array. Items are structs in a list, not scene nodes. The engine draws the result; it does not own the truth. That separation is what lets the sim run at 20 Hz while rendering at 144, fast-forward a shift 16× on request, replay a seed exactly, and evaluate thousands of complete runs headlessly for balance passes (rust/lab does exactly that, today).

OptionVerdictWhat actually happened
Rust core + BevyChosen The game wants extreme on-screen item counts scaling down to mobile, and the sim that drives them is where engines differ: the Rust core does 32,500 items in flight at 4.7 ms/tick single-threaded. The core has zero dependencies, compiles to wasm32 unchanged (CI enforces it), and Bevy is strictly a renderer over it — so the choice stays cheap to reverse.
Godot 4.xWas the recommendation; measured out This section originally recommended Godot. A verified headless toolchain was built and worked (see git history) — then GDScript measured 29× slower than JIT'd JS on the transfer loop, exactly the hot path the item-count ambition lives on.
TypeScript canvasServed, then retired The first playable prototype: a browser shell over the TS reference sim, built in hours, playtestable from a URL. Retired as designed once the wasm build of the Rust core replaced it under the same canvas UI.
Unity / UnrealNo Overkill weight for a 2D grid game; you'd fight the engine's opinions more than you'd use them.
LÖVE (Lua)No Lovely and minimal, but you'd hand-roll the entire UI layer — and this game's UI is the game.
The rule that outlives every engine

The renderer reads sim state and never writes back. Every mutation goes through the same command surface the browser drives today (rust/web is the de facto spec). The fun is entirely in the numbers and the routing, and none of it is in the rendering — which is why the design gets judged in a browser tab before a single engine scene exists.

2 · Design pillars

Compounding, not adding

A quota that doubles cannot be met by placing one more drill. It's met by finding a multiplier — a loop, an aura, a relic — and then feeding it. The player should physically feel the moment their factory stops being linear.

Space is the real currency

Credits are easy. Tiles are not. Every synergy costs board area, and a loop that triples item value eats twelve tiles you wanted for throughput. Every build is a bet on quality vs quantity.

Legible spaghetti

Factorio's joy is watching it work. Every item is a visible dot on a belt. The player should be able to point at the one lane that is starving and fix it. No hidden math, no invisible state.

The one-sentence pitch

Factorio's belts, Slay the Spire's structure, Balatro's escalation: you build a tiny production line, run a 60-tick shift against a quota, and spend the surplus on machines and relics that turn the line into something absurd by round twelve.

3 · Anatomy of the board

An 8 × 6 grid in Act 1, expanding to 12 × 9 by the end of a run. Every tile holds exactly one thing. Machines have a fixed footprint of 1 tile — no multi-tile buildings, because the whole design leans on adjacency and multi-tile shapes make adjacency ambiguous.

Tile grammar. Every machine occupies one tile and has a single output edge (the arrow). Items leave through that edge into whatever sits on the far side. Machines with inputs simply accept anything arriving on any other edge — there is no input-side configuration to get wrong. Belts move one tile per tick. Modifier machines (teal) never touch items; they project an aura onto the four orthogonally adjacent tiles, drawn as a dashed halo.

Rules the whole game rests on

4 · The value chain

Four tiers, each worth 4× the last. This 4× step is deliberately steeper than the effort to reach it, so refining deeper always beats extracting wider — until board space or shift length stops you, which is the whole tension.

Three raw lines converge upward. Ore (kinetic) is cheap and fast; Sap (organic) is slower but spawns pre-qualified; Crystal (precision) is slow and expensive but is the only route into Tier 3 precision goods. Tier 4 needs two Tier 3 inputs from different branches, which is what forces a mature factory to run parallel production lines instead of one fat one.
TierItemsBase valueMade by
T1 · RawOre, Sap, Crystal1Extractors (from nothing)
T2 · RefinedIngot, Resin, Shard4Processors (1 in → 1 out)
T3 · ComponentGear, Circuit, Lens16Assemblers (2 in → 1 out)
T4 · ProductEngine, Core, Beacon64Assemblers (2 × T3 in → 1 out)
Why quality is the interesting axis

A Tier-4 Engine at quality 0 is worth 64. The same Engine at quality 10 is worth 224 — a 3.5× swing off a stat that costs you tiles, not credits. So the endgame question is never "can I make Engines?" but "how many polish passes can I afford between the assembler and the vault?" That's the decision the whole game is built to keep asking.

5 · The machine catalogue

Roughly 30 machines across five categories. Below is the Act-1-and-beyond core; the rest are rarer variants and boss drops. Cost is in credits; tags drive synergy.

Extractors — the only source of new items

Processors — one in, one out, one tier up

Assemblers — two in, one out, big tier jump

Logistics — no transformation, all routing

Modifiers — the multipliers

6 · Synergies — where the crazy comes from

Three independent synergy systems, deliberately pulling in different directions so that no single build is optimal:

A · Adjacency auras

Modifiers buff the four orthogonal neighbours. Auras want machines clustered. But a production chain is inherently a line. Every aura you take makes your factory fold in on itself, and folded factories are where jams live.

B · Tag resonance

Five tags — HEAT, KINETIC, VOLT, PRECISION, ORGANIC. Relics key off them ("every HEAT machine touching another HEAT machine: +20% speed"). Tags reward committing to a colour of factory, and audits punish you for it.

C · Loops & quality

The deep one. Belts can form closed circuits. Put polishers on the ring and a filter as the exit gate, and items circulate, gaining quality each lap until they qualify to leave. Add a Duplicator and the item count grows too.

The three signature engines

1 · Heat Cascade. A Heat Sink at the centre with Furnaces on all four sides: every furnace is jam-immune and adds +1 quality to its output. Drop an Overclocker so its aura overlaps two of the furnaces and they run at 0.75× cycle time. Cheap, compact, and the standard Act-1 answer. Weakness: it produces only Tier 2 — it scales throughput, not value, so it stops carrying you around round 6.
2 · The Polish Loop. A closed belt ring with three Polishers on it and a Filter as the gate. An item entering at quality 1 laps the ring gaining +3 per lap; the Filter is set to quality ≥ 9 and ejects west to the Vault, passing everything else back around. Three laps ≈ 21 ticks of transit for a 3.25× value multiplier. Weakness: twelve tiles of board and it multiplies value per item, so it's worthless until your throughput is already good — and it will happily eat your entire shift if you gate it too high.
3 · Duplication Spiral (the run-winner). Put a Duplicator inside the polish loop. Every lap, 15% of circulating items clone. Item count grows geometrically while quality climbs — the loop is both a multiplier and a reactor. Weakness: it is genuinely unstable. Clone faster than the Filter drains and the ring saturates, every belt jams, and your entire factory backs up to the drills and produces nothing. Taming it — usually with a second gate or a Buffer bleed valve — is the most satisfying problem in the game.

Relics — the roguelite layer

Passive, permanent for the run, one board-independent effect each. Awarded by audits and bought from the shop's relic slot. These are where run identity comes from.

RelicEffectBuild it enables
Union ContractMachines with 2+ same-tag orthogonal neighbours run 15% faster.Mono-tag blob factories
Vertical IntegrationPayout ×1.25 for each distinct tier delivered this shift (all four = ×2.44).Wide, shallow, many parallel lines
OverengineeredQuality cap 10 → 20.Loops. Doubles the ceiling of engine #2 and #3.
Just-In-TimeItems delivered in the final 10 ticks are worth ×2.Buffer-and-dump: hoard all shift, flush at tick 50
RedundancyThe first jam each shift is ignored and refunds 5 credits.Deliberately over-saturated duplication spirals
Scrap HeapSelling refunds 100% and grants a reroll.Total rebuilds every act — a "fluid" playstyle
Critical PathThe longest belt run on the board grants +1 quality at its end.Deliberately sprawling, slow, high-value lines

7 · The six phases of a round

Design delta — 2026-08-10: shop → deck → shop-of-blueprints

The acquisition layer went through two revisions in one day. First the credit shop described below became a deck of dealt cards (one reward pick per round) — which the lab then killed: with acquisition capped at one card per round against a ~1.9× quota curve, every player and every bot died at round 4, and credits piled up with no sink. The current design (rust/core/src/cards.rs) is a shop of owned blueprints: a persistent hand (max 10), a 5-offer rack after every cleared shift, buy with surplus, reroll for 5c, placement free, removal back to hand, sell from hand at half. Measured result: the widening-only bot's wall moved from round 4 (acquisition-starved) to round 5 (board geometry) — the wall the pillars actually intend. The walkthrough below still narrates the original shop pacing; its boards and payouts are sim-accurate either way.

Every round is the same six beats. Phases 1–3 are untimed and deliberate; phase 4 is the payoff you watch; 5–6 are the dopamine. Total round length: 2–5 minutes, growing across the run.

The round loop. Twelve laps of this per run, split into three acts of three rounds plus an Audit. Only phase 4 has a clock.

8 · Full walkthrough — one complete run

Corporation: Ferrous Dynamics — starts with an extra Drill and the relic Union Contract. Seed 0xC0FFEE. Here is the whole run, board by board.

Which of these numbers are real

The round 1 and round 4 boards are executable — they exist as data in rust/core/src/boards.rs and the simulation reproduces every figure quoted below (52 credits from 13 ingots with the first landing on tick 12; 240 credits from 10 quality-2 gears). Run cargo test in rust/ to check. Rounds 7 and 11 are hand-estimated: Filter gates and Splitters are implemented and tested now, but those boards haven't been built and measured yet, and Duplicator economics remain approximate — so treat their payouts as design targets rather than measurements.

Act I · Round 1 · Quota 20

The first line

You start with 10 credits and a bare 8×6 board with one Vault already bolted to the east edge. The shop offers a Drill (3), a Furnace (5) and a Splitter (4). You buy the Drill and the Furnace, leaving 2 credits, and spend nothing on belts — belts are 1 credit each and you need six. You are 4 credits short, so you skip the last belt and put the Furnace one tile closer.

Ore / shift
15
Delivered
13 ingots
Payout
52
Quota
20

The Drill spits an Ore every 4 ticks — 15 per shift. The Furnace takes 3 ticks per Ingot, so it never becomes the bottleneck; the drill is. Transit costs 7 ticks, so two ingots are still on the belt at tick 60 and are lost. 13 × 4 = 52 credits. Quota cleared by 32.

The lesson the round teaches: the bottleneck is upstream, and the last two items didn't make it. Both facts will matter for the next eleven rounds.

Act I · Rounds 2–3 · Quota 45 → 90

Doubling the line, then discovering auras

Round 2 is the easy one: buy a second Drill and Furnace, run a parallel lane, merge before the vault. 96 delivered against a 45 quota. This is the last round that pure duplication works.

Round 3's shop offers an Overclocker for 10 and a Heat Sink for 9. You can afford one. You take the Heat Sink, place it between the two Furnaces, and discover the game: both furnaces are now jam-proof and their ingots come out at quality 1 — every ingot is worth 5 instead of 4, for free, forever. 178 delivered against 90.

The teaching moment

+1 quality on a Tier-2 item is +25% value. On a Tier-4 item it's the same +25% — but of 64 instead of 4. The player who notices this in Act 1 is the player who builds a polish loop in Act 2. Nothing in the UI says it out loud; the tooltip just shows the arithmetic and lets them find it.

Act I · Round 4 · AUDIT · Quota 200

Efficiency Audit — the first wall

Audit modifier: quota ×2, but the board gains two columns. 200 credits needed and your current line does 178. You have 140 banked. This is the round where you must stop widening and start going up a tier.

You buy a Fabricator (12) — two Ingots in, one Gear out — and an Overclocker (10), and rebuild:

Ingots / shift
28
Gears out
10
Quality
2
Payout
240
Quota
200

Two drills feed two furnaces through the round-3 Heat Sink, and both lanes corner inward into a Merger that feeds the Fabricator. The interesting decision is where the Overclocker goes. The obvious answer is on the furnaces — and it's wrong. Two drills supply 0.5 ore/tick; two furnaces can already process 0.67/tick; but the Fabricator only consumes 0.4 ingot/tick. The assembler is the bottleneck, so speeding the furnaces achieves literally nothing. On the Fabricator, the same aura cuts its cycle from 5 ticks to 3.75 and lifts demand to 0.53 ingot/tick — past supply, which is exactly where you want a bottleneck to sit.

A Polisher takes the last tile before the Vault. Each Gear leaves at quality 2 — the Heat Sink gave 1, the Polisher the other — so it's worth 16 × 1.5 = 24. Ten of them land: 240.

Cleared by 40 credits, with 9 items still stranded on belts at tick 60. That margin is the point — Act 1 should end with the player sweating, not coasting.

Audit reward: choose one of three relics. You take Overengineered (quality cap 10 → 20) because you have started to suspect what quality does.

Act II · Rounds 5–7 · Quota 400 → 700 → 1,200

The loop goes in

Act II opens the board to 10×8 and unlocks the Crystal branch, the Filter, and the Duplicator. Round 5 you add a third drill lane and a second Heat Sink — brute force, 520 delivered, comfortable. Round 6 the shop rolls a Filter and two Polishers and you commit.

Round 7's board is the first one that looks like a factory:

Gears / shift
22
Exit quality
9
Value / gear
52
Delivered
30 items
Payout
1,580

Three drill→furnace lanes, two Heat Sinks stacked so each covers two furnaces, everything merging into one Fabricator under an Overclocker. Gears then feed the polish ring in the bottom right: three Polishers on the loop, a Duplicator on the east side, and the Filter at the west gate set to quality ≥ 9. Gears enter at quality 2, lap the ring 2–3 times, and exit at 9 — worth 16 × 3.25 = 52 each. The Duplicator adds roughly a third more items than went in.

What just happened structurally

Throughput went up 40% between rounds 6 and 7. Payout went up 74%. The player has crossed from adding to compounding, and every subsequent decision is about feeding the ring rather than building new lines. That crossover is the entire emotional arc of the game, and it should happen somewhere in rounds 6–8 for almost every run.

Act II · Round 8 · AUDIT · Quota 2,400

Blackout — the audit that hates your build

Audit modifier: all VOLT machines are disabled for the shift. Your Overclocker is VOLT. So is your Duplicator. The ring still polishes but no longer clones, and the Fabricator drops back to base speed. Naive throughput falls to roughly 1,900 — a fail.

The out: you have 900 banked. You sell the dead Duplicator back (Scrap Heap would have refunded full; you get half, 10 credits, and a free tile) and spend on a fourth drill lane and a second Vault placed next to the filter, cutting six tiles of transit off every delivery. Six tiles is 10% of the shift.

Transit saved
6 ticks
Extra deliveries
+7
Payout
2,760
Quota
2,400

Cleared by 360. Audits are the game's teaching mechanism: each one invalidates a different axis of your build and forces you to find value on an axis you'd been ignoring. Blackout teaches you that latency is a resource.

Reward: Vertical Integration — payout ×1.25 per distinct tier delivered. You now have a reason to keep a cheap raw-ore line running straight to a vault, which you would otherwise have torn out. Good relics change what "waste" means.

Act III · Rounds 9–11 · Quota 4,500 → 8,000 → 14,000

Tier 4 and the second branch

The board opens to 12×9. Quotas now demand Engines, which need a Gear and a Circuit — and Circuits need Shards, which means standing up an entire second raw branch from Geode Crackers through Lapidaries. Half of Act III is logistics work: getting two independent production lines to arrive at one assembler in sync.

Round 11's board, the mature factory:

Engines / shift
18
Exit quality
17
Value / engine
336
Tier bonus
×2.44
Payout
19,500

Reading the board north to south: the ore branch runs two drill→furnace lanes through a Heat Sink into a Splitter, which feeds ingots both east to the Fabricator (Gears) and south to the Circuit Bench. The crystal branch comes in from the west through a Lapidary and merges into the same Circuit Bench lane. Gears and Circuits both corner into Engine Works under an Overclocker. Engines drop south into the big polish ring — three Polishers plus a Duplicator, gated at quality ≥ 17 thanks to Overengineered — and exit west into the main Vault.

Meanwhile the little Compressor line at the bottom left takes four raw Ore and squashes them into an Ingot, delivering to a second Vault. It's economically terrible — about 200 credits a shift — but it puts a second tier on the board, and Vertical Integration turns that 200 into a ×1.25 on everything. The player kept a bad line for a good reason. That is the kind of decision the design exists to produce.

The failure state that makes this fun

On the first attempt at this board the ring saturated: the Duplicator cloned faster than the Filter could drain, the ring filled, the Engine Works jammed, then the Fabricator, then both furnaces, and the shift ended with 4 engines delivered and forty items sitting motionless on belts. The fix was a Buffer spliced into the ring as a bleed valve. Fixing it yourself, in the build phase, watching the sim preview, is the best ten minutes in the game.

Act III · Round 12 · FINAL AUDIT · Quota 30,000

Rush Order — 30 ticks

The final audit halves the shift. Thirty ticks. Your ring needs 21 ticks just to bring an engine to quality 17, and your first engine doesn't exist until tick 14. Under the old build you deliver three engines and lose the run.

What actually wins it: you drop the Filter gate from 17 to 9, halving lap count. Engines exit at 208 instead of 336 — a 38% value cut — but you deliver 26 of them instead of 3. You also move the Vault directly against the Filter's exit edge, and you spend your entire 4,000-credit bank on two more drill lanes that only exist to keep the ring saturated for thirty ticks.

Shift
30 ticks
Engines
26
Value / engine
208
Tier bonus
×2.44
Payout
34,100
Quota
30,000

Run complete. 34,100 against 30,000 — cleared by 13.7%. The winning move was voluntarily making every item worse. That's the design working: the ceiling is never one build, it's the willingness to retune the build you love when the constraint changes.

9 · The escalation curve

The tuning target: the quota should sit just under what a well-played board can deliver, and audits should sit close enough to feel survivable rather than certain. Notice the gap narrows at every audit and re-opens after it — that sawtooth is the run's heartbeat.

Delivered value vs quota, one full run

Credits per shift · log scale · orange bands are audit rounds

Delivered Quota

Why a 1.8× quota step

Each round's quota is roughly 1.8× the last, with audits jumping 2.2×. Linear factory growth (add a lane) yields about 1.3×. Tier growth (go up a tier) yields 2.5× but costs a whole build phase. Quality growth (add a polish pass) yields 1.25× and stacks multiplicatively with both. The 1.8× step is chosen precisely so that no single growth axis keeps up — you must alternate between them, and that alternation is the round-to-round decision the game is made of.

10 · Meta-progression

Corporations (characters)

Six unlockable starts, each a starting relic plus a rule change.

  • Ferrous Dynamics — extra Drill, Union Contract. The tutorial corp.
  • Verdant Cooperative — Sap only; no Ore extractors exist in your shop at all.
  • Precision Guild — start at Tier 3; quota starts at round 5's value.
  • Salvage & Sons — start with 9 random machines and 0 credits. Build with what you're given.
  • Continuous Ltd. — the board never resets between rounds and machines cannot be sold.
  • The Bureau — every round is an audit. Every one.

Debt levels (ascension)

Twelve escalating difficulty tiers per corporation, applied in fixed order so the community shares a ladder:

  1. Quotas +15%
  2. Shop offers 2 instead of 3
  3. Shift 60 → 55 ticks
  4. Audits appear every 3rd round instead of 4th
  5. Board starts one column smaller
  6. Machines cost +25% after round 6
  7. Quality cap 10 → 8
  8. Two audit modifiers stack
  9. Rerolls cost credits
  10. Jams are permanent for the shift
  11. Quota step 1.8× → 2.0×
  12. Vaults must be re-purchased each act

Unlocks

Machines and relics unlock by usage milestones, not by wins — "deliver a quality-15 item", "run a loop of 16+ tiles", "clear a shift with zero jams". This keeps a losing run productive and teaches mechanics by naming them as goals.

11 · Build plan

Architecture

Three layers, strictly separated. The top layer must be deletable without the bottom two noticing.

LayerContentsRule
SimSim (2D array of tiles), Item structs, step(), seeded RNG — rust/core/src/sim.rs Pure data. No engine types, no I/O, no delta time. Runs headless in a test. Built.
DataMachineDef, recipes, auras, card pool — rust/core/src/defs.rs; relics/audits to follow Every number lives here. Zero balance constants in the sim. Built.
ViewToday: canvas shell over the wasm bridge. Later: Bevy — tile floor, one instanced draw for all items, UI nodes Reads sim state, interpolates between ticks, writes nothing back.

Tick rate: sim at 20 Hz, decoupled from frames. Items lerp between their previous and current tile for smooth motion. Speed control (1× / 2× / 4× / instant) is just how many sim ticks you run per frame — free, because the sim doesn't know about time.

Item rendering: a late-game board has 300–2,000 items in flight. One instanced draw with per-instance colour renders all of them in a single call. Never a scene object per item — that's the one decision that will bite you at round 11 if you get it wrong.

Milestones

#MilestoneDone when
1Tick sim, no rendering✅ A unit test builds drill→belt→furnace→vault and asserts 13 ingots at tick 60.
2Board renders + items move✅ You can watch the round-1 board run and it looks right.
3Placement UI✅ Play cards, lay belts, rotate, sell. Ghost preview; illegal placements refused by the core.
4Full round loop✅ Build, shift, quota, reward, game over — the card/deck run structure, in the browser. Playtesting is unblocked.
5Loops & quality◐ Filter, Polisher and closed-circuit rotation are in and tested; Duplicator economics still approximate.
6Content pass30 machines, 20 relics, 10 audits, all as data files.
7FeelJam pulses, delivery pops, payout counter, audio. The difference between a prototype and a game. (Likely where Bevy enters.)
8MetaCorporations, debt levels, unlocks, save/load, run history.

The one hard technical problem

Resolving a tick when items move into tiles other items are simultaneously leaving. Naive per-tile movement fails two ways: a full belt line only advances at its head (items should move as a train), and a full closed loop deadlocks (it should rotate). The implemented solution — see transfer() in rust/core/src/sim.rs — moves downstream tiles first: that order is a reverse topological sort of the flow graph, which only exists if the graph is acyclic, and belt loops are deliberately cyclic. So: Tarjan strongly-connected components, process the condensed DAG sinks-first, and resolve each multi-tile component (a loop) as a simultaneous rotation. Deterministic, order-independent, and it makes belt loops behave exactly like straight belts — which is what lets the polish loop exist at all.