// What does a running factory cost when the player is somewhere else? // Builds K self-running modules in a generated world, far from the bot, and // measures simulation time per tick. Each module: a coal + copper-ore furnace // burning in a stone-block box, a spring feeding a water wheel, a shaft carrying // its power to a 10-block belt that hauls sand off a hopper. const { load } = require('../../test/harness'); const { run } = load(); const seed = 424242, w = +(process.argv[2] || 1024), h = +(process.argv[3] || 640); run(`generateWorld(${seed}, ${w}, ${h}, null); player.tankTier = 3;`); const awake = () => run('(()=>{let a=0,h=0;for(let c=0;c { const mx = ${mx}, my = ${my}; // clear the sky box we build in for (let y = my*4 - 4; y < (my+9)*4; y++) for (let x = mx*4 - 4; x < (mx+20)*4; x++) { const i = y*W+x; if (PH[mat[i]] !== PH_SOLID) setCell(i, EMPTY, AMB[y], 0); } // furnace: 4x4 blocks of stone with a 2x2 hollow and a vent on top for (let by = my; by < my+4; by++) for (let bx = mx; bx < mx+4; bx++) { const inner = bx > mx && bx < mx+3 && by > my && by < my+3; if (inner || (by === my && bx === mx+2)) continue; placeBlock(BP_WALL, RSTONE, bx, by, true); } const ix = (mx+1)*4, iy = (my+1)*4; for (let y = iy+3; y < iy+8; y++) for (let x = ix; x < ix+8; x++) setCell(y*W+x, ((x+y)&3) ? COAL : CUORE, AMB[y], 0); for (let x = ix; x < ix+8; x++) { temp[(iy+3)*W+x] = 700; wakeHeatXY(x, iy+3); } // spring above a water wheel for (let y = my*4; y < my*4+2; y++) for (let x = (mx+6)*4; x < (mx+7)*4; x++) { mat[y*W+x] = SPRING; flags[y*W+x] = F_NAT; } addMachine('wheel', mx+5, my+1, 0); // shaft from the wheel's side down to a belt line placeBlock(BP_SHAFT, 0, mx+8, my+2, true); placeBlock(BP_SHAFT, 0, mx+9, my+2, true); placeBlock(BP_SHAFT, 0, mx+9, my+3, true); placeBlock(BP_SHAFT, 0, mx+9, my+4, true); for (let bx = mx+9; bx < mx+20; bx++) placeBlock(BP_BELT, 1, bx, my+5, true); // sand hopper on the first belt blocks for (let y = (my+5)*4 - 12; y < (my+5)*4; y++) for (let x = (mx+10)*4; x < (mx+13)*4; x++) setCell(y*W+x, SAND, AMB[y], 0); })()`); run('powerDirty = true;'); } const report = []; const botBx = run('Math.floor(bot.x / 4)'); const slots = []; for (let mx = 6; mx + 22 < w / 4 && slots.length < 8; mx += 28) if (Math.abs(mx + 10 - botBx) > 24) slots.push(mx); for (const K of [1, 4, 8]) { if (K > slots.length) break; // fresh world for each count, so every module starts fully fuelled run(`generateWorld(${seed}, ${w}, ${h}, null); for (let k=0;k<600;k++) simTick();`); const modules = slots.slice(0, K); for (const mx of modules) buildModule(mx, 8); run('for (let k=0;k<300;k++) simTick();'); const moved0 = run('stats.moved'); const ms = measure(900); const [a, ht] = awake(); const wheels = run('machines.filter(m => m && m.type === "wheel").map(m => m.out.toFixed(1)).join(" ")'); const sat = run('nets.slice(1).map(n => n.sat.toFixed(2)).join(" ")'); const furn = run(`[${modules.map(mx => `(() => { let t = 0; for (let y = 36; y < 44; y++) for (let x = ${(mx + 1) * 4}; x < ${(mx + 3) * 4}; x++) t = Math.max(t, temp[y*W+x]); return Math.round(t); })()`).join(',')}].join(' ')`); const moved = run('stats.moved') - moved0; const dist = Math.min(...modules.map(mx => Math.abs(mx * 4 + 40 - run('bot.x')))); console.log(`\n${K} module${K > 1 ? 's' : ''}: ${ms.toFixed(2)} ms/tick (+${(ms - idle).toFixed(2)} over idle), ${a} moving areas, ${ht} warm areas`); console.log(` nearest module ${Math.round(dist)} grains from the bot; wheel output ${wheels}; belt power satisfaction ${sat}`); console.log(` furnace peak temps ${furn} °C; grains moved by machines in 15 s: ${moved}`); report.push({ K, ms, extra: ms - idle, a, ht }); } const per = report.map(r => (r.extra / r.K).toFixed(2)); console.log(`\nextra cost per module: ${per.join(' / ')} ms/tick`); const budget = 9; // ms per tick left for simulation at 60 ticks/s after rendering console.log(`at ~${budget} ms/tick of simulation budget, roughly ${Math.floor((budget - idle) / Math.max(0.01, report[report.length - 1].extra / report[report.length - 1].K))} such modules run at full speed`);