Repository navigation
v1.24.0
v1.24.0 — The Arena Has Waves Now
Last release made arena combat hit back. This one makes each fight harder than the last.
In v1.23 every round of a tier felt roughly the same — monsters scaled a little per round but the curve was nearly flat. You'd clear all 10 rounds of the Gauntlet at full HP because rounds 1 and 10 played out the same way. That's not what the user asked for, and the data didn't lie: a L150 prestige-3 Godslayer was clearing the entire 49-round Godslayer's Court at 39% HP, taking 1% of max HP per round on average. The arena's headline tier was a victory lap.
v1.24 introduces wave-based escalation — a step function on enemy HP, accuracy, and crit chance that turns each tier into a deliberate gauntlet where round 10 is something you genuinely flex about clearing.
⚔️ Wave-Based Combat
Every arena round is now mapped to a difficulty wave. The wave determines three independent multipliers that compound:
| Wave | Rounds | HP multiplier | Hit cap | Enemy crit% |
|---|---|---|---|---|
| Warmup | 1-3 | ×1.0 | 18 (10% land) | 0% |
| Building | 4-6 | ×1.4 | 17 (15% land) | 3% |
| Tense | 7-9 | ×2.0 | 15 (25% land) | 6% |
| Boss-tier | 10-15 | ×3.0 | 14 (30% land) | 8% |
| Brutal | 16-25 | ×4.5 | 12 (40% land) | 12% |
| Nightmare | 26-40 | ×6.5 | 10 (50% land) | 18% |
| Endgame | 41+ | ×9.0 | 8 (65% land) | 22% |
Each row is a wall. Rounds 1-3 are a warmup so newbies can ease in. Round 4 is the first wall — monster HP nearly doubles. Round 7 is the second wall — monsters now have a 25% land rate against your defense regardless of how high you stacked it, and they have a 6% chance to crit you for double damage. Round 10 is the boss-tier wall — almost no one will clear it on their first run.
For your L26 Warrior with a Rare+4 weapon, the Gauntlet now looks like this in real numbers:
| Round | Enemy HP | Enemy hit% | Enemy crit% | Realistic swings to kill |
|---|---|---|---|---|
| 1 | 127 | 10% | 0% | 3 |
| 5 | 207 | 15% | 3% | 5 |
| 7 | 322 | 25% | 6% | 8 |
| 10 | 707 | 30% | 8% | 17 |
The cumulative damage in a single Gauntlet attempt — even when you cash out at round 7 — now eats 30-50% of your HP. Pushing to round 10 means real risk of KO.
💥 Enemy Critical Hits
Late-round enemies can now crit you for double damage with a new message variant:
CRITICAL! The Heap Corruptor crushes your guard for 88 damage! HP: 60/190
CRITICAL! The Page Fault Phantom lands a devastating blow! 76 damage! HP: 14/180
CRITICAL! The Race Condition Reaper eviscerates you for 92 damage! HP: 0/152
Crit chance is 0% in the warmup waves so the early game is unchanged, then ramps up: 3% in wave 2, 6% in wave 3, 8% in boss-tier (wave 4), all the way to 22% in endgame waves. A boss-tier 30-swing fight at 8% crit chance gives you roughly 2.4 expected crit damage events — enough to randomly swing a marginal fight into a KO.
The crit message is distinct (red CRITICAL! prefix, different action verbs) so you can tell when it happens.
🎯 Accuracy Cap Ramps Per Wave
In v1.23 the enemy hit threshold was capped at a fixed 18 across all rounds, giving a permanent 10-15% land rate regardless of how deep you pushed. That's why round 25 of Abyssal felt the same as round 5 — the enemy hit rate was identical.
In v1.24 the cap is per-wave. Warmup cap is 18 (10% land); by Wave 4 (round 10) it's 14 (30%); by Wave 6 (round 26) it's 10 (50%). A defense-stacked tank still benefits from gear, but the cap eats into them progressively as they push deeper into a tier.
🧪 The Black-Mirror Balance Simulator (dev-tool)
The fixes in this release weren't tuned by feel. They came out of a Python harness at dev-tools/balance-sim/ that runs hundreds of compressed shellquest playthroughs in parallel and persists every metric to SQLite. Think of it as the Hang the DJ episode for shellquest: a thousand simulated lives across class × race × strategy combinations, each one driving a real sq binary through tick → equip → enchant → arena cycles, recording every action, every drop, every arena attempt for later analysis.
The simulator validated this release end-to-end. For the v1.24-soft tuning we shipped:
- Pit (tier 1) — 13/13 Wizards survived, 6/6 Rogues, all clearing 4 rounds. The entry tier still works for newbies. ✓
- Gauntlet (tier 2) — most attempts end in KO around round 7-9 (~0-30% survival rate). Pushing to round 10 is a real flex. ✓
- Enemy crits fire on schedule — 0.14-0.50 crits per arena attempt depending on tier depth. ✓
- No class is broken — all 5 classes reach L40 in 1300-2100 ticks, similar progression curves. ✓
The harness lives outside the shellquest binary — it's a Python tool that calls sq as a subprocess, parses save.json directly, and aggregates 24-run sweeps in ~4 minutes wall clock with --parallel 4. Future balance changes get tested with empirical data instead of intuition.
Usage:
cd dev-tools/balance-sim
# Run a small validation sweep
python3 runner.py --runs 3 --classes Warrior Wizard --strategies greedy balanced \
--target-level 40 --max-ticks 2500 --parallel 4 \
--tuning-label my-test
# Generate the report
python3 report.py --tuning-label my-test --output reports/my-test.mdSee dev-tools/balance-sim/README.md for the full reference.
🧪 Tests
Seven new arena tuning tests pin the wave-based behaviour:
enemy_hp_at_round_ten_is_meaningfully_harder_than_round_one— locks in ≥4× HP scaling at round 10.enemy_hp_curve_is_monotonic_non_decreasing_through_round_fifty— guards against accidental wave-table inversions.enemy_hit_cap_grows_stricter_in_later_waves— locks in the per-wave cap ramp.high_defense_player_takes_more_hits_in_late_rounds_than_early— verifies the cap actually changes hit rate end-to-end.enemy_does_not_crit_in_warmup_waves— exhaustive check that rounds 1-3 are crit-free.enemy_can_crit_in_late_waves_but_not_always— confirms the crit roll is probabilistic, not deterministic.enemy_crit_message_contains_critical_marker_and_doubled_damage— locks in the newtournament_enemy_critmessage contract.
Total: 361 passing, up from 354.
🩹 Migration & Behaviour
- No save format changes. Existing characters continue working without touching disk state.
- Arena combat will feel dramatically different on the next
sq arenarun, especially past round 4. - Newbie Pit experience preserved (rounds 1-3 unchanged from v1.23).
- The
enemy_hit_threshold_capfield inArenaCombatTuningand the no-roundcompute_enemy_hitwrapper were removed (the wave function now owns these). External consumers (none in-tree) would need to usecompute_enemy_hit_at_round(..., round)andarena_wave(round).hit_threshold_cap. - All combat surfaces (arena + boss + overworld tick) still share the crit formula change from v1.23.