Files
deepgrain-foundry/test/t_lakes.js
T

52 lines
3.1 KiB
JavaScript

// Generated lakes wake without a tool, settle on their own, and have dry tree bases.
const { load, suite, ticks } = require('./harness');
const { createHash } = require('node:crypto');
const { run } = load();
const { check, done } = suite();
const water = run('WATER');
function surfacePools() {
return run(`(() => {
const pools = []; let pool = null;
for (let x = 0; x < W; x++) {
let y = 0; while (y < H && mat[y * W + x] === EMPTY) y++;
if (mat[y * W + x] !== WATER) { pool = null; continue; }
if (!pool) { pool = { x0: x, x1: x, width: 0, min: y, max: y }; pools.push(pool); }
pool.x1 = x; pool.width++; pool.min = Math.min(pool.min, y); pool.max = Math.max(pool.max, y);
}
return pools.filter(p => p.width > 20);
})()`);
}
for (const [seed, expected] of [
[7, '865ac320f743ff5ed573acab3333773b5ebc2e10f15600438dd15f1767acb72e'],
[42, '94930e108f7bd948c6f3dbe8b15b2950eed695cb3d57376d05a8ad781c2015b7'],
[424242, '8b8a4b44c2cc98d3ab86515eb55f38ce7cb3d6a283e29e0ed758af937ea8e8c8'],
]) {
run(`generateWorld(${seed}, 2048, 1024); weather.next = 1e15;`);
const hash = createHash('sha256');
for (const name of ['mat', 'temp']) hash.update(Buffer.from(run(name).buffer));
check(`seed ${seed} preserves generated material and temperature bytes`, hash.digest('hex') === expected);
check(`seed ${seed} restores pinned generation switches`, run('LSTEP === 8 && LFILM === 4 && SORTP === 0.06 && CORNER_SEAL && POWDER_FAN'));
check(`seed ${seed} starts every water area awake`, run(`mat.every((m, i) => m !== WATER || awake[((i / W) >> 5) * CW + ((i % W) >> 5)] > 0)`));
check(`seed ${seed} has no submerged tree base`, run('treeBases.every(i => !treeHeld(i) || mat[i] !== WATER)'));
check(`seed ${seed} retains dry trees`, run('treeBases.filter(i => treeHeld(i)).length > 20'));
// Seed 7 reproduces the owner's long slope. No drill, forced wakes, or terrain edits.
if (seed === 7) {
run('globalThis.lakeSave = serializeWorld();');
for (const state of ['fresh', 'reloaded']) {
if (state === 'reloaded') run('deserializeWorld(lakeSave.meta, lakeSave.buffers); weather.next = 1e15;');
check(`${state} world starts with dry tree bases`, run('treeBases.every(i => !treeHeld(i) || mat[i] !== WATER)'));
const before = run('mat.slice(270 * W, 340 * W)');
const wakeTicks = state === 'fresh' ? 1 : 171;
ticks(run, wakeTicks);
check(`${state} lake moves within its startup wake window`, run('mat.subarray(270 * W, 340 * W)').some((m, i) => m !== before[i] && (m === water || before[i] === water)));
ticks(run, 6000 - wakeTicks);
const pools = surfacePools();
check(`${state} lake levels within two grains without disturbance`, pools.length > 0 && pools.every(p => p.max - p.min <= 2), JSON.stringify(pools));
// Reload can also thaw mountain snow into new puddles; check the original lake here.
const lake = pools.reduce((a, b) => a.width > b.width ? a : b);
check(`${state} original lake has no submerged tree base after settling`, run(`treeBases.every(i => i % W < ${lake.x0} || i % W > ${lake.x1} || !treeHeld(i) || mat[i] !== WATER)`));
}
}
}
done();