// === BUILD PLAN ===
// Style: Dutch stage smock mill (stellingmolen) converted into a miller's home, canal-side
// Footprint: regular OCTAGON (never a rectangle) - whitewashed brick base r=9 (2 thick),
// tarred timber smock tower tapering r8 -> r5.5, ringed by a wooden STAGE GALLERY at Y8
// (r=11) carried on 8 diagonal brackets. Canal + stone quay to the east.
// Height: base Y0-7 | smock Y8-18 | bulged thatch cap Y19-30 | sail tips to ~Y41
//
// GROUND FLOOR (top-down, 1 char = 1 block, Z down, X right):
// #####
// ##.....## # brick wall (2 thick) . floor
// #....H....# H hearth (north wall) K kitchen counter (east)
// #..^......K# ^ staircase, runs NORTH at x=-5, walkY1 -> walkY9
// #..^..r.T.K# r rug T dining table
// #..^..r....# S sofa (faces north) D front door (south)
// #.SSS.....# W windows
// ##..D..##
// #####
//
// FRONT (south) ELEVATION:
// /^\ thatch cap + finial
// /=====\
// \ | o o | / tower windows with stair hoods (dormer hoods)
// \ | | / lattice sails (4 blades, X pattern)
// ==[ STAGE GALLERY ]== Y8 planks + fence rail on brackets
// |#W###W#|
// |###D###| whitewashed brick base
// ~~~~~~~~~~~~~~~~~~~~~~~ canal / quay east
//
// MATERIALS PLAN (what goes where, and WHY):
// base : gradientPalette Y0->Y7 mossy_cobblestone -> cobblestone -> diorite -> calcite -> smooth_quartz
// WHY: whitewash that is DAMP and dark at the canal-side footing and bright at the top = fake AO
// smock : gradientPalette Y8->Y18 dark_oak_planks -> stripped_dark_oak_wood -> spruce_planks
// WHY: tarred timber, darkest in the stage shadow, lifting toward the cap = volume on a big drum
// posts : dark_oak_log at the 8 octagon corners, PROTRUDING 1 block = real wall depth, not a flat drum
// cap : noisePalette hay_block / stripped_oak_wood / stripped_birch_wood WHY: straw thatch variation
// sails : spruce_fence lattice frame + white_wool canvas furled on the inner half
// Rooms: GROUND hearth + kitchen counter + dining + sofa + rug + barrels + lanterns
// UPPER (grinding floor) millstone + sack stacks + bed nook + lectern + chests + lanterns
// STAIR PLAN: delta = walkY2(9) - walkY(1) = 8 -> ONE straight flight NORTH along the west side
// staircase(-5, 5, 1, 9, "north") -> lands flush on the Y8 grinding floor, floor hole carved
// === END PLAN ===
var cx = 0, cz = 0;
var padY = 0;
var floorY = 0, walkY = 1;
var midY = 8; // stage gallery + grinding floor level
var walkY2 = midY + 1; // 9
var towerTopY = 18;
var capBaseY = 19;
var capH = 11;
function octIn(dx, dz, r) {
var a = Math.abs(dx), b = Math.abs(dz);
return (a <= r && b <= r && (a + b) <= r * 1.35);
}
function octShell(y, rOut, thick, mat) {
var R = Math.ceil(rOut);
for (var dx = -R; dx <= R; dx++) {
for (var dz = -R; dz <= R; dz++) {
if (octIn(dx, dz, rOut) && !octIn(dx, dz, rOut - thick)) {
var m = (typeof mat === "function") ? mat(cx + dx, y, cz + dz) : mat;
pb(cx + dx, y, cz + dz, m);
}
}
}
}
function octDisc(y, rOut, mat) {
var R = Math.ceil(rOut);
for (var dx = -R; dx <= R; dx++) {
for (var dz = -R; dz <= R; dz++) {
if (octIn(dx, dz, rOut)) {
var m = (typeof mat === "function") ? mat(cx + dx, y, cz + dz) : mat;
pb(cx + dx, y, cz + dz, m);
}
}
}
}
// === TERRAIN ===
var h = terrain({
cx: 0, cz: 0, radius: 38, baseY: -1, amp: 3, scale: 0.045, seed: 17,
irregularity: 0.35,
surface: [{ block: "grass_block", w: 62 }, { block: "coarse_dirt", w: 18 }, { block: "podzol", w: 12 }, { block: "moss_block", w: 8 }],
sub: "dirt", deep: "stone", depth: 4,
pads: [{ cx: 0, cz: 0, r: 15, y: padY, falloff: 9 }]
});
// canal channel east + stone quay walls
var quayMat = noisePalette([{ block: "stone_bricks", weight: 45 }, { block: "mossy_stone_bricks", weight: 30 }, { block: "cracked_stone_bricks", weight: 15 }, { block: "cobblestone", weight: 10 }], { seed: 4, freq: 0.16 });
fill(22, -5, -38, 33, 6, 38, "air");
fill(22, -5, -38, 33, -2, 38, "water");
for (var qz = -38; qz <= 38; qz++) {
for (var qy = -5; qy <= 0; qy++) {
pb(21, qy, qz, quayMat(21, qy, qz));
pb(34, qy, qz, quayMat(34, qy, qz));
}
pb(21, 1, qz, "stone_brick_slab");
pb(34, 1, qz, "stone_brick_slab");
}
// === BASE (whitewashed brick octagon) ===
var baseMat = gradientPalette(0, 7, [
{ block: "mossy_cobblestone", from: 0 },
{ block: "cobblestone", from: 0.20 },
{ block: "andesite", from: 0.36 },
{ block: "diorite", from: 0.52 },
{ block: "calcite", from: 0.70 },
{ block: "smooth_quartz", from: 0.86 }
], { noise: 0.22, seed: 9 });
octDisc(floorY, 9, baseMat);
var by;
for (by = floorY + 1; by <= 7; by++) octShell(by, 9, 2, baseMat);
// ground floor deck
var deckMat = noisePalette([{ block: "spruce_planks", weight: 55 }, { block: "dark_oak_planks", weight: 25 }, { block: "stripped_spruce_wood", weight: 20 }], { seed: 3, freq: 0.2 });
octDisc(floorY, 7.6, deckMat);
// base corner pilasters (octagon corners, protrude 1)
var corners = [[0, 1], [1, 1], [1, 0], [1, -1], [0, -1], [-1, -1], [-1, 0], [-1, 1]];
var ci, cxo, czo;
for (ci = 0; ci < 8; ci++) {
var ux = corners[ci][0], uz = corners[ci][1];
var len = Math.sqrt(ux * ux + uz * uz);
var px = Math.round((ux / len) * 9.4), pz = Math.round((uz / len) * 9.4);
for (by = 0; by <= 7; by++) pb(px, by, pz, "deepslate_bricks");
pb(px, 8, pz, "deepslate_brick_slab");
}
// === SMOCK TOWER (tarred timber, tapering octagon) ===
var smockMat = gradientPalette(midY, towerTopY, [
{ block: "dark_oak_planks", from: 0 },
{ block: "dark_oak_planks", from: 0.28 },
{ block: "stripped_dark_oak_wood", from: 0.50 },
{ block: "spruce_planks", from: 0.78 }
], { noise: 0.20, seed: 21 });
function towerR(y) { return 8.0 - (y - midY) * 0.25; }
var ty;
for (ty = midY; ty <= towerTopY; ty++) octShell(ty, towerR(ty), 1, smockMat);
// tarred corner posts up the smock (protrude, give the drum depth)
for (ci = 0; ci < 8; ci++) {
var ux2 = corners[ci][0], uz2 = corners[ci][1];
var l2 = Math.sqrt(ux2 * ux2 + uz2 * uz2);
for (ty = midY; ty <= towerTopY; ty++) {
var rr = towerR(ty) + 0.45;
var ppx = Math.round((ux2 / l2) * rr), ppz = Math.round((uz2 / l2) * rr);
pb(ppx, ty, ppz, "dark_oak_log[axis=y]");
}
}
// horizontal girth bands = more relief
var gb;
for (gb = 0; gb < 2; gb++) {
var gy = midY + 4 + gb * 6;
octShell(gy, towerR(gy) + 0.45, 1, "spruce_slab[type=top]");
}
// === STAGE GALLERY (stelling) ===
var stageMat = noisePalette([{ block: "spruce_planks", weight: 60 }, { block: "stripped_spruce_wood", weight: 25 }, { block: "dark_oak_planks", weight: 15 }], { seed: 12, freq: 0.22 });
var sx, sz;
for (sx = -12; sx <= 12; sx++) {
for (sz = -12; sz <= 12; sz++) {
if (octIn(sx, sz, 11.4) && !octIn(sx, sz, towerR(midY) - 0.2)) {
pb(sx, midY, sz, stageMat(sx, midY, sz));
}
}
}
// railing (2 high) around the stage rim
for (sx = -12; sx <= 12; sx++) {
for (sz = -12; sz <= 12; sz++) {
if (octIn(sx, sz, 11.4) && !octIn(sx, sz, 10.4)) {
pb(sx, midY + 1, sz, "spruce_fence");
if ((sx + sz) % 3 === 0) pb(sx, midY + 2, sz, "spruce_fence");
}
}
}
// 8 diagonal brackets carrying the overhang
for (ci = 0; ci < 8; ci++) {
var bx = corners[ci][0], bz = corners[ci][1];
var bl = Math.sqrt(bx * bx + bz * bz);
var k;
for (k = 0; k < 4; k++) {
var rr2 = 10.6 - k * 1.0;
var kx = Math.round((bx / bl) * rr2), kz = Math.round((bz / bl) * rr2);
pb(kx, midY - 1 - k, kz, "dark_oak_fence");
}
}
// stage stair down to the ground on the south side
staircase(18, 0, walkY, midY + 1, "west");
// === CAP (bulged thatch) ===
var thatch = noisePalette([{ block: "hay_block", weight: 55 }, { block: "stripped_oak_wood", weight: 20 }, { block: "stripped_birch_wood", weight: 15 }, { block: "hay_block[axis=x]", weight: 10 }], { seed: 31, freq: 0.18 });
var ki;
for (ki = 0; ki <= capH; ki++) {
var t = ki / capH;
var rcap = 7.2 * Math.pow(1 - t, 0.72);
if (rcap < 0.6) rcap = 0.6;
var yy = capBaseY + ki;
var Rc = Math.ceil(rcap);
for (var ax = -Rc; ax <= Rc; ax++) {
for (var az = -Rc; az <= Rc; az++) {
var d = Math.sqrt(ax * ax + az * az);
if (d <= rcap && d > rcap - 1.6) pb(ax, yy, az, thatch(ax, yy, az));
}
}
}
// solid crown so there is no sky gap at the apex
fill(-1, capBaseY + capH, -1, 1, capBaseY + capH, 1, "hay_block");
pb(0, capBaseY + capH + 1, 0, "spruce_fence");
pb(0, capBaseY + capH + 2, 0, "spruce_fence");
ps(1, capBaseY + capH + 2, 0, "iron_trapdoor[facing=west,half=bottom,open=true]");
// eave trim under the cap
var ex, ez;
for (ex = -8; ex <= 8; ex++) {
for (ez = -8; ez <= 8; ez++) {
var de = Math.sqrt(ex * ex + ez * ez);
if (de <= 7.6 && de > 6.4) {
if (Math.abs(ex) >= Math.abs(ez)) roofStair(ex, capBaseY - 1, ez, "spruce_stairs", ex > 0 ? "east" : "west");
else roofStair(ex, capBaseY - 1, ez, "spruce_stairs", ez > 0 ? "south" : "north");
}
}
}
// === SAILS (4 lattice blades, X pattern, on the north face) ===
var hubY = 26, hubZ = -5, bladeZ = -6;
fill(0, hubY, -2, 0, hubY, hubZ, "dark_oak_log[axis=z]");
pb(0, hubY, bladeZ, "iron_block");
var dirs = [[0.7071, 0.7071], [0.7071, -0.7071], [-0.7071, 0.7071], [-0.7071, -0.7071]];
var di, tt, ss;
for (di = 0; di < 4; di++) {
var ddx = dirs[di][0], ddy = dirs[di][1];
var pxu = -ddy, pyu = ddx; // perpendicular (in the X/Y plane)
// continuous blade: spine + outer rail + ribs, so nothing is left floating
var s0x = Math.round(ddx * 2), s0y = hubY + Math.round(ddy * 2);
var s1x = Math.round(ddx * 17), s1y = hubY + Math.round(ddy * 17);
var offx = Math.round(pxu * 3), offy = Math.round(pyu * 3);
drawLine(s0x, s0y, bladeZ, s1x, s1y, bladeZ, "spruce_fence", 1);
drawLine(s0x + offx, s0y + offy, bladeZ, s1x + offx, s1y + offy, bladeZ, "spruce_fence", 1);
for (tt = 3; tt <= 17; tt += 2) {
var rx0 = Math.round(ddx * tt), ry0 = hubY + Math.round(ddy * tt);
drawLine(rx0, ry0, bladeZ, rx0 + offx, ry0 + offy, bladeZ, "spruce_fence", 1);
}
for (tt = 3; tt <= 10; tt++) {
var cx0 = Math.round(ddx * tt + pxu * 1), cy0 = hubY + Math.round(ddy * tt + pyu * 1);
var cx1 = Math.round(ddx * tt + pxu * 2.2), cy1 = hubY + Math.round(ddy * tt + pyu * 2.2);
drawLine(cx0, cy0, bladeZ, cx1, cy1, bladeZ, "white_wool", 1);
}
}
// === CLEAR INTERIOR (both floors) then floors ===
var iy, ix, iz;
for (iy = walkY; iy <= towerTopY; iy++) {
var rin = (iy <= 7) ? 7.0 : (towerR(iy) - 1.0);
var Ri = Math.ceil(rin);
for (ix = -Ri; ix <= Ri; ix++) {
for (iz = -Ri; iz <= Ri; iz++) {
if (octIn(ix, iz, rin)) pb(ix, iy, iz, "air");
}
}
}
// grinding floor deck at Y8
octDisc(midY, 7.0, deckMat);
// ceiling joists under the cap
for (ix = -6; ix <= 6; ix += 3) {
for (iz = -6; iz <= 6; iz++) {
if (octIn(ix, iz, 6.2)) pb(ix, towerTopY, iz, "dark_oak_log[axis=z]");
}
}
// === DOOR + WINDOWS ===
// front door, south face
fill(0, walkY, 7, 0, walkY + 1, 10, "air");
ps(0, walkY, 9, "oak_door[facing=south,half=lower,hinge=left]");
ps(0, walkY + 1, 9, "oak_door[facing=south,half=upper,hinge=left]");
roofStair(-1, walkY + 2, 10, "spruce_stairs", "north");
roofStair(0, walkY + 2, 10, "spruce_stairs", "north");
roofStair(1, walkY + 2, 10, "spruce_stairs", "north");
pb(-1, walkY, 10, "spruce_fence"); pb(1, walkY, 10, "spruce_fence");
pb(-1, walkY + 1, 10, "spruce_fence"); pb(1, walkY + 1, 10, "spruce_fence");
// base windows: E, W, SE, SW (recessed, sill + shutters)
var winSpots = [[9, 0], [-9, 0], [6, 6], [-6, 6], [6, -6], [-6, -6]];
var wi;
for (wi = 0; wi < winSpots.length; wi++) {
var wxx = winSpots[wi][0], wzz = winSpots[wi][1];
var nx = wxx === 0 ? 0 : (wxx > 0 ? 1 : -1);
var nz = wzz === 0 ? 0 : (wzz > 0 ? 1 : -1);
var j;
for (j = 0; j <= 2; j++) {
var gx = wxx - nx * j, gz = wzz - nz * j;
pb(gx, 3, gz, "air"); pb(gx, 4, gz, "air");
pb(gx, 3, gz, "glass_pane"); pb(gx, 4, gz, "glass_pane");
}
pb(wxx + nx, 2, wzz + nz, "smooth_quartz_slab");
ps(wxx + nx, 3, wzz + nz - (nz === 0 ? 1 : 0) - (nz !== 0 ? 0 : 0), "air");
pb(wxx + nx, 5, wzz + nz, "spruce_slab[type=top]");
}
// tower windows with stair hoods (dormer hoods)
var twSpots = [[0, 1], [0, -1], [1, 0], [-1, 0]];
for (wi = 0; wi < 4; wi++) {
var ux3 = twSpots[wi][0], uz3 = twSpots[wi][1];
var wy0 = 12;
var rw = towerR(wy0);
var wpx = Math.round(ux3 * rw), wpz = Math.round(uz3 * rw);
var jj;
for (jj = 0; jj < 2; jj++) {
pb(wpx, wy0 + jj, wpz, "glass_pane");
if (ux3 === 0) { pb(wpx - 1, wy0 + jj, wpz, "glass_pane"); }
else { pb(wpx, wy0 + jj, wpz - 1, "glass_pane"); }
}
// hood above
var hy = wy0 + 2;
var edge = ux3 === 1 ? "east" : (ux3 === -1 ? "west" : (uz3 === 1 ? "south" : "north"));
roofStair(wpx + ux3, hy, wpz + uz3, "spruce_stairs", edge);
if (ux3 === 0) roofStair(wpx - 1 + ux3, hy, wpz + uz3, "spruce_stairs", edge);
else roofStair(wpx + ux3, hy, wpz - 1 + uz3, "spruce_stairs", edge);
// sill
pb(wpx + ux3, wy0 - 1, wpz + uz3, "spruce_slab[type=top]");
}
// === STAIRCASE ground -> grinding floor ===
staircase(-5, 5, walkY, walkY2, "north");
// === INTERIOR: GROUND FLOOR (hearth, kitchen, dining, sofa, rug) ===
// hearth on the north wall
fill(0, walkY, -7, 2, walkY + 2, -7, "bricks");
fill(0, walkY, -6, 2, walkY, -6, "bricks");
pb(1, walkY, -6, "campfire[lit=true]");
ps(0, walkY + 1, -6, "brick_stairs[facing=east,half=top]");
ps(2, walkY + 1, -6, "brick_stairs[facing=west,half=top]");
fill(0, walkY + 2, -6, 2, walkY + 2, -6, "brick_slab[type=bottom]");
pb(1, walkY + 3, -6, "bricks"); pb(1, walkY + 4, -6, "bricks");
// mantel decoration
pb(0, walkY + 3, -7, "flower_pot"); pb(2, walkY + 3, -7, "lantern");
// kitchen counter run along the east wall (x=+5..+6)
pb(6, walkY, -2, "stripped_spruce_log"); ps(6, walkY + 1, -2, "spruce_stairs[facing=west,half=top]");
ps(6, walkY, -1, "furnace[facing=west,lit=true]"); ps(6, walkY + 1, -1, "iron_trapdoor[facing=west,half=bottom]");
pb(6, walkY, 0, "stripped_spruce_log"); ps(6, walkY + 1, 0, "spruce_stairs[facing=west,half=top]");
ps(6, walkY + 1, 1, "water_cauldron[level=3]"); pb(6, walkY, 1, "stripped_spruce_log");
pb(6, walkY, 2, "barrel[facing=up]");
pb(5, walkY + 3, 0, "spruce_fence"); pb(5, walkY + 2, 0, "lantern[hanging=true]");
// shelf above the counter
pb(6, walkY + 3, -1, "bookshelf"); pb(6, walkY + 3, 0, "bookshelf");
// dining table + chairs
pb(2, walkY, 2, "dark_oak_fence"); pb(2, walkY + 1, 2, "oak_pressure_plate");
pb(3, walkY, 2, "dark_oak_fence"); pb(3, walkY + 1, 2, "oak_pressure_plate");
chairStair(2, walkY, 1, "spruce_stairs", "south");
chairStair(3, walkY, 3, "spruce_stairs", "north");
pb(2, walkY + 2, 2, "lantern[hanging=true]");
pb(2, walkY + 3, 2, "dark_oak_fence");
// sofa (3 seats) facing north, on the south side
chairStair(-1, walkY, 5, "spruce_stairs", "north");
chairStair(0, walkY, 5, "spruce_stairs", "north");
chairStair(1, walkY, 5, "spruce_stairs", "north");
ps(-2, walkY, 5, "spruce_wall_sign[facing=east]");
ps(2, walkY, 5, "spruce_wall_sign[facing=west]");
// rug in front of the hearth
var rx, rz;
for (rx = -1; rx <= 2; rx++) for (rz = -4; rz <= -1; rz++) pb(rx, walkY, rz, (rx + rz) % 2 === 0 ? "red_carpet" : "brown_carpet");
// flour sacks + storage by the door
pb(3, walkY, 6, "barrel[facing=up]"); pb(4, walkY, 5, "barrel[facing=up]");
pb(3, walkY + 1, 6, "hay_block");
pb(-3, walkY, 6, "chest[facing=north]");
pb(-4, walkY, 3, "flower_pot");
// ceiling lanterns
pb(0, midY - 1, 0, "lantern[hanging=true]");
pb(-3, midY - 1, -3, "lantern[hanging=true]");
pb(4, midY - 1, 3, "lantern[hanging=true]");
// === INTERIOR: GRINDING FLOOR (millstone, sacks, bed nook) ===
// millstone bed
fill(1, walkY2, -2, 3, walkY2, 0, "polished_andesite");
ps(2, walkY2 + 1, -1, "stonecutter[facing=south]");
pb(1, walkY2 + 1, -2, "andesite_wall"); pb(3, walkY2 + 1, 0, "andesite_wall");
// drive shaft down from the cap into the millstone
fill(0, walkY2 + 2, -1, 0, towerTopY - 1, -1, "dark_oak_log[axis=y]");
// sack stacks
pb(4, walkY2, 2, "hay_block"); pb(4, walkY2 + 1, 2, "hay_block"); pb(5, walkY2, 2, "hay_block");
pb(4, walkY2, 3, "barrel[facing=up]"); pb(3, walkY2, 3, "barrel[facing=up]");
pb(5, walkY2, 1, "composter");
// bed nook, north-west
placeBed(-3, walkY2, -3, "white", "north");
pb(-4, walkY2, -3, "spruce_fence"); pb(-4, walkY2 + 1, -3, "oak_pressure_plate"); pb(-4, walkY2 + 2, -3, "lantern");
pb(-2, walkY2, -5, "chest[facing=east]");
// study corner
ps(-4, walkY2, 2, "lectern[facing=east]");
chairStair(-3, walkY2, 2, "dark_oak_stairs", "west");
pb(-4, walkY2, 3, "bookshelf"); pb(-4, walkY2 + 1, 3, "bookshelf");
// rug
for (rx = -1; rx <= 1; rx++) for (rz = 1; rz <= 3; rz++) pb(rx, walkY2, rz, "light_gray_carpet");
// hanging lanterns from the joists
pb(2, towerTopY - 1, 2, "lantern[hanging=true]");
pb(-2, towerTopY - 1, -2, "lantern[hanging=true]");
pb(2, towerTopY - 1, -3, "lantern[hanging=true]");
// === EXTERIOR: path, garden, jetty, planting ===
var pathMat = noisePalette([{ block: "gravel", weight: 40 }, { block: "cobblestone", weight: 30 }, { block: "andesite", weight: 20 }, { block: "coarse_dirt", weight: 10 }], { seed: 6, freq: 0.25 });
var pz2;
for (pz2 = 10; pz2 <= 16; pz2++) {
var wpath = 1 + ((pz2 > 13) ? 1 : 0);
var pxx;
for (pxx = -wpath; pxx <= wpath; pxx++) pb(pxx, padY, pz2 + 0, pathMat(pxx, padY, pz2));
}
// path east to the quay
var pxx2;
for (pxx2 = 2; pxx2 <= 21; pxx2++) {
pb(pxx2, padY, 14, pathMat(pxx2, padY, 14));
pb(pxx2, padY, 15, pathMat(pxx2, padY, 15));
}
// jetty over the canal
var jx;
for (jx = 21; jx <= 27; jx++) {
pb(jx, 0, 14, "spruce_planks"); pb(jx, 0, 15, "spruce_planks");
if (jx > 21) { pb(jx, -1, 14, "spruce_fence"); pb(jx, -1, 15, "spruce_fence"); }
}
pb(27, 1, 14, "spruce_fence"); pb(27, 1, 15, "spruce_fence");
pb(24, 1, 13, "barrel[facing=up]");
// lamp posts (post + lantern on top, never floating)
function lamp(lx, lz) {
pb(lx, 1, lz, "dark_oak_fence"); pb(lx, 2, lz, "dark_oak_fence"); pb(lx, 3, lz, "dark_oak_fence");
pb(lx, 4, lz, "lantern");
}
lamp(-3, 12); lamp(3, 12); lamp(20, 13); lamp(-11, -6);
// garden beds + fence boundary
var gx2, gz2;
for (gx2 = -14; gx2 <= -8; gx2++) {
for (gz2 = 2; gz2 <= 8; gz2++) {
pb(gx2, padY, gz2, "farmland[moisture=7]");
if ((gx2 + gz2) % 2 === 0) pb(gx2, padY + 1, gz2, "wheat[age=7]"); else pb(gx2, padY + 1, gz2, "carrots[age=7]");
}
}
pb(-15, padY + 1, 5, "water");
// fence around the garden
for (gx2 = -16; gx2 <= -7; gx2++) { pb(gx2, padY + 1, 1, "oak_fence"); pb(gx2, padY + 1, 9, "oak_fence"); }
for (gz2 = 1; gz2 <= 9; gz2++) { pb(-16, padY + 1, gz2, "oak_fence"); }
// willows / trees along the bank
function willow(tx, tz, th) {
var i2;
for (i2 = 0; i2 < th; i2++) pb(tx, padY + 1 + i2, tz, "spruce_log[axis=y]");
makeSphere(tx, padY + th, tz, noisePalette([{ block: "oak_leaves[persistent=true]", weight: 65 }, { block: "azalea_leaves[persistent=true]", weight: 20 }, { block: "birch_leaves[persistent=true]", weight: 15 }], { seed: 8, freq: 0.3 }), 3.4, false);
pb(tx, padY + th + 3, tz, "oak_leaves[persistent=true]");
}
willow(16, -10, 5); willow(17, 9, 4); willow(-14, -12, 5); willow(-6, 17, 4);
// flower scatter
var fi;
for (fi = 0; fi < 90; fi++) {
var fx = Math.floor(noise2d(fi * 3.1, 1.7) * 30) - 4;
var fz = Math.floor(noise2d(2.3, fi * 2.9) * 46) - 22;
if (fx > 19 && fx < 36) continue;
if (octIn(fx, fz, 13)) continue;
var gyy = padY + 1;
var fb = (fi % 4 === 0) ? "poppy" : (fi % 4 === 1 ? "dandelion" : (fi % 4 === 2 ? "oxeye_daisy" : "short_grass"));
pb(fx, gyy, fz, fb);
}
// potted plants flanking the door
pb(-2, walkY, 10, "flower_pot"); pb(2, walkY, 10, "flower_pot");