The boot gate learns about the profile: skeleton plaque, locked splash, a 4s cap
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
04ef49ef3b
commit
7a9b61fc6b
3 files changed
+29
-4
No files matched your search
+10
@@ -491,6 +491,16 @@ zombie (now an occasional opponent, `TUNE.racketEvery`, not the every-game fixtu
|
|||||||
`RETURNED`, `DOUBLE KILL`) is a footnote to something you already watched happen. Sharing the loud
|
`RETURNED`, `DOUBLE KILL`) is a footnote to something you already watched happen. Sharing the loud
|
||||||
FACE with the milestone cards is right; sharing their SIZE made every footnote read as a milestone.
|
FACE with the milestone cards is right; sharing their SIZE made every footnote read as a milestone.
|
||||||
|
|
||||||
|
## Session log: the boot gate learns about the profile (2026-08-29, same day, STAGING ONLY)
|
||||||
|
|
||||||
|
Oliver: on a fresh load the player/build requests are still in flight while the splash is already
|
||||||
|
interactive. The existing `#splash.busy` gate (sprites + fonts) now ALSO waits for the profile
|
||||||
|
mirror's pull — capped at 4 s, because a dead network must never park the player on the title
|
||||||
|
(the sprite loader's own rule). While busy the PLAQUE is a skeleton: ghost crest, blank pills
|
||||||
|
where the words go, empty bar, no chevron, `pointer-events: none` — and the splash keyboard
|
||||||
|
shortcuts respect the gate too (they didn't). Half-true numbers neither show nor navigate; the
|
||||||
|
pull's `refreshSplash` repaints the real values the moment the gate lifts.
|
||||||
|
|
||||||
## Session log: THE CUP CLIMBS — the shuffle retires too (2026-08-29, same day, STAGING ONLY)
|
## Session log: THE CUP CLIMBS — the shuffle retires too (2026-08-29, same day, STAGING ONLY)
|
||||||
|
|
||||||
Oliver, straight after the draw screen went: "warum sollten wir noch mischen? wäre es nicht gut
|
Oliver, straight after the draw screen went: "warum sollten wir noch mischen? wäre es nicht gut
|
||||||
|
|||||||
+11
-1
@@ -483,6 +483,16 @@ if (location.hostname !== 'splatter-tennis.wuwi.one' && !window.Capacitor?.isNat
|
|||||||
font: 400 9px Silkscreen, monospace; color: var(--dim); letter-spacing: 2px; }
|
font: 400 9px Silkscreen, monospace; color: var(--dim); letter-spacing: 2px; }
|
||||||
#splash.busy #boot { display: block; }
|
#splash.busy #boot { display: block; }
|
||||||
#splash.busy .btn, #splash.busy .two, #splash.busy #build { display: none; }
|
#splash.busy .btn, #splash.busy .two, #splash.busy #build { display: none; }
|
||||||
|
/* ...and the PLAQUE boots as a SKELETON: no tap, ghost crest, blank pills where the words go.
|
||||||
|
The profile mirror may still be in flight, and half-true numbers must neither show nor
|
||||||
|
navigate (main.js holds .busy until the pull settles or its 4 s cap fires). */
|
||||||
|
#splash.busy #plaque { pointer-events: none; }
|
||||||
|
#splash.busy #plaque em { visibility: hidden; }
|
||||||
|
#splash.busy #plBadge { opacity: 0.14; filter: grayscale(1); }
|
||||||
|
#splash.busy #plName, #splash.busy #plLv, #splash.busy #plGoal {
|
||||||
|
color: transparent; text-shadow: none; background: rgba(255,255,255,0.08);
|
||||||
|
border-radius: 4px; }
|
||||||
|
#splash.busy #plRow s i { width: 0% !important; }
|
||||||
#sSum, #brSum { display: flex; justify-content: space-between; gap: 8px; margin: 0 0 8px;
|
#sSum, #brSum { display: flex; justify-content: space-between; gap: 8px; margin: 0 0 8px;
|
||||||
font: 400 9px Silkscreen, monospace; color: var(--dim); letter-spacing: 1px; }
|
font: 400 9px Silkscreen, monospace; color: var(--dim); letter-spacing: 1px; }
|
||||||
.tabs { display: flex; gap: 6px; margin: 12px 0 14px; }
|
.tabs { display: flex; gap: 6px; margin: 12px 0 14px; }
|
||||||
@@ -854,6 +864,6 @@ if (location.hostname !== 'splatter-tennis.wuwi.one' && !window.Capacitor?.isNat
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script type="module" src="src/main.js?v=331"></script>
|
<script type="module" src="src/main.js?v=332"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
+8
-3
@@ -906,8 +906,12 @@ document.getElementById('stModes').addEventListener('click', e => {
|
|||||||
});
|
});
|
||||||
refreshSplash();
|
refreshSplash();
|
||||||
// the profile mirror: adopt a server copy that is ahead (a wiped phone, a second device), then
|
// the profile mirror: adopt a server copy that is ahead (a wiped phone, a second device), then
|
||||||
// let the strip show whatever came back. Fire-and-forget — the menu never waits on the network.
|
// let the plaque show whatever came back. The BOOT GATE holds the splash locked (skeleton
|
||||||
profile.pull().then(refreshSplash);
|
// plaque, no buttons, no keys) until this settles — capped at 4 s, because a dead network must
|
||||||
|
// never park the player on the title (the sprite loader's own rule).
|
||||||
|
let profileDone = false;
|
||||||
|
profile.pull().then(() => { profileDone = true; refreshSplash(); });
|
||||||
|
setTimeout(() => { profileDone = true; }, 4000);
|
||||||
|
|
||||||
// THE BOOT GATE. render.js fires all ~230 sprite requests at import; this only watches them and
|
// THE BOOT GATE. render.js fires all ~230 sprite requests at import; this only watches them and
|
||||||
// keeps the splash's buttons out of reach until the last one has landed and both faces are ready.
|
// keeps the splash's buttons out of reach until the last one has landed and both faces are ready.
|
||||||
@@ -925,7 +929,7 @@ const loaded = () => !splash.classList.contains('busy');
|
|||||||
const tick = setInterval(function watchLoad() {
|
const tick = setInterval(function watchLoad() {
|
||||||
const frac = LOAD.total ? LOAD.done / LOAD.total : 1;
|
const frac = LOAD.total ? LOAD.done / LOAD.total : 1;
|
||||||
bootFill.style.width = (frac * 100).toFixed(1) + '%';
|
bootFill.style.width = (frac * 100).toFixed(1) + '%';
|
||||||
if (frac < 1) return;
|
if (frac < 1 || !profileDone) return; // sprites AND the profile mirror (or its 4 s cap)
|
||||||
clearInterval(tick);
|
clearInterval(tick);
|
||||||
// fonts.ready resolves once nothing is pending — including the three faces warmed above — so the
|
// fonts.ready resolves once nothing is pending — including the three faces warmed above — so the
|
||||||
// first canvas frame is never the system serif.
|
// first canvas frame is never the system serif.
|
||||||
@@ -950,6 +954,7 @@ addEventListener('keydown', e => {
|
|||||||
if (!menuUp()) return;
|
if (!menuUp()) return;
|
||||||
menuMusic(); // a key is a gesture too — unlock the theme on a desktop that never taps
|
menuMusic(); // a key is a gesture too — unlock the theme on a desktop that never taps
|
||||||
const stage = intro.dataset.stage;
|
const stage = intro.dataset.stage;
|
||||||
|
if (stage === 'splash' && !loaded()) return; // the boot gate holds the keys too
|
||||||
if (e.key === 'Escape') return go('splash');
|
if (e.key === 'Escape') return go('splash');
|
||||||
if (stage === 'splash') {
|
if (stage === 'splash') {
|
||||||
if (!loaded()) return; // the boot bar hides the buttons; a key must not walk past it
|
if (!loaded()) return; // the boot bar hides the buttons; a key must not walk past it
|
||||||
|
|||||||
Reference in new issue
Block a user