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 @@ - +