Skip to content

Balance evidence pack — soak telemetry, 2026-07-15

Balance evidence pack — soak telemetry (2026-07-15, overnight W5)

Section titled “Balance evidence pack — soak telemetry (2026-07-15, overnight W5)”

Evidence + proposals for the §2 “Balance-tune pass with soak telemetry in hand” item on docs/RELEASE-0.1.md. No consts were changed — every recommendation below is labeled PROPOSAL — Chris's call.

100 autopilot runs across 11 soak reports (reports/soak-*.json, 2026-07-14 → 07-15), including 2 targeted sweeps run for this pack:

Slice Runs What it covers
Fresh-save, all 7 hulls, solo+co-op, seeds 1000-1003 (soak-1784064266) 56 The uniform per-hull comparison set (10-min cap)
Fresh-save, cobalt+obsidian, solo+co-op, seeds 5000-5002 (soak-1784100096, new) 12 Seed-independence check on the survival window
Invuln (late-game coverage), cobalt+obsidian, solo+co-op, seeds 3000-3002 (soak-1784065064 + reruns) 14 Full 10-min windows, dimensions, late arsenal
Invuln solo, aurum+prism, seeds 3000-3001 (soak-1784100037, new) 4 Solo boss-duel duration proxy across hull bonuses
Early short-cap smoke runs (1-2 min caps) 14 Excluded from per-hull medians (capped windows)

Method caveats — read before trusting any number:

  • Damage is pre-mitigation ATTEMPTS (SoakStats.on_damage hooks before mitigation) — shares overstate weapons that hit phased/armored targets (e.g. vs Glass Wisp).
  • AutoPlayer aims the manual weapon at the nearest enemy within 400px every tick — the Aim weapon runs at its maximum possible duty cycle. Human aim share will be lower; treat the Aim numbers as an upper bound.
  • AutoPlayer’s upgrade policy is “always take a new weapon, else first offered” — arsenal breadth is maximized, stat-pick synergy is unoptimized. Build quality ≈ a novice player’s; survival times are a lower bound on human play.
  • Invuln runs that “die” or flag SOFTLOCK are known artifacts, not bugs: dash-into-solid-hazard damage bypasses dev_invuln (§4 item, found by W3), and the SOFTLOCK invariant fires on any boss duel longer than 3 min (W3’s §2 verdict). All 7 invariant failures across the 100 runs are one of these two; 0 genuine failures, 0 cross-run anomalies.
Context Fresh-save (82 runs) Late-game/invuln (18 runs)
aim (manual) 59.1% 22.0%
blaster (starter) 19.8% 54.9%
drone 8.6% 1.4%
momentum_core 3.6% 2.2%
thunder_wake 2.1% 2.2%
everything else (11 weapons) ≤1.8% each ≤3.4% each
unattributed 1.1% 2.8%
orbit ~0 (4 dmg total) ~0 (91 dmg total)

Two weapons account for ~77-79% of all damage in every slice. The 2026-07-09 content batch registers but is marginal: wildfire peaks at 3.4% (invuln), momentum_core 3.6% (fresh), railgun/scythe ≤0.4% everywhere.

Kill share mirrors damage: fresh-save runs kill only Swarmer/Shooter/Charger (types 0/2/4); invuln runs kill 21 distinct types (Swarmer 7.6k, then Shooter 1.2k, Charger 1.0k, Tank-Missile 303, Coil/Orbiter/Lancer/Centurion 100-190 each, long tail of 1-85).

Fresh-save survival window (uniform 56-run sweep, seeds 1000-1003)

Section titled “Fresh-save survival window (uniform 56-run sweep, seeds 1000-1003)”
Hull Solo deaths (s) Co-op deaths (s) Solo lvl at death
cobalt (default) 45-93 90-137 4-8
manta 64-116 63-108 5-12
amethyst 64-109 101-124 6-10
fuchsia / prism 87-111 87-125 7-9
aurum 98-127 110-126 7-9
obsidian (cruiser) 55-184 147-170 4-15
  • Every one of the 82 fresh-save runs died; solo median death ≈ 91s, co-op ≈ 109s.
  • Seed-independence confirmed: the new seeds-5000 sweep reproduces the same windows (cobalt solo 59-95s, obsidian solo 115-127s).
  • The first boss spawns at ~t13380 (~223s). Max solo fresh-save survival ever observed: 184s. A fresh-save solo (autopilot) player mathematically never sees a boss or a dimension. Exactly ONE fresh-save run reached a boss: co-op obsidian seed 5000 killed it at ~t13.4-22.8k, entered the fire dimension, died at 381s.
  • Cobalt — the default starter — is the weakest fresh-save survivor of all 7 hulls (its +15% move speed does the least for a kiting survivor vs aurum’s +5 armor or obsidian’s +70 HP). Caveat: autopilot may underuse speed vs a human dodging.
  • Obsidian quantifies the §4 “near strict-upgrade” concern: ~1.5-1.6× the frigates’ survival solo and co-op, highest levels reached, and the only hull to reach a boss on a fresh save.
  • Fresh-save: median level 9 by ~2 min (≈1 level / 13s early) — generous but bounded.
  • Invuln 10-min runs: solo levels 17-30 (median ~25), co-op 30-45 (median ~35; shared party kill-XP banks into both pilots).
  • No runaway: the pre-XP_LEVEL_GROWTH pathology was level ~250 after 3 bosses; the compounding threshold now holds 10-min runs to ≤45 even in co-op.

Solo boss-duel duration (ties to the §2 boss-adds decision)

Section titled “Solo boss-duel duration (ties to the §2 boss-adds decision)”
  • W3’s instrumented repro: solo boss ~6.6k HP at ~31 HP/s autopilot DPS → ~3.6 min duel in a deliberately-emptied arena (trickle adds are dead code — open §2 item).
  • The >3-min SOFTLOCK proxy fired on solo runs of all 4 hulls tested (cobalt, obsidian, aurum, prism — new sweep) on seed 3000, and on obsidian seed 3001; co-op never flags (its ~2× DPS keeps the duel under ~2 min). Solo duels straddle 2.5-4 min depending on build luck.

3 · What the data says about each §2 named const

Section titled “3 · What the data says about each §2 named const”

FIRE_RATE_CAP = 3.0 — working as designed; keep. The cap’s job was to stop multiplicative RoF snowballs (the historic DPS-321 run); no run in 100 approaches that. Late-game blaster concentration (54.9%) is a weapon-baseline diversity problem (kinetic-crystal power/multishot rungs all feed the starter), not a cap failure — lowering the cap would flatten the power fantasy without redistributing share.

BOSS_HP_TIME_FRAC = 1.0 — the one const the data argues to move, conditionally. At autopilot DPS the solo duel is ~3.6 min in an empty arena. But this decision is coupled to the open §2 boss-adds item: trickle adds during the duel would give the fight (and the player’s leech/XP economy) something to chew on, making 1.0 fine.

XP_LEVEL_GROWTH = 1.06 — validated; keep. Bounded 10-min levels (≤45 co-op, ~25 solo median), healthy early pace, no starvation and no runaway across 100 runs.

ELITE_HP_MULT = 27.0 / ELITE_CONTACT_MULT = 1.45 — unmeasurable with current telemetry; do not tune blind. kills_by_type doesn’t distinguish elite kills (the is_elite flag isn’t in the sink) and there is no spawn→death timing, so elite TTK cannot be computed from any existing report. Note ELITE_CONTACT_MULT is already ceiling-capped at 1.45 by the test_difficulty.gd “no enemy out-damages a boss” guard.

PLAYER_CRIT_MULT = 2.0 (15% “Focus”) — crit was picked 13× across the sweep but the sink doesn’t attribute crit vs non-crit damage; no evidence either way. Playtest question (§3), not a telemetry one.

The Aim ~60% question — yes, it’s crowding out the arsenal, with caveats. Baseline DPS explains it fully: Aim = 6 dmg / 0.24s = 25 DPS with pierce(1) + 48px impact burst; Blaster = 4 dmg / 0.45s = 8.9 DPS. Under constant autopilot aim that 2.8× ratio yields the observed 59-60% fresh-save share. The caveat cuts both ways: humans won’t hold perfect aim (share drops), but humans who do learn it get a weapon that outguns their whole arsenal combined — which undermines the crystal-threshold ladder the arsenal progression is built on. Related finding: the game’s #1 and #2 damage sources (Aim, Blaster) are both completely silent (§4 item, W2).

P1 — Trim the Aim weapon’s baseline, keep its ladder. PROPOSAL — Chris’s call. WeaponAim.DEF_COOLDOWN 0.24 → 0.32 (25 → ~19 DPS; alternative: DEF_DAMAGE 6.0 → 4.5 for the same effect). Expected: fresh-save aim share ~60% → ~45%, arsenal weapons regain early relevance, ladder rungs (aether 5 power, kinetic 10 pierce…) become the way Aim earns its dominance back — across-runs progression, per the balance philosophy. Risk: the §3 “is the manual weapon worth learning?” playtest may already say it feels weak on a controller; sequence this AFTER that playtest, and remember autopilot share is an upper bound.

P2 — BOSS_HP_TIME_FRAC 1.0 → 0.8, ONLY IF the clean-arena duel is blessed. PROPOSAL — Chris’s call. If the §2 boss-adds decision lands on “delete the dead code, bless the empty-arena duel”, cut solo duel ~3.6 → ~2.9 min. If trickle adds get wired in instead, keep 1.0 and re-measure — adds feed leech/XP and change duel economics. Risk at 0.8: meta-progressed builds melt bosses again (the original reason HP scaling exists); mitigate by re-running the invuln soak after the change (SOFTLOCK flags should drop to ~0 solo).

P3 — Keep XP_LEVEL_GROWTH = 1.06 and FIRE_RATE_CAP = 3.0. PROPOSAL — Chris’s call. Both consts demonstrably do their anti-snowball jobs across 100 runs; the remaining late-game blaster concentration is a per-weapon baseline issue (post-0.1 diversity pass), not a knob issue. No change.

P4 — Don’t touch ELITE_HP_MULT/ELITE_CONTACT_MULT yet; add elite telemetry first. PROPOSAL — Chris’s call. One-line-ish QA change: pass is_elite (and spawn/kill ticks) through Sim.stats_sink so elite TTK is computable, then re-sweep. Tuning a 27× mult with zero TTK data would be exactly the “torturing high-level data” trap.

P5 — Decide the intended fresh-save arc explicitly; if run 1 should touch a boss, soften the 60-120s ramp rather than contact damage. PROPOSAL — Chris’s call. Data: every fresh-save run dies at ~45-184s; the boss is at ~223s; solo can never reach it. That’s coherent with meta-progression-first (die → spend gold → push further), but it means a new player’s first several runs end before the game’s first real spectacle. If that window should widen: prefer slowing the minute-1-3 spawn-pressure ramp or +base HP (100 → 115) over any contact-damage change (threat stays HP/numbers-driven per the philosophy). If the current arc is intended — no change, and the first-boss moment becomes an earned milestone. Autopilot ≈ novice skill; expect humans to add ~30-60s.

P6 — Investigate Orbit before any balance conclusions. PROPOSAL — Chris’s call (investigation, not a const change). Orbit dealt 95 damage total across 100 runs while being picked 7 times — indistinguishable from inert. Plausibly the autopilot’s constant kiting keeps the shard ring off enemies, but 95 total damage over ~70 minutes of combined runtime smells like the Disruptor-slow/Halo-Chain class of silently-inert bug. Suggest a §4 punch-list line: one instrumented run with orbit forced, watch its contact-damage path. (Also noteworthy, already known: cobalt is the weakest fresh-save starter, and obsidian’s strict-upgrade profile is now quantified — feeds the §4 frigate-niche line.)

P6 RESOLUTION (W8, 2026-07-15, test commit ea2cb64) — NOT a bug; design-scale DPS. Three hypotheses discriminated:

  • (a) attribution gap — NO. sim.gd wraps every arsenal weapon update in damage_context = wid (sim.gd:815) before WeaponOrbit.update() calls elemental_system.damage_enemy(), and the sink records pre-mitigation attempts under that context — the 95 damage WAS orbit’s own correctly-attributed bucket, nothing leaked to “unattributed”.
  • (c) inert code path — NO, definitively. New GUT test test_orbit_full_contact_second_removes_exactly_base_damage_hp (tests/test_weapon_orbit.gd): enemy frozen in 100% shard contact loses exactly base_damage (1.2) HP per second. The damage path works precisely as written.
  • (b) autopilot kiting — SECONDARY, not root cause. 95 recorded damage ÷ (1.2 × dt per contact-tick) ≈ ~79 enemy-contact-seconds across the 7 runs that picked orbit — contact DID happen, repeatedly. But even a hypothetical 100%-uptime 7-minute run yields only ~500 damage (420 s × 1.2), still a rounding error vs the aim/blaster totals.

Root cause: orbit’s bible base_damage 1.2 is consumed as continuous contact DPS (dmg := base_damage * damage_mult * dt, unchanged since its first commit 6c63944 “continuous DPS”; bible value only ever moved 0.8 → 1.2). Every other weapon spends base_damage per hit-EVENT: beam = 0.8 per 0.1 s tick ≈ 8 DPS, blaster = 4 per 0.45 s shot ≈ 8.9 DPS/target, thunder_wake = 20 per 3 s ≈ 6.7 DPS — orbit’s 1.2 DPS/enemy is ~7× under its weakest peer before upgrades. Minor aggravator: at 0.02/tick attempts, any armor ≥ ~0.027 floors orbit to the 25% minimum (0.3 DPS vs armored enemies). Proposal — Chris’s call: raise orbit’s bible base_damage toward the peer band (~8–15 as contact DPS; a shard can hit multiple enemies at once and has zero cooldown, so parity is below beam’s 8, not above). The pinned magnitude test documents the live value and says to update BIBLE_BASE_DAMAGE with any rebalance.

  • Aggregation script (throwaway): parses all reports/soak-*.json, splits shares by invuln/coop/hull — logic documented in this file’s tables.
  • New sweeps: scripts/soak.sh --runs=2 --ticks=36000 --ships=aurum,prism --coop=solo --seed0=3000 --invuln=1 → soak-1784100037.json; scripts/soak.sh --runs=3 --ticks=36000 --ships=cobalt,obsidian --coop=both --seed0=5000 → soak-1784100096.json.
  • Const values cited from sim/sim.gd (lines ~140-230), sim/weapon_aim.gd, data/bible.json (blaster), sim/ship_bonuses.gd, sim/weapon_thresholds.gd (“aim”), as of commit 74e7197.