Skip to content

Commit 4675a1e

Browse files
Stop the difficulty tiers paying the player back, and thin the escorts
Two findings from the third 24-seed run. CADET measured harder than PILOT -- 12 wins against 13, with longer boss fights (57.8s vs 48.0s) and more damage taken (5.4 vs 4.8) despite firing slower. The cause is the one only half-fixed two commits ago: enemies are salvage, so CADET's 0.85 budget bought fewer crystals, a worse ship and a longer fight. Narrowing that spread was not enough; every tier now fields the same number of enemies and the tiers separate on rate of fire and hull depth alone. HIVE MOTHER's fight ran to 65.6 seconds against 30 to 53 for the other four, and a fight that long accumulates damage whatever its patterns do. Escorts were carrying full wave hit points and soaking the player's fire. They are meant to be moving obstacles, not health bars: half hit points. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AKLqS4PgnCXrzKHDH8Cnzy
1 parent e686ce4 commit 4675a1e

2 files changed

Lines changed: 20 additions & 8 deletions

File tree

‎pc/nova/combat.py‎

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,15 @@ def spawn_wave(self, dt):
126126
self.spawn_t = gap
127127

128128
def spawn_escort(self, kind, x, y):
129-
"""A boss launching an escort. Weaker than a spawned wave enemy: they
130-
arrive in numbers and the boss is the real fight."""
131-
hp = max(1, data.ENEMY_HP[kind] + self.run.sector - 1)
129+
"""A boss launching an escort.
130+
131+
Half the hit points of a wave enemy. They arrive in numbers and they
132+
are meant to be moving obstacles, not health bars: at full strength
133+
they soaked so much of the player's fire that HIVE MOTHER's fight ran
134+
to 66 seconds against 30 to 53 for every other boss, and a fight that
135+
long accumulates damage whatever its patterns are doing.
136+
"""
137+
hp = max(1, (data.ENEMY_HP[kind] + self.run.sector) // 2)
132138
e = ent.Enemy(kind, max(data.PLAY_L + 12, min(data.PLAY_R - 12, x)),
133139
y, hp, self.run.sector, self.rng)
134140
e.score = data.ENEMY_SCORE[kind] // 2

‎pc/nova/data.py‎

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -402,13 +402,19 @@ def SEC_ACCENT(sector):
402402
# take a third of your hull in one mistake needs a hull you can afford to make
403403
# mistakes with -- otherwise "hard" just means "the first hit ends the run",
404404
# which is not difficulty, it is fragility.
405-
# The budget spread is narrow on purpose: enemies are also salvage, so a tier
406-
# that fields many more of them hands the player a better ship in exchange.
407-
# The tiers separate on rate of fire and on the depth of the hull bar instead.
405+
# Every tier fields the same number of enemies, and the column is kept only
406+
# because the endless Void still wants to scale.
407+
#
408+
# Narrowing the spread was not enough: enemies are salvage, so CADET's 0.85
409+
# bought fewer crystals, a worse ship, longer boss fights and more damage taken
410+
# than PILOT -- the easy tier measured *harder* than the intended one, 12 wins
411+
# against 13. A difficulty knob that pays the player back is not a difficulty
412+
# knob. The tiers separate on rate of fire and on the depth of the hull bar,
413+
# and on nothing else.
408414
DIFFICULTIES = (
409-
("CADET", 24, 0.85, 0.0, "Forgiving. Learn the patterns."),
415+
("CADET", 24, 1.00, 0.0, "Forgiving. Learn the patterns."),
410416
("PILOT", 18, 1.00, 0.35, "The intended fight."),
411-
("ACE", 12, 1.15, 0.78, "Fast, dense, unkind."),
417+
("ACE", 12, 1.00, 0.78, "Fast, dense, unkind."),
412418
)
413419

414420
# --- map nodes -----------------------------------------------------------

0 commit comments

Comments
 (0)