The game as of artifact version 24, ready for local development with coding agents. - Source split from three large files into 52 small ones under src/sim, src/render and src/ui, joined in the order in src/manifest.json by build.py. The joined code is unchanged apart from comments; every headless suite gives the same output, and screenshots in both looks are pixel-identical to before. - Light tidying with no change in behaviour: one movement scan loop, shared hazard-stripe and belt shader helpers, unused code removed, a shared check helper for the test suites. - World files can be exported as an ordinary download outside claude.ai. - Tests: broken old scripts removed, experiments moved to tools/, test/run_all.py added. Tools: shot.py (repeatable screenshots), where.py, map.py. - Docs: AGENTS.md, CLAUDE.md, NOTES.md (the owner's to-do inbox), docs/PROJECT_MAP.md, DESIGN.md, TESTING.md, systems notes, the owner's requests and an agent log. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01K9kLmYADKSEjuwUN3rFxDA
49 lines
3.3 KiB
JavaScript
49 lines
3.3 KiB
JavaScript
// Furnace scenarios on a flat test world: builds a chamber, charges it with ore and coal, lights it
|
|
// and prints temperatures, burning cells and what has melted or set at intervals.
|
|
const { load, flatWorld, rect, count, maxTemp, ticks } = require('../../test/harness');
|
|
const { run } = load();
|
|
const C = n => run(n);
|
|
|
|
function report(t, region) {
|
|
const [x0, y0, x1, y1] = region;
|
|
const burning = run(`(()=>{let n=0;for(let y=${y0};y<=${y1};y++)for(let x=${x0};x<=${x1};x++)if(flags[y*W+x]&F_BURN)n++;return n})()`);
|
|
const oreT = run(`(()=>{let s=0,n=0;for(let y=${y0};y<=${y1};y++)for(let x=${x0};x<=${x1};x++)if(mat[y*W+x]===CUORE||mat[y*W+x]===FEORE){s+=temp[y*W+x];n++;}return n?Math.round(s/n):0})()`);
|
|
const airT = run(`(()=>{let s=0,n=0;for(let y=${y0};y<=${y1};y++)for(let x=${x0};x<=${x1};x++)if(mat[y*W+x]===EMPTY){s+=temp[y*W+x];n++;}return n?Math.round(s/n):0})()`);
|
|
console.log(`t=${String(t).padStart(5)} maxT=${String(maxTemp(run, x0, y0, x1, y1)).padStart(5)} oreT=${String(oreT).padStart(5)} airT=${String(airT).padStart(4)} burn=${String(burning).padStart(3)} coal=${count(run, C('COAL'), x0, y0, x1, y1)} cuOre=${count(run, C('CUORE'), x0, y0, x1, y1)} feOre=${count(run, C('FEORE'), x0, y0, x1, y1)} mCu=${count(run, C('MCU'), x0, y0, x1, y1)} Cu=${count(run, C('COPPER'), x0, y0, x1, y1)} mFe=${count(run, C('MFE'), x0, y0, x1, y1)} Fe=${count(run, C('IRON'), x0, y0, x1, y1)} slag=${count(run, C('SLAG'), x0, y0, x1, y1)} ash=${count(run, C('ASH'), x0, y0, x1, y1)} magma=${count(run, C('MAGMA'), x0, y0, x1, y1)} brick=${count(run, C('BRICK'), x0, y0, x1, y1)} smoke=${count(run, C('SMOKE'), x0, 0, x1, y1)}`);
|
|
}
|
|
function scenario(name, build, total, every, region) {
|
|
flatWorld(run, 200, 140, 90);
|
|
build();
|
|
console.log(`\n=== ${name} ===`);
|
|
for (let t = 0; t <= total; t += every) { if (t) ticks(run, every); report(t, region); }
|
|
}
|
|
function ignite(x, y, n = 40) { run(`for (let k=0;k<${n};k++){ toolIgnite(${x},${y}); simTick(); }`); }
|
|
// mixed charge: coal with ore grains sprinkled through it
|
|
function charge(x0, y0, x1, y1, ore, frac) {
|
|
run(`{ let r=mulberry32(5); for (let y=${y0};y<=${y1};y++) for (let x=${x0};x<=${x1};x++) setCell(y*W+x, r()<${frac} ? ${ore} : COAL, AMB[y], 0); }`);
|
|
}
|
|
function furnace(x0, y0, x1, y1, wall, thick, vent) {
|
|
rect(run, x0, y0, x0 + thick - 1, y1, wall); rect(run, x1 - thick + 1, y0, x1, y1, wall);
|
|
rect(run, x0, y0, x1, y0 + thick - 1, wall);
|
|
const cx = (x0 + x1) >> 1;
|
|
run(`for (let y=${y0};y<${y0 + thick};y++) for (let x=${cx - (vent >> 1)};x<${cx - (vent >> 1) + vent};x++) setCell(y*W+x, EMPTY, AMB[y], 0)`);
|
|
}
|
|
const which = process.argv[2] || 'all';
|
|
|
|
if (which === 'all' || which === 'open') scenario('Open mixed pile (coal + 30% copper ore)', () => {
|
|
charge(80, 80, 103, 89, C('CUORE'), 0.3);
|
|
ignite(85, 79); ignite(98, 79);
|
|
}, 3600, 600, [70, 60, 113, 89]);
|
|
|
|
if (which === 'all' || which === 'stone') scenario('Stone furnace, mixed charge, 2-wide vent', () => {
|
|
furnace(77, 66, 106, 89, C('STONE'), 2, 2);
|
|
charge(79, 76, 104, 89, C('CUORE'), 0.3);
|
|
ignite(84, 75); ignite(99, 75);
|
|
}, 4800, 600, [77, 64, 106, 89]);
|
|
|
|
if (which === 'all' || which === 'clay') scenario('Clay furnace, mixed charge (walls fire to brick)', () => {
|
|
furnace(77, 66, 106, 89, C('CLAY'), 2, 2);
|
|
charge(79, 76, 104, 89, C('CUORE'), 0.3);
|
|
ignite(84, 75); ignite(99, 75);
|
|
}, 4800, 600, [77, 64, 106, 89]);
|