Triple-tap the scoreboard for a sandbox
A test mode for trying the new content without playing twenty games to reach it. Three taps on the scoreboard toggles it, three more turns it off, and a single tap is still the miss-log overlay. Same shape as the umpire triple-tap cheat it sits next to. It OVERRIDES the difficulty director rather than editing it, so the wave is the same whether you opened it in game 1 or game 40 and the run keeps running underneath: 8 bodies, a fixed 1.15 m/s shamble, a spawn every 1.6 s, and pickVariant pretending to be at game 20 so every body type can turn up. All four barrel weapons sit on the rack and are topped back up each frame, because committing a burst spends the whole tin and a sandbox that runs dry is not one. A barrel rolls out every 14 s so the pickup itself is testable too. The third tap must NOT toggle logShow: taps one and two already toggled it twice and it is back where it started, so toggling again left the miss-log overlay switched on behind you every single time. Also records the trap that cost a debugging round getting here: index.html loads main.js?v=N, and fetching 'main.js' does not bust that URL -- so main.js stayed stale through a reload while every other module was fresh, and the tap handler appeared to do nothing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
282f5145a9
commit
46e268973d
7 files changed
+101
-12
No files matched your search
@@ -5,7 +5,7 @@
|
||||
|
||||
import { TUNE, COURT, COURTS, UMP_H, UMP_X, EATEN_RESTART } from './config.js';
|
||||
import { P, O, ball, score, G, setupPoint, selectCourt } from './state.js';
|
||||
import { update, restartRun, keyPressed, solveShot, inServeBox, inCourt, forceZombies, splatPoint, deliverTin, selectWeapon, grantWeapon, showModal, dismissModal, startDuel, resolveInterlude, flickTarget, startBossFight, endBossFight } from './gameplay.js';
|
||||
import { update, restartRun, keyPressed, solveShot, inServeBox, inCourt, forceZombies, splatPoint, deliverTin, selectWeapon, grantWeapon, showModal, dismissModal, startDuel, resolveInterlude, flickTarget, startBossFight, endBossFight , toggleTestMode } from './gameplay.js';
|
||||
import { fitViewport, render, proj, RES } from './render.js';
|
||||
import { voice, ambient, menuMusic, menuDuck } from './audio.js';
|
||||
import { zombies, spawnZombie, spawnRacketZombie, spawnMachine, spawnChapterBoss, piles, gore, parts, pellets, extras, shots, explode, hurtPlayer, killPlayer , spawnBarrel } from './zombies.js';
|
||||
@@ -166,13 +166,26 @@ const maybeRestart = () => {
|
||||
cv.addEventListener('pointerdown', maybeRestart);
|
||||
addEventListener('keydown', maybeRestart);
|
||||
|
||||
// hidden shortcut: tap the umpire three times to summon zombie mode early
|
||||
let umpTaps = [];
|
||||
// hidden shortcuts: three taps on the UMPIRE summons zombie mode early, three on the SCOREBOARD
|
||||
// opens test mode (a medium wave plus every barrel weapon — see gameplay.toggleTestMode)
|
||||
let umpTaps = [], boardTaps = [];
|
||||
cv.addEventListener('pointerdown', e => {
|
||||
const r = cv.getBoundingClientRect();
|
||||
const x = (e.clientX - r.left) / r.width * (cv.width / RES); // logical coords
|
||||
const y = (e.clientY - r.top) / r.height * (cv.height / RES);
|
||||
if (x >= 6 && x <= 138 && y >= 6 && y <= 36) { G.logShow = !G.logShow; return; } // scoreboard tap = miss-log overlay
|
||||
if (x >= 6 && x <= 138 && y >= 6 && y <= 36) { // the scoreboard
|
||||
const now = performance.now();
|
||||
boardTaps = boardTaps.filter(t => now - t < 1600);
|
||||
boardTaps.push(now);
|
||||
if (boardTaps.length >= 3) {
|
||||
boardTaps = [];
|
||||
// taps one and two already toggled the miss-log twice, so it is back where it started —
|
||||
// this third one must NOT toggle it again, or every trip through test mode leaves the
|
||||
// overlay on behind you
|
||||
toggleTestMode();
|
||||
} else G.logShow = !G.logShow; // a single tap is still the miss-log overlay
|
||||
return;
|
||||
}
|
||||
const u = proj(UMP_X, 0, COURT.netZ);
|
||||
if (Math.abs(x - u.x) > 16 || y > u.y + 6 || y < u.y - UMP_H * u.s - 8) return;
|
||||
const now = performance.now();
|
||||
@@ -184,6 +197,6 @@ cv.addEventListener('pointerdown', e => {
|
||||
requestAnimationFrame(frame);
|
||||
|
||||
// exposed for in-browser sanity checks and simulated playtests
|
||||
window.T = { TUNE, ball, P, O, score, G, zombies, spawnZombie, spawnRacketZombie, spawnMachine, spawnChapterBoss, spawnBarrel, grantWeapon, piles, gore, parts, pellets, extras, shots, explode, hurtPlayer, killPlayer, splatPoint, solveShot, inServeBox, inCourt, proj, setupPoint, forceZombies, deliverTin, selectWeapon, showModal, dismissModal, startDuel, resolveInterlude, flickTarget, startBossFight, endBossFight,
|
||||
window.T = { TUNE, ball, P, O, score, G, zombies, spawnZombie, spawnRacketZombie, spawnMachine, spawnChapterBoss, spawnBarrel, grantWeapon, toggleTestMode, piles, gore, parts, pellets, extras, shots, explode, hurtPlayer, killPlayer, splatPoint, solveShot, inServeBox, inCourt, proj, setupPoint, forceZombies, deliverTin, selectWeapon, showModal, dismissModal, startDuel, resolveInterlude, flickTarget, startBossFight, endBossFight,
|
||||
step: dt => update(dt), render, press: keyPressed,
|
||||
get phase() { return G.phase; }, set phase(v) { G.phase = v; } };
|
||||
Reference in new issue
Block a user