SOURCE / PINNED RELEASE
Made of little things.
Supersonic RC Revive
- Release
- 1ba42f1ca1d6…
- Author-recorded commit
- baecad10b1cd…
- License
- LICENSE
- Author’s source reference
- nostr://npub1ye5ptcxfyyxl5vjvdjar2ua3f0hynkjzpx552mu5snj3qmx5pzjscpknpr/wss%3A%2F%2Fgit.napplet.soy%2F/n-143146b0d6f
Archive hash verified: 90d22b206672eba4…. The source-to-build association is the author’s claim; it has not been independently rebuilt.
#!/usr/bin/env node
// Record which Rapier WASM bindings the physics port calls, for
// tools/build/rapier-slim.ts. Runs headless test drives (tools/sim/drive.mjs)
// and, optionally, replays of original-game logs (tools/sim/replay.mjs)
// against the full, unstripped module.
// node tools/build/record-rapier-exports.mjs [original-log.txt ...]
// Needs ref-out/game (tools/extract). Re-run after upgrading Rapier or when
// src/game/physics starts using a new part of its API.
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
import { resolve, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
import { execFileSync } from 'node:child_process';
const root = resolve(dirname(fileURLToPath(import.meta.url)), '../..');
const out = resolve(root, 'tools/build/rapier-exports.json');
const tmp = resolve(root, 'node_modules/.cache/rapier-exports.txt');
mkdirSync(dirname(tmp), { recursive: true });
// Acceleration, steering, reversing, the handbrake, wall and ramp impacts.
const DRIVES = ['u:4,ul:2,u:2,-:2', 'u:8,ur:3,u:6', 'd:3,dl:2,s:1,-:1', 'u:2,ul:6,ur:6,us:2', 'u:12,-:3'];
// Preloaded into each run: wraps every WASM export and logs the ones called.
const hook = `import { writeFileSync } from 'node:fs';
const used = new Set();
const instantiate = WebAssembly.instantiate;
WebAssembly.instantiate = async (...args) => {
const result = await instantiate(...args);
const instance = result.instance ?? result;
const exports = {};
for (const [name, value] of Object.entries(instance.exports)) {
exports[name] = typeof value === 'function' ? (...a) => (used.add(name), value(...a)) : value;
}
const wrapped = Object.setPrototypeOf({ exports }, WebAssembly.Instance.prototype);
return result.instance ? { module: result.module, instance: wrapped } : wrapped;
};
process.on('exit', () => writeFileSync(${JSON.stringify(tmp)}, [...used].join('\\n')));`;
const used = new Set();
function record(script, args) {
execFileSync(process.execPath, ['--import', `data:text/javascript,${encodeURIComponent(hook)}`, resolve(root, script), ...args], {
env: { ...process.env, SSRC_RAPIER_FULL: '1', SIM_DT: '1000' },
stdio: ['ignore', 'ignore', 'inherit'],
});
for (const name of readFileSync(tmp, 'utf8').split('\n')) if (name) used.add(name);
}
// Local sessions also remove bodies and their attached collider/joint mappings.
record('tests/local-multiplayer.test.mjs', []);
for (const drive of DRIVES) record('tools/sim/drive.mjs', [drive]);
for (const log of process.argv.slice(2)) record('tools/sim/replay.mjs', [log, '/dev/null']);
const exports = [...used].filter((n) => n.startsWith('raw')).sort();
const rapier = JSON.parse(readFileSync(resolve(root, 'node_modules/@dimforge/rapier3d-compat/package.json'), 'utf8')).version;
writeFileSync(out, JSON.stringify({ note: 'Rapier bindings called by the port; see tools/build/rapier-slim.ts.', rapier, exports }, null, 1) + '\n');
console.log(`${exports.length} raw bindings -> ${out}`);
