// Shared Node/browser reproduction: vacuum the foot of settled 60-grain heaps, one stroke per tick. function pileCutWorld() { alloc(768, 600); worldSeed = 7; RS = 123; for (let x = 0; x < W; x++) { surfY[x] = 224; dirtY[x] = 234; graniteY[x] = basaltY[x] = magmaY[x] = H; } computeAmbient(); fillNoise(); for (let y = 0; y < H; y++) for (let x = 0; x < W; x++) { const i = y * W + x; mat[i] = y >= 224 ? STONE : EMPTY; flags[i] = y >= 224 ? F_NAT : 0; temp[i] = AMB[y]; } bag.fill(0); bagTotal = 0; player.tankTier = 3; resetWeather(); weather.next = 1e15; updateRoof(); } function pileCutSetup(peak, mixed) { const rubble = [RSTONE, CUORE, FEORE, LDIRT]; for (let y = 164; y < 224; y++) for (let x = peak - (y - 164); x <= peak + (y - 164); x++) setCell(y * W + x, mixed ? rubble[(x + y) % rubble.length] : RSTONE, AMB[y], 0); } function pileCutStroke(peak) { bot.x = peak - 50; bot.y = 170; bot.vx = bot.vy = 0; for (let y = 223; y >= 164; y--) for (let x = peak - 100; x < peak; x++) { if (PH[mat[y * W + x]] !== PH_POWDER) continue; return toolVacuum(Math.min(peak - 7, x), y - 3, 6, () => true).got; } return 0; } function pileCutProfile(peak) { let cliff = 0, previous = 0, grains = 0; for (let x = peak - 110; x <= peak + 110; x++) { let y = 0; while (y < 224 && PH[mat[y * W + x]] !== PH_POWDER) y++; const height = 224 - y; cliff = Math.max(cliff, Math.abs(height - previous)); previous = height; for (; y < 224; y++) if (PH[mat[y * W + x]] === PH_POWDER) grains++; } return {cliff, grains}; }