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.
/**
* Generate src/save/elements.js: element and wall colours for the thumbnail
* renderer, read from upstream's source at the pinned tag.
*
* git clone --depth 1 --branch v100.1.400 https://github.com/The-Powder-Toy/The-Powder-Toy /tmp/tpt
* node scripts/gen-elements.mjs /tmp/tpt
*
* Element ids are the positions in src/simulation/elements/meson.build
* (upstream generates ElementNumbers.h from that list); each element's
* colour is the `Colour = 0x..._rgb` line in its .cpp. Wall ids are the
* positions in LoadWalls() in src/simulation/SimulationData.cpp.
*/
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
import { join } from 'node:path';
import { fileURLToPath } from 'node:url';
import { upstream } from './upstream.mjs';
const source = process.argv[2] ?? process.env.UPSTREAM_SRC;
if (!source || !existsSync(join(source, 'src/simulation/elements/meson.build'))) {
console.error('usage: node scripts/gen-elements.mjs <upstream checkout at the pinned tag>');
process.exit(1);
}
const list = readFileSync(join(source, 'src/simulation/elements/meson.build'), 'utf8');
const block = /simulation_elem_names\s*=\s*\[([\s\S]*?)\]/.exec(list);
if (!block) throw new Error('simulation_elem_names not found');
const names = [...block[1].matchAll(/'([A-Z0-9_]+)'/g)].map((match) => match[1]);
const elements = names.map((name, id) => {
const file = join(source, 'src/simulation/elements', `${name}.cpp`);
if (!existsSync(file)) return [id, name, null];
const colour = /\bColour\s*=\s*0x([0-9A-Fa-f]{6})_rgb/.exec(readFileSync(file, 'utf8'));
return [id, name, colour ? parseInt(colour[1], 16) : null];
});
const data = readFileSync(join(source, 'src/simulation/SimulationData.cpp'), 'utf8');
const wallsBlock = /LoadWalls\(\)\s*\{[\s\S]*?std::vector<wall_type>\s*\{([\s\S]*?)\n\t\};/.exec(data);
if (!wallsBlock) throw new Error('LoadWalls() not found');
const walls = [...wallsBlock[1].matchAll(/\{0x([0-9A-Fa-f]{6})_rgb,[^}]*?"DEFAULT_WL_([A-Z]+)"/g)]
.map((match, id) => [id, match[2], parseInt(match[1], 16)]);
const output = fileURLToPath(new URL('../src/save/elements.js', import.meta.url));
writeFileSync(output, `// Generated by scripts/gen-elements.mjs from The Powder Toy ${upstream.tag} (${upstream.commit}). GPL-3.0.\n`
+ `// [id, name, 0xRRGGBB]\nexport default ${JSON.stringify({ version: upstream.version, elements, walls })};\n`);
console.log(`${elements.length} elements (${elements.filter((row) => row[2] === null).length} without a colour), ${walls.length} walls -> ${output}`);
