Make every weapon hurt the boss, drop his HP bar, un-cap the director

Steps 1-3 of the late-game depth plan, after Oliver's 50+ game playtest.

"Sometimes the racket zombie doesn't seem harmable" was real, not a feeling.
Three of the five rack slots did nothing at all to him and said nothing about
it: TRIPLE side balls skipped him, GUN and horde pellets skipped him, fire
couldn't ignite him. BOMB meanwhile deleted him outright ignoring his hp. All
of it now routes through one wound() with a TUNE.dmg* table, so damage is
proportional to the body and a future 20 hp boss needs no new code. Fractional
damage banks on zb.chip so whole points only come off hp — the wound skins
switch on hp thresholds. His contact radius goes to 0.7 m, because part of
"unharmable" was just missing him. Melee still skips him and that's correct:
he's on the far side of the net and melee can't span it.

The HP bar is gone. It was the only floating UI on a body, it was on screen
for nearly the whole run, and nobody knew what it meant — while the wound
skins already say the same thing in the language every other multi-hit enemy
uses. A one-per-run modal explains what he is instead. Skins and bleed anchors
now read a fraction of hpMax, since his hp scales with the run.

And the plateau: every difficulty dial bottomed out by about game 12, so games
12-50 were arithmetically identical. Body cap, spawn gap, shamble speed,
variant mix, boss hp and horde size all keep climbing now, calibrated to track
the old curve through game 12 rather than replace it. One deliberate exception:
shamble speed was time-based and maxed during game 2, so the early game is
genuinely gentler now — zSpeedPerGame if that reads flabby.

HANDOFF carries the full spec for steps 4 and 5 (ranged attacks with player
damage, then chapter bosses) including the decisions we settled, so the next
session can pick it up cold.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
wuwiandClaude Opus 5 committed 2026-07-30 12:30:27 +02:00
1 parent 4cf54603f3
commit ffac9b5512
6 files changed
+339 -54

No files matched your search

+12 -7
View File
@@ -190,15 +190,20 @@ function drawZombie(zb) {
} else if (SPR.z_gw) name = 'z_gw'; // a missing asset degrades to the last skin that loaded
}
else if ((zb.variant === 'a' || zb.variant === 'b') && zb.hp < TUNE.shamblerHp && SPR['z_' + zb.variant + 'w']) name = 'z_' + zb.variant + 'w'; // gashed shambler
else if (rk && zb.hp <= 1 && SPR.z_cw2) { name = 'z_cw2'; h = 1.52; } // headless: a head shorter, so the shoulders land where a whole zombie's do
else if (rk && zb.hp === 2 && SPR.z_cw1) name = 'z_cw1';
// The boss's damage is read as a FRACTION of full health — his hp scales with the run
// (TUNE.racketHpPerGame), so the old `hp === 2` / `hp <= 1` thresholds would have left a late-run
// boss looking untouched until the killing blow. Keep these in step with bleed()'s anchors.
else if (rk) {
const f = zb.hp / (zb.hpMax || TUNE.racketHp);
if (f <= 0.34 && SPR.z_cw2) { name = 'z_cw2'; h = 1.52; } // headless: a head shorter, so the shoulders land where a whole zombie's do
else if (f <= 0.67 && SPR.z_cw1) name = 'z_cw1';
}
drawStatic(name, zb.x, zb.z, h, Math.floor(zb.walkT * 5.2) % 2);
if (zb.burnT > 0) drawFlames(zb, h);
if (rk) { // HP bar floating above the mini-boss
const p = proj(zb.x, 2.05, zb.z), w = Math.max(10, p.s * 0.5), x = p.x - w / 2;
ctx.fillStyle = '#300'; ctx.fillRect(x, p.y, w, 3);
ctx.fillStyle = '#e03030'; ctx.fillRect(x, p.y, w * Math.max(0, zb.hp) / TUNE.racketHp, 3);
}
// No HP bar. It was the only floating UI on a body anywhere in the game, it was on screen for
// almost the whole run (a boss respawns every game you win), and nobody knew what it meant —
// while the wound SKINS above already encode exactly the same information in the language every
// other multi-hit enemy uses. The first-sight modal in spawnRacketZombie explains him instead.
}
// Fire, drawn procedurally instead of as a sprite sheet: a few vertically-stretched quads whose
// offsets ride each body's own phase (walkT), so no two burning zombies flicker in sync — and it