// Seeded worlds, no storage round-trip (saves quantize heat and land flying grains). function perfScene(name, w, h) { GAME.running = false; // Match a fresh page: generation retains the power scheduler and weather random stream. nextPowerBuild = 0; WS = 0x1b873593 | 0; for (const key of Object.keys(stats)) stats[key] = 0; generateWorld(424242, w, h, null); for (let k = 0; k < 600; k++) simTick(); if (name !== 'settled') { const x0 = Math.max(8, (W / 4 - 100) & ~3), y0 = Math.max(16, Math.min(H - 176, (surfY[Math.max(8, W / 4 | 0)] - 100) & ~3)); for (let y = y0; y < y0 + 160; y++) for (let x = x0; x < x0 + 200; x++) { setCell(y * W + x, y >= y0 + 144 ? STONE : EMPTY, AMB[y], 0); bgm[y * W + x] = 0; } bot.x = x0 + 98; bot.y = y0 + 50; if (name === 'factory') { // Furnace and hopper from experiments/factory_cost.js, with a screw/filter line. const mx = x0 / 4 + 3, my = y0 / 4 + 16; const place = (code, v, x, y, extra) => { const error = placeBlock(code, v, x, y, true, extra); if (error) throw Error(`factory ${x},${y}: ${error}`); }; for (let by = my; by < my + 4; by++) for (let bx = mx; bx < mx + 4; bx++) { if ((bx > mx && bx < mx + 3 && by > my && by < my + 3) || (by === my && bx === mx + 2)) continue; place(BP_WALL, RSTONE, bx, by); } for (let y = (my + 1) * 4 + 3; y < (my + 3) * 4; y++) for (let x = (mx + 1) * 4; x < (mx + 3) * 4; x++) setCell(y * W + x, (x + y) & 3 ? COAL : CUORE, 700, 0); for (let x = mx + 8; x < mx + 25; x++) place(BP_BELT, 1, x, my + 5); for (let x = mx + 25; x < mx + 30; x++) place(BP_SCREW, 1, x, my + 4); for (let x = mx + 30; x < mx + 40; x++) place(BP_FILTER, 128, x, my + 5, { m: [SAND], inv: 0 }); // Two full silos keep both materials flowing for the entire real run. for (const [dx, material] of [[9, SAND], [33, CUORE]]) { const silo = addMachine('silo', mx + dx, my - 2, 0); silo.sm = material; silo.sn = SILO_CAP; silo.open = true; } // Start with a loaded line, rather than timing its initial travel delay. for (let x = (mx + 8) * 4; x < (mx + 40) * 4; x++) setCell(((my + 5) * 4 - 1) * W + x, x & 3 ? SAND : CUORE, AMB[(my + 5) * 4 - 1], 0); } else { for (let y = y0 + 100; y < y0 + 144; y++) for (let x = x0 + 12; x < x0 + 188; x++) setCell(y * W + x, y < y0 + 114 ? WATER : MAGMA, y < y0 + 114 ? 20 : 1450, 0); } for (let k = 0; k < 60; k++) simTick(); } enterGame(); GAME.paused = true; SET.fog = false; SET.autosave = 0; SET.cameraLead = false; SET.shake = false; SET.fpsCap = 0; SET.showPerf = false; document.querySelectorAll('.card, .toast').forEach(e => e.remove()); R.particles.length = 0; snapCamera(); acc = 0; return perfState(); } function perfState() { let a = 0, h = 0; for (let c = 0; c < NCH; c++) { if (awake[c]) a++; if (hot[c]) h++; } return { tick, awake: a, hot: h, chunks: NCH, moved: stats.moved, flyers: flyers.length, silos: machines.filter(m => m && m.type === 'silo').map(m => ({ material: m.sm, grains: m.sn, pouring: tick - m.pourT < 10 })), camera: [R.camX, R.camY], bot: [bot.x, bot.y] }; } function perfView(look, zoom) { SET.look = look; SET.zoom = zoom; SET.lighting = 'full'; resizeRender(); snapCamera(); for (let k = 0; k < 5; k++) { R.frame++; drawWorld(); } if (look === 'smooth' && (!R.smoothOn || (!R.gpuOn && !SM.ok))) throw Error('Smooth look unavailable: ' + SM.why); return { grains: R.bw * R.bh, buffer: [R.bw, R.bh], scale: R.gpuOn ? 1 : SM.scale }; }