Back to Shiftfield
SOURCE / PINNED RELEASE

Made of little things.

Shiftfield

Release
5a170c505f6b…
Author-recorded commit
a2e23e0171aa…
License
LICENSE
Author’s source reference
nostr://npub16nzc4ql748r2kv9202rgzrt0fmtk4n3tzsjl86yf6ty9agqe9u0qjcc7hc/wss%3A%2F%2Fgit.napplet.soy%2F/n-e4fb6341ccd

Archive hash verified: 66de7623efd91da1…. The source-to-build association is the author’s claim; it has not been independently rebuilt.

tests/perf-trace.probe.mjs
// Probe 2 (2026-10-28 re-audit): CDP tracing to quantify PAINT load —
// rAF dt cannot see paint-driven animations (they cost raster, not main thread).
// Scenarios: idle with fire/ice hazards (firePulse box-shadow/filter,
// iceShimmer filter), flood wave (juiceReveal brightness filter),
// each A/B'd within one page session against animation-off overrides.
import { createServer } from 'node:http';
import { readFile } from 'node:fs/promises';
import { join, extname } from 'node:path';
import { chromium } from 'playwright';


const dist = new URL('../dist', import.meta.url).pathname;
const MIME = { '.html': 'text/html', '.js': 'text/javascript', '.css': 'text/css', '.json': 'application/json' };
async function serveDist() {
  const server = createServer(async (req, res) => {
    const p = req.url === '/' ? '/index.html' : req.url.split('?')[0];
    try {
      const body = await readFile(join(dist, p.slice(1)));
      res.writeHead(200, { 'content-type': MIME[extname(p)] ?? 'application/octet-stream' });
      res.end(body);
    } catch { res.writeHead(404).end('not found'); }
  });
  await new Promise((ok) => server.listen(0, '127.0.0.1', ok));
  return { url: `http://127.0.0.1:${server.address().port}/`, close: () => server.close() };
}
const svc = await serveDist();
const browser = await chromium.launch();
const page = await browser.newPage({ viewport: { width: 900, height: 600 } });
await page.goto(svc.url, { waitUntil: 'load' });
await page.waitForFunction(() => window.minesweeperDx !== undefined);
const cdp = await page.context().newCDPSession(page);

async function trace(tag, ms, action) {
  const chunks = [];
  cdp.on('Tracing.dataCollected', (e) => chunks.push(...e.value));
  await cdp.send('Tracing.start', {
    includedCategories: ['devtools.timeline', 'disabled-by-default-devtools.timeline', 'cc'],
    transferMode: 'ReportEvents',
  });
  if (action) await action();
  await page.waitForTimeout(ms);
  const done = new Promise((ok) => cdp.once('Tracing.tracingComplete', ok));
  await cdp.send('Tracing.end');
  await done;
  cdp.removeAllListeners('Tracing.dataCollected');
  const counts = {};
  for (const e of chunks) if (e.ph === 'X' || e.ph === 'B') counts[e.name] = (counts[e.name] ?? 0) + 1;
  const pick = (n) => counts[n] ?? 0;
  // Paint event bounds tell us tile-size vs viewport paints
  let tilePaints = 0, bigPaints = 0;
  let paintDur = 0;
  for (const e of chunks) {
    if (e.name === 'Paint' && e.ph === 'X') {
      paintDur += e.dur ?? 0;
      const b = e.args?.data?.layer?.bounds;
      if (b && b.width * b.height > 400000) bigPaints++;
      else if (b) tilePaints++;
    }
  }
  return {
    tag,
    Paint: pick('Paint'), Layout: pick('Layout'), UpdateLayoutTree: pick('UpdateLayoutTree'),
    RasterTask: pick('RasterTask'), PrePaint: pick('PrePaint'), Commit: pick('Commit'),
    tilePaints, bigPaints, paintMs: +(paintDur / 1000).toFixed(1),
  };
}

async function startRun() {
  await page.click('#startRunBtn');
  await page.waitForFunction(() => window.minesweeperDx.phase === 'running');
}
async function toMenu() {
  await page.evaluate(() => { window.minesweeperDx.showScreen?.('menu'); });
}

// seed hazards helper
async function seedHazards() {
  await page.evaluate(() => {
    const g = window.minesweeperDx.board.game;
    let placed = 0;
    for (const t of g.world.tiles) {
      if (placed >= 16) break;
      const c = g.idx(t.coord[0], t.coord[1]);
      if (!t.hasMine && t.state === 'HIDDEN' && !g.fire.has(c) && !g.ice.has(c)) { g.fire.add(c); placed++; }
    }
    let ice = 0;
    for (const t of g.world.tiles) {
      if (ice >= 6) break;
      const c = g.idx(t.coord[0], t.coord[1]);
      if (!t.hasMine && t.state === 'HIDDEN' && !g.fire.has(c) && !g.ice.has(c)) { g.ice.set(c, 999); ice++; }
    }
    window.minesweeperDx.board.refresh();
  });
}

const out = [];

// ---- P3: idle hazard paint load, A/B within one session ----
await startRun();
await seedHazards();
out.push(await trace('idle: P3 full (16 fire + 6 ice anims)', 1500));
const tagP3 = await page.addStyleTag({ content: '/* p3off */ .cell-fire,.cell-ice{animation:none!important}' });
await page.evaluate(() => { for (const s of document.querySelectorAll('style')) if (s.textContent.includes('p3off')) s.dataset.p3off = '1'; });
out.push(await trace('idle: P3 anim-off', 1500));
// also: everything except the bg layer + hazard anims off -> isolate bgDrift cost
const tagBg = await page.addStyleTag({ content: '/* bgoff */ body::before{animation:none!important}' });
await page.evaluate(() => { for (const s of document.querySelectorAll('style')) if (s.textContent.includes('bgoff')) s.dataset.bgoff = '1'; });
out.push(await trace('idle: P3 off + bgDrift off', 1500));
await page.evaluate(() => { document.querySelector('[data-p3off]').disabled = true; document.querySelector('[data-bgoff]').disabled = true; });
out.push(await trace('idle: P3 full again (sanity)', 1500));

// clean-plate idle (no hazards at all, only bgDrift running)
await page.evaluate(() => { window.minesweeperDx.board.newRun(); });
out.push(await trace('idle: no hazards (bgDrift only)', 1500));

// ---- P4: flood wave paint load ----
async function flood() {
  await page.evaluate(() => {
    const g = window.minesweeperDx;
    const eng = g.board.game;
    let target = null;
    for (const t of eng.world.tiles) {
      if (t.state === 'HIDDEN' && !t.hasMine && eng.world.adjacentMineCount(t.coord[0], t.coord[1]) === 0) { target = t; break; }
    }
    document.querySelector(`.cell[data-cell="${target.coord[0]},${target.coord[1]}"]`).click();
  });
}
await page.evaluate(() => window.minesweeperDx.board.newRun());
out.push(await trace('flood: full (brightness filter wave)', 1100, flood));
await page.evaluate(() => window.minesweeperDx.board.newRun());
const tagP4 = await page.addStyleTag({ content: `/* p4off */ @keyframes juiceReveal { 0% { opacity:.1; transform: scale(.82); } 100% { opacity:1; transform: scale(1); } }` });
await page.evaluate(() => { for (const s of document.querySelectorAll('style')) if (s.textContent.includes('p4off')) s.dataset.p4off = '1'; });
out.push(await trace('flood: no-filter wave (opacity+transform only)', 1100, flood));
await page.evaluate(() => { document.querySelector('[data-p4off]').disabled = true; });
await page.evaluate(() => window.minesweeperDx.board.newRun());
out.push(await trace('flood: full again (sanity)', 1100, flood));

console.log(JSON.stringify(out, null, 1));
await browser.close();
svc.close();