diff --git a/HANDOFF.md b/HANDOFF.md
index 520857d..c8823bf 100644
--- a/HANDOFF.md
+++ b/HANDOFF.md
@@ -1172,6 +1172,19 @@ scaled so the BODY matches the standing frame (98% of sprite height) and the rac
this on any new pose with a raised prop.
## Gotchas learned the hard way
+- **Nothing outside the four slot accessors may know how many slots there are.** `endBurst` had
+ `[0, 1, 2, 3, 4].find(i => slotId(i) === id)`, which was correct for exactly as long as the rack
+ held five. `RACK_MAX` 4 → 9 and a burst weapon in slot 5..9 was suddenly unfindable, so it was
+ never spent: beacon, flamer, rocket and gun sat at their pickup count forever. Use `slotOf(id)`.
+ The serve weapons were untouched because they all spend through `spendSlot(G.weapon)` — the LIVE
+ index, never a search — which is why the laser looked fine while the other four did not.
+ Note also that spending re-indexes the rack (`spendSlot` splices), so a slot number goes stale the
+ moment any tin empties. Look weapons up by ID, not by a slot you cached a frame ago.
+- **A test that walks the game forward will quietly kill the player.** Three separate diagnostic runs
+ above returned nonsense (`stillCarried: true`, no laser fired at all) purely because `G.mode` had
+ become `'eaten'` several steps earlier and every gameplay entry point bails on that. When a probe
+ says a feature is broken, check `T.G.mode` before believing it. `setInterval(() => T.zombies.length = 0, 30)`
+ for the duration of the test is the cheap fix.
- **Stale ES modules are the #1 time sink.** python http.server sends no cache headers, so an edited
module often loads STALE. `preview_stop`/`preview_start` only helps if the port actually changes,
and holding 8641 with a throwaway socket **did not work reliably**. What DOES work:
diff --git a/gameplay.js b/gameplay.js
index 73da091..0d5412f 100644
--- a/gameplay.js
+++ b/gameplay.js
@@ -511,12 +511,20 @@ function startChangeover() {
// no tins here anymore — weapons are won in the duel, never handed out on a schedule
}
-// ---- the courtside rack. Five slots still, but only slot 0 is fixed: it is BALL (infinite), or a
-// FIFTH gathered weapon riding it temporarily. Slots 1..4 are whatever you have picked up, in order.
-// Everything reads through these three, so nothing else has to know how the rack is stored.
+// ---- the courtside rack. RACK_MAX + 1 slots, and only slot 0 is fixed: it is BALL (infinite), or
+// an overflow weapon riding it temporarily. Slots 1..RACK_MAX are what you have picked up, in order.
+// EVERYTHING READS THROUGH THESE FOUR, so nothing else has to know how the rack is stored — and
+// nothing else may hardcode how MANY slots there are. `slotOf` exists because endBurst did exactly
+// that ("[0,1,2,3,4].find(...)"), so the moment the rack grew past five, a burst weapon sitting in
+// slot 5..9 could never be found and never spent: beacon, flamer and rocket sat at their pickup
+// count forever. One accessor, one place that knows the range.
export const slotEntry = i => (i === 0 ? G.temp : G.rack[i - 1]) || null;
export const slotId = i => slotEntry(i)?.id || (i === 0 ? 'ball' : null);
export const slotStock = i => { const e = slotEntry(i); return e ? e.n : (i === 0 ? Infinity : 0); };
+export const slotOf = id => { // -1 if you are not carrying it
+ for (let i = 0; i <= RACK_MAX; i++) if (slotId(i) === id) return i;
+ return -1;
+};
export function selectWeapon(i) {
if (G.interlude) return; // the sudden-death duel is played under tennis rules — plain balls only
if (slotStock(i) <= 0) return; // dud: nothing in that slot (slot 0 is only ever empty if a spent
@@ -1022,8 +1030,8 @@ export function endBurst() {
const id = G.gunId;
G.gunId = null;
if (!id) return;
- const slot = [0, 1, 2, 3, 4].find(i => slotId(i) === id);
- if (slot !== undefined) spendSlot(slot);
+ const slot = slotOf(id);
+ if (slot >= 0) spendSlot(slot);
}
// The laser fired from a TAP (the keyboard/two-stage path). The drag path solves its own direction
diff --git a/index.html b/index.html
index ff69d58..fa47f93 100644
--- a/index.html
+++ b/index.html
@@ -184,6 +184,6 @@
-
+