// Smelter design experiments, built with the same block pieces a player uses. // Layout (block rows, 4x4 grains each), on flat ground at row 25: // roof with a vent ........ row g-CH-1 // chamber, CH blocks tall .. charge of coal + copper ore inside // grate floor ............. row g = 23 (liquids pass, powders do not) // ingot mold .............. row 24, sitting on the ground // side walls run from the roof down past the mold. // Usage: node t_smelter.js [key=value ...] const { load, flatWorld, ticks } = require('../../test/harness'); const opt = Object.assign({ wall: 'RSTONE', ratio: 0.33, ch: 4, vent: 1, grate: 1, fill: 0.65, mix: 'mix', ign: 'top', mold: 'ingot', T: 7200, dump: 0, lid: 0, base: 'RSTONE', cw: 4 }, Object.fromEntries(process.argv.slice(2).map(a => a.split('=')).map(([k, v]) => [k, isNaN(+v) ? v : +v]))); const { run } = load(); flatWorld(run, 200, 160, 100); run('bot.x = 90; bot.y = 50;'); const bx = 23, g = 23, CH = opt.ch, top = g - CH - 1, CWB = opt.cw; const W_ = opt.wall; const B = (code, v, x, y) => run(`placeBlock(${code}, ${v}, ${x}, ${y}, true)`); // mold on the ground for (let k = 0; k < CWB / 4; k++) { const moldErr = run(`addMold('${opt.mold}', ${bx + k * 4}, 24, ${opt.base}, true)`); if (typeof moldErr === 'string') { console.log('mold error', moldErr); process.exit(1); } } // floor: grate (or plain walls with nothing) over the mold for (let x = bx; x < bx + CWB; x++) if (opt.grate) B('BP_GRATE', 0, x, g); // side walls from roof down to the mold row, roof with a vent in the middle if (W_ !== 'none') { for (let y = top; y <= 24; y++) { B('BP_WALL', W_, bx - 1, y); B('BP_WALL', W_, bx + CWB, y); } const mid = bx + (CWB >> 1); const ventX = opt.vent === 2 ? [mid - 1, mid] : opt.vent === 1 ? [mid] : []; for (let x = bx; x < bx + CWB; x++) if (!ventX.includes(x)) B('BP_WALL', W_, x, top); } // charge const x0 = bx * 4, x1 = (bx + CWB) * 4 - 1, yBot = g * 4 - 1, yTop = Math.round(yBot - CH * 4 * opt.fill) + 1; run(`{ const r = mulberry32(11); for (let y = ${yTop}; y <= ${yBot}; y++) for (let x = ${x0}; x <= ${x1}; x++) { const i = y*W+x; if (mat[i] !== EMPTY || part[i]) continue; let ore; if ('${opt.mix}' === 'layers') ore = ((${yBot} - y) >> 1) % 3 === 1; else if ('${opt.mix}' === 'coalbottom') ore = y < ${yTop} + (${yBot} - ${yTop}) * ${opt.ratio}; else ore = r() < ${opt.ratio}; setCell(i, ore ? CUORE : COAL, AMB[y], 0); } }`); const ore0 = run(`(()=>{let n=0;for(let i=0;i{let n=0;for(let i=0;i `toolIgnite(${x}, ${iy});`).join('')} simTick(); }`); const stat = () => run(`(() => { let mcu = 0, cu = 0, scr = 0, ore = 0, coal = 0, inCav = 0, peak = 0, slag = 0; const mo = molds[0], cav = new Set(molds.flatMap(m => m.cavs.flat())); for (let i = 0; i < N; i++) { const m = mat[i]; if (m === MCU) mcu++; else if (m === COPPER) cu++; else if (m === SCRCU) scr++; else if (m === CUORE) ore++; else if (m === COAL) coal++; else if (m === SLAG) slag++; if ((m === MCU || m === COPPER) && cav.has(i)) inCav++; } for (let y = ${top * 4}; y < ${g * 4}; y++) for (let x = ${x0}; x <= ${x1}; x++) peak = Math.max(peak, temp[y*W+x]); return { mcu, cu, scr, ore, coal, slag, inCav, cav: cav.size, peak: Math.round(peak), state: molds.map(m => m.state).join('+'), ready: molds.reduce((a, m) => a + m.ready.length, 0), fill: +mo.fill.toFixed(2) }; })()`); console.log(JSON.stringify(opt), `ore ${ore0} coal ${coal0}`); let el = 0; for (const dt of [900, 900, 1800, 1800, 1800, 1800, 1800, 1800].filter((_, k, a) => a.slice(0, k + 1).reduce((p, q) => p + q, 0) <= opt.T)) { ticks(run, dt); el += dt; const s = stat(); console.log(`${String(el / 60).padStart(4)}s peak ${String(s.peak).padStart(4)}°C ore ${String(s.ore).padStart(3)} coal ${String(s.coal).padStart(3)} molten ${String(s.mcu).padStart(3)} set ${String(s.cu).padStart(3)} in mold ${s.inCav}/${s.cav} mold ${s.state}${s.ready ? ' ' + s.ready + ' bars' : ''}`); } if (opt.dump) { const ch = { [run('EMPTY')]: '.', [run('COAL')]: 'c', [run('CUORE')]: 'o', [run('MCU')]: 'M', [run('COPPER')]: '=', [run('SLAG')]: 's', [run('ASH')]: 'a', [run('FIRE')]: '^', [run('SMOKE')]: '~', [run('STONE')]: '#', [run('BRICK')]: 'B', [run('CLAY')]: 'C' }; for (let y = top * 4 - 2; y < 104; y++) { let l = ''; for (let x = x0 - 6; x <= x1 + 6; x++) { const i = run(`${y}*W+${x}`); const m = run(`mat[${i}]`); l += run(`part[${i}]`) === 5 && m === 0 ? '+' : (ch[m] || '?'); } console.log(l); } }