Back to Powder Tool V600Billion
SOURCE / PINNED RELEASE

Made of little things.

Powder Tool V600Billion

Release
142767edcab8…
Author-recorded commit
6d92971effd0…
License
LICENSE
Author’s source reference
nostr://npub1fllw8kw0thjj55wds0uugcnp5kej2nfxd36eruq39d56wwz8r44q5q78wj/wss%3A%2F%2Fgit.napplet.soy%2F/powder-toy

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

source/scripts/make-fixtures.mjs
/**
 * Let the real game write the saves the thumbnail tests read.
 *
 *   PLAYWRIGHT_CHROMIUM_EXECUTABLE=... node scripts/make-fixtures.mjs
 *
 * Through the harness it builds two scenes in the Lua console and stores
 * them as stamps (a stamp is an OPS1 save of a region, the same format the
 * online browser shows), then copies the files out of host storage into
 * test/fixtures/:
 *   stamp-small.cps  100 x 48: a METL line, a WATR column, one red-decorated
 *                    DUST particle, one WALL cell
 *   stamp-full.cps   612 x 384: a floor of SAND and two rows of WALL
 */
import { mkdirSync, writeFileSync } from 'node:fs';
import { fileURLToPath } from 'node:url';

import { QA_DIR, startHarness } from './harness.mjs';

const fixtures = fileURLToPath(new URL('../test/fixtures/', import.meta.url));

async function lua(harness, line) {
  await harness.tab.keyboard.press('Backquote');
  await harness.tab.waitForTimeout(200);
  await harness.tab.keyboard.type(line, { delay: 1 });
  await harness.tab.keyboard.press('Enter');
  await harness.tab.waitForTimeout(300);
  await harness.tab.keyboard.press('Backquote');
  await harness.tab.waitForTimeout(200);
}

async function stored(harness, path) {
  await harness.tab.waitForFunction((key) => window.__host.storage.has(key), `fs:${path}`, { timeout: 10000 });
  const value = JSON.parse(await harness.host((key) => window.__host.storage.get(key), `fs:${path}`));
  return Buffer.from(value.data, 'base64');
}

const harness = await startHarness({ identity: null });
try {
  await harness.waitForGame();
  await harness.frame().click('#canvas', { position: { x: 5, y: 5 } });
  await lua(harness, 'sim.clearSim() sim.paused(true)');
  await lua(harness, 'for x=10,29 do sim.partCreate(-1,x,10,elem.DEFAULT_PT_METL) end');
  await lua(harness, 'for y=20,39 do sim.partCreate(-1,5,y,elem.DEFAULT_PT_WATR) end');
  await lua(harness, 'i=sim.partCreate(-1,50,20,elem.DEFAULT_PT_DUST) sim.partProperty(i,"dcolour",0xFFFF0000)');
  await lua(harness, 'sim.wallMap(20,5,8)');
  await lua(harness, 'n=sim.saveStamp(0,0,99,47) f=io.open("/powder/fixture-small.txt","w") f:write(n) f:close()');
  const small = (await stored(harness, '/powder/fixture-small.txt')).toString();
  writeFileSync(`${fixtures}stamp-small.cps`, await stored(harness, `/powder/stamps/${small}.stm`));

  await lua(harness, 'sim.clearSim() for x=0,611 do for y=250,383 do sim.partCreate(-1,x,y,elem.DEFAULT_PT_SAND) end end');
  await lua(harness, 'sim.wallMap(0,0,153,2,8)');
  await lua(harness, 'm=sim.saveStamp() g=io.open("/powder/fixture-full.txt","w") g:write(m) g:close()');
  const full = (await stored(harness, '/powder/fixture-full.txt')).toString();
  writeFileSync(`${fixtures}stamp-full.cps`, await stored(harness, `/powder/stamps/${full}.stm`));
  mkdirSync(QA_DIR, { recursive: true });
  await harness.tab.screenshot({ path: `${QA_DIR}fixtures.png` });
  console.log(`wrote stamps ${small} and ${full}`);
} finally {
  await harness.close();
}