diff --git a/gameplay.js b/gameplay.js
index a6bbace..781a0d6 100644
--- a/gameplay.js
+++ b/gameplay.js
@@ -5,7 +5,7 @@ import { P, O, ball, score, crowd, G, court, other, deuceSide, setupPoint, sendB
import { audio, pock, swish, whoosh, applause, voice, sfx, aww, zombieMusic, zombieDuck, menuDuck, splat, shriek, boom } from './audio.js';
import { axisX, axisZ, takeFlickAim, touchPX, resetInput } from './input.js';
import { W } from './render.js'; // runtime-only cycle (render imports gameplay), same pattern as input/zombies
-import { updateZombies, spawnZombie, spawnRacketZombie, spawnMachine, spawnChapterBoss, zombies, gore, explode, meleeSwipe, extras, parts, pellets, shots, playerGore, eatenBleed, resetZombies , firePellet , spawnBarrel , fireBeam , pops, popText } from './zombies.js';
+import { updateZombies, updateParts, spawnZombie, spawnRacketZombie, spawnMachine, spawnChapterBoss, zombies, gore, explode, meleeSwipe, extras, parts, pellets, shots, playerGore, eatenBleed, resetZombies , firePellet , spawnBarrel , fireBeam , pops, popText } from './zombies.js';
// ------------------------------------------------------------- ballistics ----
// Launch ball from (x0,y0,z0) so it arrives at (tx, tz) with horizontal speed s under gravity g.
@@ -742,13 +742,7 @@ export function startBossFight(chapter) {
const art = bossArt(chapter);
G.card = { title: art.name, color: UI.bad, t: TUNE.setCardT };
G.flash = null;
- if (!G.seen.boss) { // the rules change: a wall, and a thing that shoots back
- G.seen.boss = true;
- showModal({ title: 'IT BRINGS A MACHINE', color: UI.bad,
- body: ['IT THROWS BALLS AT YOU', 'SWING TO RETURN THEM — OR SWISH TO BAT THEM AWAY',
- 'SWIPE SIDEWAYS TO STEP OUT OF THE WAY',
- 'A HIT COSTS BLOOD. WIN A DUEL TO HEAL.'] });
- }
+ // (the four-line machine instruction modal is gone — people figure it out)
}
// the chapter boss is down: the parked game beat resumes and normal spawning comes back
@@ -767,7 +761,7 @@ export function endBossFight() {
// long hold — the chapter and the crowd move down to the subs where they belong.
// (no 'GAME n NEXT' line: the bar under the scoreboard prints the game number permanently, and a
// card that repeats what the HUD already says is the clutter this pass is meant to remove.)
- G.card = { title: 'YOU DID IT', color: UI.pick, t: TUNE.bossWinT,
+ G.card = { title: 'EPIC!', sub1: 'YOU DID IT!', color: UI.pick, t: TUNE.bossWinT,
wait: TUNE.bossDeathT }; // ...after the body has finished coming apart
ball.active = false;
// a duel the handback just started owns the phase; otherwise hold the boss beat, and never
@@ -1500,6 +1494,7 @@ export function update(dt) {
// --- zombies + transition timeline
if (G.mode !== 'tennis') updateZombies(dt);
+ else updateParts(dt); // tennis has no zombies but its bounces still kick up dust that must settle
tickTestMode(dt); // keeps the sandbox stocked and rolls it a barrel now and then
if (G.meleeT > 0) G.meleeT -= dt;
if (G.rackGlow && (G.rackGlow.t -= dt) <= 0) G.rackGlow = null; // the fresh-pickup pulse fades out
diff --git a/index.html b/index.html
index 690fefe..309d80c 100644
--- a/index.html
+++ b/index.html
@@ -398,6 +398,6 @@
-
+