Load the game once, not on every launch
The cold-start complaints — late fonts, zombies missing from the stats screen — were one header. server.py sent no-cache, must-revalidate for everything, so a fresh launch revalidated ~230 sprites and three fonts before the game had a full set of frames. Assets under /assets now cache for a year when the URL carries ?v= (changing the file changes the URL, which is what SPRV is for) and a day when it does not; the fonts get a ?v= too. HTML and JS stay no-cache, so a deploy is still visible. Two client-side halves of the same report: a dropped sprite request used to be permanent for the session — the sheet stayed undefined and the zombie drew as some other design — so each one gets one retry. And the splash now holds its buttons back behind a loading bar until the last sheet has landed and both faces are ready, instead of letting you open the stats screen while half of it is still in flight. The bar is driven by setInterval, not rAF: rAF does not fire in a hidden tab, and an app that loads while backgrounded would come back to a frozen bar and a menu with no buttons on it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
a1a8a61422
commit
c5a9746bc1
4 files changed
+80
-13
No files matched your search
@@ -202,6 +202,10 @@ function drawRunOff() {
|
||||
// menu screens hang <img> tags on the same files, and two copies of this number is one copy too
|
||||
// many: the one that does not get bumped is the one that serves a cached 404.
|
||||
export const SPRV = 86;
|
||||
// The boot bar in main.js watches this. Nothing here CHANGES when things load — every sprite was
|
||||
// already requested at import — it just makes the wait visible and holds the menu back until the
|
||||
// last sheet has landed. See the onerror note below for the other half of "sometimes missing".
|
||||
export const LOAD = { done: 0, total: 0 };
|
||||
const SPR = {};
|
||||
for (const n of ['p_idle1','p_idle2','p_bounce','p_bounce2','p_toss','p_smash','p_run1','p_run2','p_run3','p_run4','p_swing1','p_swing2','p_die1','p_die2','p_die3','p_die4','p_die5',
|
||||
'p_pull', // the serve wind-up: the racket dropping behind him while the pull is drawn
|
||||
@@ -254,13 +258,22 @@ for (const n of ['p_idle1','p_idle2','p_bounce','p_bounce2','p_toss','p_smash','
|
||||
'z_c1_f','z_c2_f','z_c3_f','z_c4_f','z_cw1_f','z_cw2_f','z_cw1b_f','z_cw2b_f',
|
||||
'scoreboard']) {
|
||||
const img = new Image();
|
||||
img.onload = () => SPR[n] = img;
|
||||
// ?v=SPRV, for the same reason index.html versions main.js. python http.server sends no cache
|
||||
// headers, so the browser caches sprite responses heuristically — INCLUDING 404s. A brand-new sheet
|
||||
// whose name was added to this list before the PNG existed stays permanently "missing" for that
|
||||
// browser, and drawZombie silently falls back to another design. That cost a debugging round.
|
||||
// ?v=SPRV, for the same reason index.html versions main.js. It is also what buys the year-long
|
||||
// immutable cache in server.py: a versioned URL can never go stale, because changing the file
|
||||
// changes the URL. A brand-new sheet whose name was added to this list before the PNG existed
|
||||
// stays permanently "missing" for that browser, and drawZombie silently falls back to another
|
||||
// design. That cost a debugging round.
|
||||
// BUMP THIS whenever assets/ changes, alongside main.js?v=N in index.html.
|
||||
img.src = 'assets/' + n + '.png?v=' + SPRV;
|
||||
const url = 'assets/' + n + '.png?v=' + SPRV;
|
||||
// ONE RETRY. A dropped request used to be permanent for the whole session — the sprite stayed
|
||||
// undefined, the zombie drew as some other design, and the stats screen showed a broken <img>.
|
||||
// That is the "sometimes the graphics don't load" report. onerror still has to count on the
|
||||
// second failure, or one genuinely missing file hangs the boot bar forever.
|
||||
let retried = false;
|
||||
LOAD.total++;
|
||||
img.onload = () => { SPR[n] = img; LOAD.done++; };
|
||||
img.onerror = () => { if (retried) LOAD.done++; else { retried = true; img.src = url + '&r=1'; } };
|
||||
img.src = url;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------ crowd ----
|
||||
|
||||
Reference in new issue
Block a user