Served with isolation headers; start-screen capability notices; tests on the real GPU (t88 phase 1)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-27 19:11:42 -04:00
co-authored by Claude Opus 5.5
parent 9781aa3ee1
commit b2c9ad9533
22 changed files with 376 additions and 91 deletions
+1
View File
@@ -48,6 +48,7 @@
<div class="titlewrap">
<canvas id="titleart" width="320" height="80" aria-label="Deepgrain Foundry"></canvas>
<p class="tagline">Dig. Smelt. Cast your own tools. Every grain is simulated, and nothing turns into anything unless the physics says so.</p>
<div id="cap-notice" class="plate note" role="status" hidden></div>
<div class="tmenu" id="tmenu">
<button class="btn primary" id="btn-continue" hidden>Continue <small id="continue-meta"></small></button>
<button class="btn" id="btn-worlds" hidden>Worlds <small>load · rename · delete</small></button>
+2
View File
@@ -291,6 +291,8 @@ input.text { background: var(--soot-0); border: 1px solid var(--soot-4); border-
#titleart { width: min(820px, 100%); aspect-ratio: 4 / 1; display: block; margin: 0 auto; image-rendering: pixelated; max-width: 100%; }
.titlewrap { align-self: center; display: flex; flex-direction: column; align-items: center; gap: 18px; padding-block: 24px; }
.tagline { color: var(--ash); max-width: 52ch; text-align: center; margin: -6px 0 4px; text-wrap: balance; }
#cap-notice { max-width: 64ch; padding: 8px 14px; color: var(--melt-hot); }
#cap-notice p { margin: 6px 0; }
.tmenu { display: flex; flex-direction: column; gap: 8px; width: min(360px, 100%); }
.tmenu .btn { padding: 10px 14px; text-align: left; display: flex; justify-content: space-between; align-items: center; }
.tmenu .btn small { color: var(--ash); font-size: 0.82em; }
+2
View File
@@ -32,6 +32,7 @@ async function setupNewWorld(seed, w, h, name, carried, title = 'Generating worl
if (carried) applyCareerState(carried);
}
async function startNewWorld(seed, w, h, name = '') {
if (!await canStartGame()) return false;
try {
const worlds = await listWorlds();
await setupNewWorld(seed, w, h, cleanWorldName(name, claimName(seed, worlds.map(w => w.name))));
@@ -45,6 +46,7 @@ async function startNewWorld(seed, w, h, name = '') {
} catch (e) { showLoading(false); toast('Could not create a world. Browser storage is unavailable.'); }
}
async function startFromSave(sv, onProgress) {
if (!await canStartGame()) return false;
onProgress = onProgress || ((f, s) => showLoading(true, f, s, 'Loading world'));
auInit();
GAME.paused = true;
+29 -1
View File
@@ -1,4 +1,32 @@
// The title screen art.
// Startup capabilities and title art.
const REQUIRE_GPU_AND_THREADS = false;
const CAPS = { isolated: self.crossOriginIsolated === true, webgpu: false, adapterInfo: null, ready: false };
async function checkCapabilities() {
try {
const adapter = navigator.gpu && await navigator.gpu.requestAdapter();
CAPS.webgpu = !!adapter;
const info = adapter && adapter.info;
if (info) CAPS.adapterInfo = { vendor: info.vendor, architecture: info.architecture, device: info.device, description: info.description };
} catch (e) { CAPS.webgpu = false; }
CAPS.ready = true;
renderCapabilityNotice();
}
function renderCapabilityNotice() {
const messages = [];
if (!CAPS.isolated) messages.push("Deepgrain needs to be served (for example with python3 tools/serve.py) so it can use all CPU cores; opened from a file it can't.");
if (!CAPS.webgpu) messages.push(/Firefox\//.test(navigator.userAgent)
? 'WebGPU is unavailable. In Firefox, open about:config and set dom.webgpu.enabled to true, then restart. On Linux, use Firefox Nightly. If no graphics adapter is available, try Chrome or Edge.'
: 'WebGPU is unavailable. Use a browser with WebGPU (Chrome or Edge).');
const notice = $('cap-notice');
notice.replaceChildren(...messages.map(text => { const p = document.createElement('p'); p.textContent = text; return p; }));
notice.hidden = !messages.length;
}
async function canStartGame() {
await CAPS_CHECK;
return !REQUIRE_GPU_AND_THREADS || (CAPS.isolated && CAPS.webgpu);
}
const CAPS_CHECK = checkCapabilities();
// ---------- Title art ----------
const FONT5 = {
D: ['11110', '10001', '10001', '10001', '10001', '10001', '11110'], E: ['11111', '10000', '10000', '11110', '10000', '10000', '11111'],