Rift Bolt detonation, power-shift calibration (2026-10-12)
Rift Bolt detonation: power-shift calibration (2026-10-12)
Section titled “Rift Bolt detonation: power-shift calibration (2026-10-12)”Spec: docs/superpowers/specs/2026-10-12-rift-bolt-detonation-design.md § Power budget. The goal
was to move part of the Rift Bolt’s damage into detonation (a hit on an element-stacked enemy
deals bolt_dmg * DETONATE_MULT_PER_STACK * stacks extra, plus DETONATE_SPLASH_FRAC of that to
neighbours within DETONATE_RADIUS) without changing average run power.
Result: WeaponAim.DEF_DAMAGE 6.0 → 5.25, DETONATE_MULT_PER_STACK stays 0.25
(splash 0.5, radius 70, boss 0.5 unchanged). Paired economy careers against the pre-feature base
show no effect detectable at n = 5 per profile (95% CIs of +/-8-15%); the weak profile leans about
5% under main on all four metrics (table below).
1. Stacks at Rift Bolt impact (measured)
Section titled “1. Stacks at Rift Bolt impact (measured)”Temporary, uncommitted counters in ElementalSystem.resolve_collisions / detonate() (bolt hits,
burst splash, detonations, stack histogram, direct and splash detonation damage, nominal and
effective = actual HP removed). Soak: tools/soak/soak_runner.gd --player=skilled (plain
SkilledAutoPlayer, AUTOPILOT_VERSION 2), branch at 6.0 / 0.25.
| set | runs | bolt hits | p (share that detonate) | stacks hist 1/2/3/4/5/6 | mean s̄ | median |
|---|---|---|---|---|---|---|
| fresh save, mortal, seeds 1000-1015 (median run 92 s) | 16 | 8752 | 0.205 | 759/291/147/104/79/410 | 2.82 | 2 |
| fresh save, invulnerable, 10 min, seeds 2000-2007 | 8 | 37874 | 0.257 | 2739/1323/1006/625/416/3618 | 3.57 | 3 |
Damage-weighted, detonation adds (at m = 0.25) nominal damage equal to 14.6% (fresh) / 26.7% (10-min) of the bolt’s direct + burst damage, splash included (splash is 20% of detonation damage fresh, 30% late). Many detonations overkill: only 51% (fresh) / 69% (late) of nominal detonation damage removes HP, versus 69% / 64% for the direct hit, because the direct hit lands first. Stack cap 6 is the second most common bucket in the fresh runs (410 vs 759 for 1 stack) and the most common in the 10-min runs (3618 vs 2739 for 1 stack): enemies the bolt ignores keep stacking.
2. Solving the shift
Section titled “2. Solving the shift”Brief: b * (1 + p*m*s̄) ≈ 6.0 (average) and b * (1 + 2m) ≈ 6.0 (a 2-stack hit ≈ today). Both
can only hold if p*s̄ ≈ 2; measured p*s̄ (damage-weighted) is 0.57 fresh / 0.89 late, so they
conflict. Per the brief the average wins. Solving with burst and splash included gives
b(m = 0.25) = 5.24 (fresh) / 4.73 (10-min). m was left at 0.25: lowering it toward the 2-stack
condition (m ≈ 0.07 at b = 5.25) would make detonation nearly invisible, and the spec also asks for
“stacked hits above and unstacked hits below today’s output”.
Resulting per-hit damage at base level: unstacked 5.25 (−12.5% vs 6.0), 1 stack 6.56, 2 stacks 7.88, 3 stacks 9.19, 6 stacks 13.13 (plus half of the detonation part as splash).
3. Run power: paired comparison vs. the pre-feature base
Section titled “3. Run power: paired comparison vs. the pre-feature base”Base = merge-base ad6112b1 (detached worktree, same seeds). Careers:
scripts/economy-careers.sh 5 150 72000 (5 seeds x weak/median/strong, every career runs until
the whole shop is bought, 13-28 runs each). “Paired ±” = 95% CI of the per-seed difference.
b = 5.25 (chosen):
| profile | runs to buy everything | mean run time | mean gold / run | mean level |
|---|---|---|---|---|
| weak | 25.6 → 26.0 (+1.6% ±7.9) | 230.8 → 209.3 s (−9.3% ±12.3) | 940 → 891 (−5.2% ±6.8) | −5.4% ±9.1 |
| median | 19.2 → 19.2 (0.0% ±9.1) | 332.5 → 344.0 s (+3.5% ±14.2) | 1262 → 1303 (+3.3% ±9.4) | +1.1% ±9.3 |
| strong | 13.0 → 13.2 (+1.5% ±13.0) | 527.2 → 541.0 s (+2.6% ±15.0) | 1812 → 1898 (+4.7% ±13.2) | +3.3% ±11.0 |
b = 5.0 (first candidate, rejected): weak careers needed +7.0% runs (±6.1) and earned −12.6% gold per run (±3.1), both outside noise; median/strong leaned weaker (+3.1% / +7.7% runs).
Fixed-seed soaks (64 fresh-save mortal seeds, 24 invulnerable 10-min seeds) were too noisy or insensitive to decide: mortal run time ±22-32% CI; invulnerable kill counts are spawn-limited (main 1388 vs branch 1384-1390, ±5-6%).
The tilt at 5.25 is the expected one: weak players (more aim error) detonate less and sit a few percent under main, strong players a few percent over. No difference is detectable at n = 5, but the weak profile leans the same way on all four metrics (about 5% under main). 5.25 matches the fresh-run solve (5.24), not the 10-min solve (4.73), so long runs sit slightly above main.
Caveats
Section titled “Caveats”- The autopilot under-rates detonation late-run. SkilledAutoPlayer (v2) aims at the most-stacked in-range enemy (≥ 2 stacks) only when nothing is within 160 px; otherwise it keeps the threat-cluster aim. A human who hunts stacked enemies will detonate more than p = 0.2-0.26, so human run power is probably slightly above main. Worth a telemetry check after release, not a reason to pre-nerf.
- n = 5 careers per profile detects ~8-13% effects on runs-to-complete, not smaller ones.
- Short 2400-tick knob runs (
tests/test_skilled_knob_baseline.gd) move kills both ways (0 / −10 / +14 / +3); that is noise, not signal. - All defaults remain live console tunables (
WeaponAim.DEF_DAMAGE,WeaponAim.DETONATE_MULT_PER_STACK, …), so a live retune does not need a rebuild.