DEEPFALL: a tabletop game mashing up 9 loved games (SmashUp, Dragon Rampage, Blood Rage, Catan, EverQuest, Daggerfall, Eye of the Beholder, Quarriors, SmallWorld). Core fusion = SmallWorld decline + Blood Rage glorious death -> three exits (Cash Out / Press On / Worthy End) under a rising Maw that collapses a reikhelm dungeon floor-by-floor. - deepfall-core: pure deterministic engine (vendored ChaCha8, 11 tests) - deepfall-sim: balance-by-bot sweeps -> CSV/JSON - analysis/analyze.py: stdlib ASCII heatmap (no deps) - DESIGN.md (rules + post-critique revisions), FINDINGS.md (9-iteration balance journey), README.md - reikhelm-core/examples/sample_dungeon.rs: dumps a real generated board Method: adversarial design critics -> build -> simulate -> tune. 9 iterations compressed combo spread 77.8 -> 32.5 pts (all 36 combos viable). Fixed deep-content lockout (value rises with the Maw), the multi-collapse feel-bad (1 collapse/round cap; feel-bad now 0.00/game), and dead combos. Open finding: Cash-Out and Worthy-End are substitutes for a glory-maximizing bot. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
21 KiB
DEEPFALL — Design & Simulation Spec
This is two documents in one:
- Part A — The Game. A playable tabletop design (the rulebook in prose).
- Part B — The Simulation. The faithful abstraction the Rust engine implements, so the balance numbers mean something. Where the sim simplifies the tabletop rules, it says so explicitly.
The vocabulary (room themes, depth, connectivity, doors) is borrowed straight
from reikhelm-core so a printed board is a real generated dungeon.
Part A — The Game
1. The fantasy & the arc
Reikhelm is a vertical megadungeon of stacked Floors. Floor 1 is the Threshold (the surface mouth, safe, poor). The deeper the floor, the richer and deadlier it is. Beneath the deepest floor waits the Maw — a rising hunger that devours the hold one floor at a time, from the bottom up. The richest plunder is therefore the most doomed: a deep Vault is worth a fortune and will be eaten first.
Rival delve-companies (players) descend to plunder before it's all gone. You don't win by surviving — you win by Glory, and the surest way to bank a fortune is to spend a party deliberately: send them quietly to ground with their loot, or hurl them into a Worthy End at the bottom and let the Maw take them gloriously.
The game lasts until the Maw eats Floor 1. Most Glory wins. Nobody is ever eliminated.
2. Your delve-company: Lineage × Calling
At the start, and every time you bring in a fresh party, you draft two halves that smash together (Smash Up / Small World / EverQuest / Daggerfall). Each half grants an advantage and a cost — there are no free builds (Daggerfall's custom-class trade-off).
Lineages (the "race" — sets your starting dice bag + a passive)
| Lineage | Advantage | Cost (disadvantage) | Bag leans |
|---|---|---|---|
| Dvergar | +1 Steel resolved each turn (sturdy) | −1 Move (slow) | Warrior |
| Wisp | +1 die drawn each hand (nimble) | Setbacks hit double (fragile) | Scholar |
| Revenant | Ignore the first Dread each roll (fearless dead) | Faith −1 (no living soul) | Balanced, dread-proof |
| Gnoll | +Loot from combat rooms (Den/Forge) (scavenger) | Cunning −1 (clumsy at locks) | Warrior/Rogue |
| Sylphid | +1 Move (fleet) | Steel −1 (frail) | Scholar/Rogue |
| Golem-born | Setback-resistant (rarely loses dice) | Cannot recruit Relic dice (rigid) | Big, balanced, slow to grow |
Callings (the "class/faction" — special ability + recruit pool + scoring lean)
| Calling | Special | Recruits | Scoring lean |
|---|---|---|---|
| Reaver | Pillage: extra loot from every room you claim | Warrior dice (cheap) | Loot |
| Lorekeeper | Open Vaults solo (no trinity needed); +Cunning at locks | Scholar dice | Deep vaults |
| Wardancer | Worthy-End payout +50%; cheap Moves | Rogue dice | Glorious death |
| Hierophant | Cancel extra Dread; heal Setbacks; cheap denizen rep | Priest dice | Longevity (persist) |
| Warden | Your control markers count double for majority | Champion dice | Area control |
| Prospector | Cheaper recruits, bigger hand, can find Relic dice | Relic dice | Engine / snowball |
6 × 6 = 36 companies. Natural synergies emerge (Dvergar Reaver = smash-and-grab; Wisp Lorekeeper = vault cracker; Sylphid Wardancer = fast martyr; Golem-born Warden = the immovable wall) — the simulator's job is to confirm none of them is solved.
3. The dice bag (Quarriors) & the six faces
Your bag is a pile of six-sided delve dice. Each face shows one symbol:
| Symbol | Meaning |
|---|---|
| ⚔ Steel | Combat power — clear a room's threat |
| 🜏 Cunning | Wits — open mechanisms / locks; buy extra Moves |
| ✚ Faith | Spirit — cancel Dread; heal Setbacks; appease denizens |
| 💰 Greed | Loot — turns into banked Glory |
| ✦ Mettle | Wild currency — recruit new dice; pay for actions |
| ☠ Dread | Peril — accumulates; too much triggers a Setback |
Different die kinds weight these faces differently. Starting bags are mostly Recruit dice (balanced, one of each). You grow your bag in play by recruiting stronger kinds (Warrior/Scholar/Priest/Rogue/Champion/Relic) from the dungeon's offer.
A turn
- Draw a hand from your bag (default 4 dice; modified by Lineage/Calling).
- Roll them.
- Resolve Dread — cancel Dread with Faith (and Lineage dread-resist). If Dread still standing ≥ the Dread threshold, suffer a Setback (lose a die to your bag's wound slot, or lose unbanked loot).
- Act with your symbols — Move between floors, clear & claim a room, take loot, recruit a die.
- Press On? (push-your-luck) — you may draw & roll another hand for more symbols this turn. Every press nudges the Maw and stacks more Dread risk. Stop whenever you like; greed is punished by the dice and by the clock.
- Exit decision — see §6.
4. The dungeon: rooms, themes, mechanisms (EotB / Catan / reikhelm)
Each Floor holds several rooms, each with a theme from reikhelm's palette. A room's base Glory and its threat/lock scale with its theme and its depth:
| Theme | Base value | Threat (Steel) | Lock (Cunning) | Note |
|---|---|---|---|---|
| Threshold | 1 | 0 | 0 | safe mouth |
| Stone | 2 | 1 | 0 | plain |
| Cistern | 3 | 1 | 1 | flooded |
| Den | 3 | 3 | 0 | monster lair (Gnoll loot bonus) |
| Crypt | 3 | 2 | 1 | undead |
| Hall | 4 | 1 | 1 | pillared |
| Library | 4 | 1 | 2 | Cunning-gated, loot-rich |
| Forge | 5 | 4 | 1 | lava, produces Steel |
| Vault | 6 | 2 | 3 | needs the trinity (Steel+Cunning+Faith present) unless Lorekeeper |
| Throne | 7 | 5 | 2 | boss; deepest |
A room's collapse Glory = base_value × depth. A Vault on Floor 6 is worth 6 × 6 = 36 to whoever holds the majority when Floor 6 falls. Holding a room also makes it
produce each turn you roll its matching symbol (Catan): a held Forge throws extra
Steel, a Library extra Cunning, a Vault extra Greed — your engine grows on the ground
you keep, right up until the Maw takes it.
Claiming a room: spend Steel ≥ threat (fight through) and Cunning ≥ lock (crack the mechanism). Vaults additionally require trinity presence (you produced at least one Steel and one Cunning and one Faith this turn) — the EverQuest holy-trinity made literal — unless your Calling is Lorekeeper. Claiming drops a control marker.
5. The Maw: the doom clock (Blood Rage / Dragon Rampage)
The Maw begins below the deepest floor and rises. Each round it advances; its speed ramps up over the game and is pushed faster by the total Dread everyone rolled that round (your collective greed feeds it). When the Maw reaches a floor:
- The floor collapses and scores. For each room, the majority marker-holder
takes its Glory (
base × depth). Ties split, rounding down. A Warden's markers count double here; a party that went to ground leaves silent Fallen markers that still count. - Anything still on that floor is Taken by the Maw (see §6).
Because collapse runs bottom-up, the deep treasure has the shortest window. The game ends when Floor 1 collapses.
6. The three exits (the heart of the game)
Every party, every turn, faces the same triangle. This is the design's core, fusing Small World's Decline with Blood Rage's glorious death:
-
Cash Out / "Go to Ground" (Small World Decline). End this party's adventuring. Bank their unbanked loot + a depth dividend (deepest floor reached × factor). Their control markers become permanent Fallen markers — still counted at every future collapse, but they can't move or act. Then draft a fresh Lineage×Calling and re-enter at the Threshold. Safe, repeatable, keeps your territory working for you from beyond the grave.
-
Press On / Persist (Catan/Quarriors engine). Keep the party active: keep recruiting, keep holding rooms, keep producing. More upside, but the Maw is climbing and a party caught flat-footed loses everything unbanked and its territory.
-
Worthy End (Blood Rage Valhalla). Declare a Last Stand (free if you hold a Throne or Vault, or via Wardancer). Now, when the Maw Takes your active party, you score a huge Worthy End bonus =
deepest_floor × worthy_factor+ held room values (×1.5 for Wardancer). This is the single biggest payout available — and it's all-or-nothing: you lose the party and its unbanked loot. Sometimes you want the Maw to eat you, as deep as possible, in a blaze.
Getting Taken without a Last Stand is the one true feel-bad in the game (lose loot
- territory for nothing). The simulator measures how often bots fall into it — a healthy design keeps that rare, because the exits above are always offered.
7. Denizen reputation (Daggerfall / EverQuest — light)
A few denizen factions live in the deep (the Deep Cult, the Gnoll Warrens, the Revenant Court). Clearing their themed rooms angers them (reputation down → they raise the threat of their rooms against you); making offerings (spend Greed/Faith) raises reputation → unlocks premium recruit dice and safer passage. One short track per denizen, two or three thresholds. (Kept deliberately light; the sim models it as a small threat modifier so it doesn't dominate the balance picture.)
8. Why this fixes the originals' worst parts
- No runaway leader. A trailing player dives recklessly, takes a Worthy End or a deep Cash-Out for a glory spike, and resets — catch-up is built into the core loop, not bolted on. Leaders who over-persist feed the Maw and lose territory.
- No elimination, no downtime. A dead party is glory and silent territory, not a removed player. Turns are short; you're always choosing.
- Variance with a floor. The dice can betray you, but Faith mitigates Dread and Cash-Out lets you lock in value before luck turns — Quarriors' whiff is defanged.
- Conflict without spite. You fight for majorities at collapse, never to destroy an opponent's hand. The shared "robber" is the Maw, and it is perfectly fair.
Part B — Simulation model
The engine in deepfall-core is a faithful abstraction of Part A, not a literal
table simulator. It keeps everything that drives the six balance questions (the dice
faces, the bag-building, the three exits, the bottom-up Maw, the area-control scoring,
the Lineage×Calling asymmetry) and abstracts the fiddly bits (exact board geometry,
turn-by-turn movement pathing, denizen micro-management) into clean numeric rules. Each
abstraction is called out below.
B1. State
- Dungeon:
floors[1..=D], defaultD = 6. FloorfhasRrooms (default 4), drawn from the theme table weighted toward richer themes at greater depth. EachRoomhastheme, base_value, threat, lock, produces(symbol), markers: Vec<Marker>. (Abstraction: rooms are an unordered set per floor; we don't model intra-floor pathing or the corridor graph — only "which floor are you on" matters for the Maw.) - Maw:
accum: f64,frontier: u32= deepest uncollapsed floor (starts atD). - Players:
glory, and an optional activeParty. - Party:
lineage, calling, bag: Vec<DieKind>, floor (starts at 1), unbanked_loot, deepest_reached, last_stand: bool, held: Vec<RoomRef>. - Marker:
{ owner, strength, fallen }. Active strength = 1 (×2 for Warden); Fallen strength = 1.
B2. Round structure
Each round, in player id order, every player takes a turn (B3). After all turns, the Maw advances (B4) and any collapses resolve (scoring + Takes). Repeat until the frontier passes Floor 1. Then final scoring (B5).
B3. A turn (the engine's core resolution)
- Decide intent from the controller (B6): a target floor and a risk appetite.
- Move:
moves = 1 + lineage_move + calling_move; optionally spend Cunning/Mettle for extra moves if the bot wants to dive. Stepfloortoward the target (clamped to[1, frontier]— you cannot stand on an already-eaten floor). Updatedeepest_reached. - Roll the hand: draw
hand_sizedice (+lineage/calling), roll each to a face, summing the six symbol totals. The controller may Press On (B6) to draw & roll additional hands, each appending to the totals and addingpress_dread_pushto the round's Maw pressure. - Dread:
dread -= faith_cancel(Faith spent to cancel, plus Hierophant bonus and Revenant's "ignore first"). If remainingdread ≥ dread_threshold, a Setback: lose one die from the bag (Golem-born resists; Wisp loses two) or, if the bag is minimal, losesetback_lootunbanked loot. Count it. - Claim: among rooms on the current floor not already held by this party, pick the
highest-value one the party can afford this turn (Steel ≥ threat, Cunning ≥ lock,
trinity-or-Lorekeeper for Vault). Place/strengthen a marker; add to
held. (Abstraction: one claim attempt per turn; "contest" = simply adding your own marker, majority resolved at collapse.) - Loot: `unbanked_loot += greed × loot_per_greed × depth_factor(floor)
- production(held) + reaver/gnoll bonuses`.
- Recruit: if
mettle ≥ recruit_costand the controller wants to grow, add a die of the Calling's recruit kind to the bag (Prospector discount; Golem-born can't take Relics). - Exit decision (B6): Cash Out, set Last Stand, or persist.
B4. The Maw
After all turns in a round r:
speed = base_rate + accel * r + dread_push * total_dread_this_round
accum += speed
while accum >= 1.0 and frontier >= 1:
accum -= 1.0
collapse(frontier) // score rooms (B5) + Take parties on this floor
frontier -= 1
collapse(f): for each room on f, the owner with the greatest summed marker strength
takes base_value × f Glory (ties split, floor-divided). Then every active party
whose floor == f is Taken: if last_stand, score the Worthy End bonus
(f × worthy_factor + held_value, ×1.5 Wardancer); else lose unbanked loot + all its
active markers (a feel-bad event, counted). The party is removed; the player may
draft a new one next round at the Threshold.
B5. Scoring
Glory accrues from: room majorities at collapse, Cash-Out banks (loot + depth dividend), and Worthy-End bonuses. At game end (frontier < 1), any still-active party is force-Taken under the same B4 rule (Last Stand pays; otherwise unbanked loot is lost). Highest total Glory wins; we also record the margin (winner − runner-up).
B6. Controllers (the bots under test)
Each is a pure function of the public game view. Risk appetite and exit timing are the levers that distinguish them.
- CashOut (Cautious). Targets a moderate depth; presses on rarely; Cash-Out as
soon as banked-worthy loot clears a small bar or the Maw is within
safe_marginfloors. Rarely sets Last Stand. Models the safe Decline player. - PressOn (Greedy/Engine). Recruits hard early; targets rooms to hold; presses aggressively; persists, fleeing upward only when the Maw is one floor away; Cashes Out only when forced. Models the engine-builder who risks the clock.
- WorthyEnd (Martyr/Diver). Rushes to the deepest reachable floor; sets Last Stand as soon as it holds a Vault/Throne (or is Wardancer); presses hard; rides the floor into a Worthy End. High variance, high ceiling.
- Balanced (Adaptive). Reads
collapses_until_my_floorvs. banked value: Cash-Out when the Maw is close and it has a worthwhile bank; opportunistically converts to a Worthy End when deep and doomed; otherwise presses moderately and grows. The "good human" baseline.
B7. What we measure (written to CSV/JSON; see analysis/)
- Win rate by strategy (mixed tables) → dominance check (target: no strategy > ~40% in 4-player, none < ~12%).
- Win rate by Lineage and by Calling → asymmetry fairness (flag any > ~1.6× the mean).
- Game length (rounds) → pacing (target band ~8–14).
- Victory margin as a fraction of the winner's score → runaway check (lower = tighter).
- Feel-bad rate: Takes-without-Last-Stand per game → keep low.
- Cash-Out timing spread: distribution of the depth/round at which winners cashed out → is the Decline decision genuinely live, or is there one correct moment?
Part C — Revisions after adversarial review (v2, what the engine implements)
Two independent reviewers (a "fun/decisions" lens and a "balance/exploits" lens) tore into v1 before any code was written. They converged on the same structural flaw, so v2 folds the high-leverage fixes in. The engine implements v2. The deltas:
-
Value rises with the Maw (the big one). Problem:
glory = base×depth+ bottom-up collapse correlated value with time — the climax landed mid-game, the endgame fizzled on cheap floors, and the Worthy-End catch-up valve closed in the back half (no deep floors left to dive into) → a back-half runaway, contradicting the whole pitch. Fix: on collapse, a fraction (value_rise_frac) of each room's unclaimed value rises to the floor above as "refugee plunder." The Maw's frontier is therefore always the swelling hot zone, all the way up — the final Floor-1 collapse is now the biggest scoring event, the arc crescendos, and a trailing player can always dive into the (now-shallow) frontier for a real comeback. -
Re-entry near the frontier. Problem: a fresh party from the Cash-Out loop starts at Floor 1 and can never reach the deep live floor before it collapses → Cash-Out self-limited to shallow farming; deep game decided once, early. Fix: re-entering parties insert at
max(1, frontier − reentry_gap)— the upper floors are eaten anyway, so new delvers drop in near the action. Keeps every party relevant. -
One collapse per round (carry the remainder). Problem:
while accum ≥ 1.0could eat two floors in a round late-game, Taking "I'll flee next turn" parties with no Last Stand — a systematic feel-bad. Fix: at mostmax_collapses_per_round(default 1) collapses per round; the overflow carries inaccum. "One floor away" is now an honest promise. -
Worthy End = burst + denial, not a bigger Cash-Out. Problem: Cash-Out did almost everything Worthy-End did, safely and repeatably, so the triangle was a binary and Worthy-End read as the loser's button; also a
held_valuedouble-count risk. Fix: the two exits now have non-overlapping upside. Cash-Out = the long game (loot + depth dividend + Fallen markers that keep earning). Worthy-End = burst + denial: a guaranteedworthy_factor × deepest_floorspike and the Maw consumes your held rooms clean — their value is removed from the board so no rival inherits it. Now a leader takes a Worthy-End to deny a chaser a 36-point Vault.worthy_held_bonusis 0 by default (no double-count); it's a separate knob. -
Variable-strength claims + assault progress. Problem: contest-by-marker-visit was solitaire and un-reactable; deep claims were a ~5% one-turn lottery with no floor. Fix: a claim's marker strength = 1 + symbols invested (Warden ×2), so majority is a live bid; and unmet Steel/Cunning accumulates as assault progress on the room across turns, so a near-miss is never a total zero.
-
Lineages get behavioral hooks; dead cells fixed. Problem: Lineages were flat stat tweaks (no "two halves surprise you"), and some combos negated themselves (Golem-born Prospector locked out Relics; Gnoll Reaver / Revenant Hierophant stacked the same axis). Fix: Dvergar ignores room threat on its claim (smash-through — now Dvergar Lorekeeper cracks guarded Vaults); Revenant converts Dread→Mettle (peril as fuel, a decision, not redundant immunity); Golem-born's cost is now −1 hand size (orthogonal — and it cancels Prospector's +hand, no dead cell). See
content.rsfor the final tables. -
Sub-linear depth + comeback rubber-band, both as knobs. Room glory is
base × (1 + depth_coeff × (depth−1))(depth_coefftunes the cliff), andcomeback_bpoptionally scales a trailing party's exit payouts by its glory deficit. Both default conservatively and are what the sweeps actually move.
These are the hypotheses the sim must now confirm: that the triangle is live (no exit
~45% of winners' choices), that deep rooms are contestable but not free, that the runaway is dead (tight margins; real comeback rate), and that the feel-bad is rare.
B8. What the sim deliberately does not model
Intra-floor geometry & corridors; denizen reputation as a full subsystem (folded into a
threat modifier); trading/negotiation (no table talk to simulate); the exact card/draft
UI. These don't move the six questions above, and adding them would trade clarity for
false precision. The balance levers that do matter all live in configs/default.json
and in the Lineage/Calling tables in deepfall-core/src/content.rs.