diff --git a/web/js/boot.js b/web/js/boot.js index 27680ce..aeb8c32 100644 --- a/web/js/boot.js +++ b/web/js/boot.js @@ -133,6 +133,22 @@ bus.on('level:event', (ev) => { }); } }); +// CONTINUE on the medal card -> load the next segment. cards.js raises ui:continue with C's +// `next` id; consuming it here is what makes the campaign a campaign rather than three levels +// in a folder. A full page load is deliberate (ponytail: the alternative is rebuilding world + +// player + combat + UI in place and re-wiring every bus listener, to save ~1s on a transition +// that happens 4 times a run) — it also guarantees no leaked pools or stale event pumps. +// Flags ride along, so ?dbg=1 / ?seed= survive the hop. Unknown/absent `to` = campaign over: +// stay on the card rather than dumping the player into the stub tube. +bus.on('ui:continue', async (e) => { + if (!e?.to) return; + const mod = await import('./levels/index.js').catch(() => null); + if (!mod?.CAMPAIGN?.includes(e.to)) { console.info(`[boot] no level "${e.to}" yet — campaign ends here`); return; } + const q = new URLSearchParams(location.search); + q.set('lvl', e.to); + location.search = q.toString(); +}); + bus.on('player:death', () => { run.deaths++; run.respawnT = 2.0; }); // 2s of feed-drop, then back function updateRun(dt) { if (!run.done) run.t += dt;