Combat Risk/Reward Tuning Gates — How Spelunky, Hades, and Dead Cells Make Players Choose to Suffer

If you are building a roguelike combat system and your difficulty curve feels like it has only two states — trivial or unfair — this pattern gives you a structural alternative. Instead of a single "harder = more loot" slider, you model risk and reward as a series of tunable gates that players opt into.

Who This Helps

The Problem

Roguelike combat design tends to collapse in three ways:

ProblemSymptomRoot Cause
Risk ignoredPlayers only use safe strategies; the game gets boringReward does not scale with risk
Risk forcedDifficulty spikes without player consent; freedom feels fakeDifficulty curve rises without reward pools to match
Meta progression disconnectedUpgrades outside the run make in-run rewards feel meaninglessRun-level and run-between rewards are designed independently

The core argument: risk-reward balance is not a tuning-numbers problem. It is a structural pattern problem. Explicitly modeling "tuning gates" prevents unintended balance collapse and keeps player choice meaningful.

Core Idea — Gate Arrays

Instead of modeling risk-reward as a single continuous function, model it as a gate array:

RiskLevel ──→ [Gate₁] ──→ RewardPool₁
              [Gate₂] ──→ RewardPool₂
              [Gate₃] ──→ RewardPool₃
                  ⋮

Each gate defines:

  1. Entry condition: What state the player must be in to access this risk tier (HP, equipment, floor depth, elapsed time)
  2. Reward pool: The set of rewards that can only appear at this risk level
  3. Failure penalty: What happens if the player loses at this gate (run end, HP loss, resource drain)
  4. Tuning coefficient: A designer-adjustable margin — 0.0 (strict) to 1.0 (forgiving)

When a gate is tunable, designers can adjust reward pools and penalties independently without touching the global balance table.

How To Apply It

1. Define the Data Model

interface RiskGate {
  id: string;
  level: number;
  entryCondition: (state: RunState) => boolean;
  rewardPool: RewardDistribution;
  failurePenalty: Penalty;
  tuningCoeff: number;        // 0.0 ~ 1.0
  metaInfluence: MetaFactor[]; // how meta-progression adjusts this gate
}

interface RunState {
  currentHP: number;
  maxHP: number;
  floor: number;
  elapsedRooms: number;
  activeBuffs: Buff[];
  metaUpgrades: MetaUpgrade[];
}

2. Evaluate Active Gates at Checkpoints

function evaluateGates(state: RunState, gates: RiskGate[]): ActiveGate[] {
  return gates
    .filter(g => g.entryCondition(state))
    .map(g => ({
      gate: g,
      effectiveTuning: applyMetaInfluence(g.tuningCoeff, g.metaInfluence, state),
      adjustedRewards: scaleRewards(g.rewardPool, g.tuningCoeff, state),
      adjustedPenalty: scalePenalty(g.failurePenalty, state),
    }));
}

3. Let the Player Choose

The player sees the currently active gates and picks one. The chosen gate determines the reward pool sampled and the penalty applied on failure.

4. Keep Meta Progression Additive

Meta upgrades should only shift the tuning coefficient — never bypass the entry condition entirely. This preserves the run-level reward structure while still making the player feel stronger.

Reference Games

Spelunky HD

Each world (1-1 through 4-4) acts as an implicit risk gate. The bomb room, shop, and sacrificial altar are explicit risk choices. Failure penalties differ spatially: bomb room = instant death, shop = world-wide aggro, altar = 1 HP cost. Lesson: When risk choices are spatial ("where do I go?"), the feeling of agency is stronger.

Hades

The Heat system is an explicit CRRTG. Each Heat level from 1 to 64 is a gate combination. The penalty is always run-end, but the reward scaling makes failure feel like "I got more meta-currency even though I died." Lesson: When the penalty is constant, the reward curve alone can modulate risk acceptance.

Dead Cells

The Brutality/Tactics/Survival branches form an implicit risk spectrum. Weapon rarity tiers map to gate levels. The penalty is partial: cell loss plus run end. Lesson: Partial meta-currency loss as a penalty motivates retry better than a full reset.

Risk of Rain 2

Time-based difficulty scaling acts as an implicit gate. Every 5/15/25 minutes, the reward tier shifts. Artifacts (Command, Swarm) serve as explicit tuning coefficients. Lesson: Time-based scaling can feel like the player is being "pushed" rather than choosing — artifacts compensate by restoring explicit choice.

Common Mistakes

Failure ModeCauseMitigation
Too many gatesPlayer choice overload; gates get ignoredLimit to 3–5 gates (cognitive load boundary)
Auto-tuning coefficientDDA modifies tuning; player choices feel meaninglessDesigners only adjust tuning manually; DDA only modifies entry conditions
Meta progression bypasses gatesUpgrades invalidate entry conditions; every run starts at max riskMeta progression only affects the tuning coefficient, never the entry condition
All penalties are identicalEvery gate ends the run; low gates become pointlessVary penalties: at least 2 types (run-end vs. status penalty)
Reward pools overlapAll gates draw from the same pool with different weights; difference is invisibleEach gate has at least 1 unique item

Checklist

References

  1. Derek Yu. "Designing Spelunky." GDC 2017.
  2. Supergiant Games. "Building Hades: A Post-Mortem." GDC 2021.
  3. Motion Twin. "Dead Cells Post-Mortem: How We Made an Action Roguelike." 2019.
  4. Hopoo Games. Risk of Rain 2 patch notes and community forum. 2020–2024.
  5. Schell, Jesse. The Art of Game Design: A Book of Lenses (2nd ed.). CRC Press, 2019. Chapter 10: Balance.