You do not pick a path through a fog. The map is generated whole the moment the act starts, under rules the game ships with — so the question "which path do I take" has two halves: what the generator guarantees before you see it, and what each node type actually pays.

Node budget math

Both games draw maps on a grid: the Exordium and everything after use a 15-row map, 7 nodes wide, at map density 6. The final act collapses to a fixed linear column instead — more on that below.

Room counts are not rolled freely; they are percentages of one number: availableRoomCount, the nodes that have edges once the second-to-last row is excluded (room_type_counts.source). Every act uses the same chances (per_act_chances):

Room typeChanceCount formula
Shop0.05round(availableRoomCount * shopRoomChance)
Rest0.12same shape
Treasure0.0
Event (?)0.22same shape
Elite0.08× 1.6 at Ascension 1+, × 2.5 under Elite Swarm
Monsterremainderwhatever the other counts leave

That treasure row is not a typo. treasureRoomChance is 0.0 in all acts; normal-run chests come only from ? rooms converting into treasure and one fixed assignment on row 8 (treasure_room_note). The map never budgets a treasure room — you find them inside question marks.

Why row 0 differs

Row 0 ignores the parent/sibling placement rules entirely: "nodes at y == 0 accept any room regardless of parent/sibling rules" and are force-assigned as monster rooms first anyway (distribution_rules.row0_exception). That is why every run opens with the same texture — a wide fan of fights — no matter how the rest of the map branches.

The elite-weight ramp

Elite rooms cost the same everywhere, but which elite you meet is weighted. Act 1 rolls its three elites evenly — Gremlin Nob, Lagavulin and 3 Sentries all sit at weight 1.0. The Beyond breaks even: Giant Head, Nemesis and Reptomancer each carry weight 2.0 — still uniform among themselves.

The real asymmetry hides in the strong fight pools, not the elite pools. In the Exordium, hard openers are discounted: Gremlin Gang and Lots of Slimes sit at weight 1.0 while Blue Slaver, Large Slime, 3 Louse and 2 Fungi Beasts carry 2.0, and the mid-tier pairs (Exordium Thugs, Exordium Wildlife) take 1.5 (acts.Exordium.strong). The City runs weights up to 6.0 on its heaviest fights (acts.TheCity.strong). So an elite path in act 1 is a coin flip between three known fights — check what each demands before you commit: the monster index lists them all.

? rooms decay into fights

A ? room is not a coin flip — it is a pot that boils. On entry the game rolls with these base chances:

ResultBase
Eventremainder (0.55 at reset)
Monster0.10
Shop0.03
Treasure0.02

After each roll, the type you hit resets to base and everything else grows by its own base amount (ramp_after_miss): miss a monster and MONSTER goes 0.10 → 0.20 → 0.30…, miss a shop and SHOP climbs 0.03 at a time. Two catches the extraction records: the elite chance resets to 0.0 at every act transition even though its initial constant reads 0.1 (reset note), and a shop result is forced to 0 while you stand in a shop row. Hold Tiny Chest and every fourth ? forces treasure instead.

StS2 keeps the same boiling-pot design with different numbers. Its unknownMapPointOdds start at Monster 0.1, Treasure 0.02, Shop 0.03, Event 0.85 — and Elite is set to −1.0: negative odds are never rolled and never grow, so co-op-era Spire 2 maps have no elite surprises hiding in unknowns. Odds reset between acts. See the StS2 atlas for where unknowns sit on those maps.

Shop/rest placement rules

Rest sites are the second-largest budget at 0.12, shops the smallest at 0.05 — both computed against availableRoomCount and rounded (room_type_counts.formulas). Because the formulas round, small acts can shift a count by one; because the chances are identical across acts (initializeLevelSpecificChances() is identical for Exordium, TheCity, TheBeyond and TheEnding), a longer path to the boss means proportionally more camps and shops, never different rates. Planning around "act 3 has fewer camps" is planning around nothing — it has the same rate, only fewer eligible nodes if your route skips side branches.

Key and act-4 exceptions

Two overrides break the pattern. Act 4 replaces generation outright: a fixed linear column at x=3 — Rest, Shop, Elite, Boss, victory — with hardcoded edges and a still-seeded but layout-deterministic mapRng (act4_map.layout). And when the emerald key is available and unclaimed, the game picks one elite node uniformly at random and buffs it: Strength +(actNum+1) on every monster, or +25% max HP, or Metallicize (actNum×2+2), or Regenerate (1+actNum×2), chosen by a 4-way roll (emerald_key_elite.buff_roll).

Per-act independence

Each act's map comes off its own seed offset — seed+1, seed+200, seed+600, seed+1200 for acts 1–4 — so knowing act 1's layout tells you nothing about act 2's, and neither game lets you precompute the climb from the seed screen alone. What the seed does decide is a bigger story: see how the acts themselves are built.