// === BUILD PLAN ===
// Style: Dutch stellingmolen (stage smock mill) turned dwelling + attached gabled BAKEHOUSE wing
// Related-graph routing gave me: "Clean Dome/Cupola = DRUM + CAP + CROWN", "Cylinder min 3 blocks
// per flat side", "Gable ridge cap must be a SOLID block", placeGableRoof helpers, makeCone.
// So this build is composed as: DRUM (brick base cylinder, r9) -> stacked SHRINKING CYLINDERS
// (the tapering smock) -> CONE cap -> CROWN finial. Annex roof uses placeGableRoof (solid ridge).
//
// Footprint: COMPOSITE, not a single volume -
// round mill drum r=9 at (0,0) + 10x10 gabled bakehouse wing to the WEST (x -19..-10)
// + stage gallery ring r=11 at Y7 + canal & quay to the west beyond the wing
//
// GROUND PLAN (top-down, X right, Z down):
// ~~~~~~ +-------+ ....ooo....
// ~canal~ | OVEN | ..o o..
// ~~~~~~ | bake d====o PARLOUR o d = connecting door
// ~~~~~~ | wing | ..o ^ o.. ^ = staircase (runs EAST, Y1->Y9)
// ~~~~~~ +-------+ ....oDo.... D = front door (south)
//
// ELEVATION (south):
// /^\ crown finial
// /=====\ CONE thatch cap (r7 over a r5.6 tower top = 1.4 overhang)
// | o o | stacked shrinking cylinders = tarred smock, girth bands + buttress posts
// \ | | / lattice sails (4 blades)
// =[ STAGE ]= Y7 gallery ring, fence rail, brackets, outside stair
// |#W#D#| DRUM: whitewashed brick, plinth 2 rows, 8 pilasters
// ___|_____|___
//
// MATERIALS PLAN:
// plinth/drum : gradientPalette Y0->Y6 mossy_cobblestone -> andesite -> polished_diorite ->
// white_terracotta -> bone_block WHY: limewash that is grimy at the wet
// canal footing and bright at the cornice = free ambient occlusion on a big drum
// smock : gradientPalette Y8->Y19 dark_oak_planks -> stripped_dark_oak_wood -> spruce_planks
// WHY: tar is darkest in the stage's shadow, lifts toward the light at the cap
// cap : noisePalette hay_block / stripped_oak_wood / stripped_birch_wood = straw
// annex : white_terracotta plaster between dark_oak_log half-timber posts (contrast frame)
// sails : spruce_fence lattice + white_wool canvas on the inner half
// Rooms: PARLOUR (hearth, dresser, table+chairs, rug, lanterns) | BAKEHOUSE (oven bank, kneading
// table, flour barrels, hay) | GRINDING FLOOR Y8 (millstone, sacks, bed nook, desk)
// STAIR PLAN: delta = 9 - 1 = 8 -> one straight flight EAST: staircase(-4, -4, 1, 9, "east")
// === END PLAN ===
var floorY = 0, walkY = 1;
var drumTopY = 6; // last row of the brick drum
var stageY = 7; // cornice + stage gallery deck
var smockY0 = 8, smockY1 = 19;
var walkY2 = 9; // grinding floor walk level (floor deck at Y8)
var capBaseY = 20, capH = 10;
// ---------- TERRAIN ----------
var ground = terrain({
cx: -2, cz: 0, radius: 38, baseY: -1, amp: 3, scale: 0.05, seed: 44,
irregularity: 0.4,
surface: [{ block: "grass_block", w: 60 }, { block: "coarse_dirt", w: 16 }, { block: "podzol", w: 12 }, { block: "moss_block", w: 12 }],
sub: "dirt", deep: "stone", depth: 4,
pads: [{ cx: 0, cz: 0, r: 14, y: floorY, falloff: 8 }, { cx: -15, cz: 0, r: 9, y: floorY, falloff: 6 }]
});
// canal to the WEST + brick quay
var quay = noisePalette([{ block: "bricks", weight: 40 }, { block: "mossy_stone_bricks", weight: 28 }, { block: "stone_bricks", weight: 20 }, { block: "cracked_stone_bricks", weight: 12 }], { seed: 71, freq: 0.15 });
fill(-34, -5, -38, -24, 8, 38, "air");
fill(-34, -5, -38, -24, -2, 38, "water");
var cq;
for (cq = -38; cq <= 38; cq++) {
var qy;
for (qy = -5; qy <= 0; qy++) { pb(-23, qy, cq, quay(-23, qy, cq)); pb(-35, qy, cq, quay(-35, qy, cq)); }
pb(-23, 1, cq, "brick_slab");
pb(-35, 1, cq, "brick_slab");
}
// ---------- DRUM (whitewashed brick base) ----------
var drumMat = gradientPalette(floorY, drumTopY, [
{ block: "mossy_cobblestone", from: 0 },
{ block: "andesite", from: 0.22 },
{ block: "polished_andesite", from: 0.40 },
{ block: "polished_diorite", from: 0.58 },
{ block: "white_terracotta", from: 0.74 },
{ block: "bone_block[axis=y]", from: 0.90 }
], { noise: 0.24, seed: 5 });
makeCylinder(0, floorY, 0, drumMat, 9, drumTopY - floorY + 1, true); // hollow drum, 1 thick
makeCylinder(0, floorY, 0, drumMat, 10, 2, true); // 2-row plinth, wider = depth
makeCylinder(0, floorY, 0, noisePalette([{ block: "spruce_planks", weight: 55 }, { block: "dark_oak_planks", weight: 25 }, { block: "stripped_spruce_wood", weight: 20 }], { seed: 2, freq: 0.2 }), 8, 1, false); // floor disc
// 8 pilasters on the drum (real relief, min 3 blocks per flat side respected by using r>=9)
var ang, pi2;
for (pi2 = 0; pi2 < 8; pi2++) {
ang = (Math.PI * 2 / 8) * pi2 + 0.39;
var px = Math.round(Math.cos(ang) * 9.4), pz = Math.round(Math.sin(ang) * 9.4);
var yy;
for (yy = floorY; yy <= drumTopY; yy++) pb(px, yy, pz, yy < 3 ? "deepslate_bricks" : "polished_deepslate");
pb(px, drumTopY + 1, pz, "polished_deepslate_slab");
}
// cornice ring on top of the drum (1 block overhang, as the drum+cap rule asks)
makeCylinder(0, stageY, 0, "smooth_quartz_slab", 10, 1, true);
// ---------- SMOCK: stacked SHRINKING CYLINDERS ----------
var smockMat = gradientPalette(smockY0, smockY1, [
{ block: "dark_oak_planks", from: 0 },
{ block: "dark_oak_planks", from: 0.26 },
{ block: "stripped_dark_oak_wood", from: 0.52 },
{ block: "spruce_planks", from: 0.80 }
], { noise: 0.2, seed: 66 });
function smockR(y) { return 8.2 - (y - smockY0) * 0.24; }
var sy;
for (sy = smockY0; sy <= smockY1; sy++) {
makeCylinder(0, sy, 0, smockMat, smockR(sy), 1, true);
}
// tarred corner posts + two girth bands = the drum is not a smooth blank tube
for (pi2 = 0; pi2 < 8; pi2++) {
ang = (Math.PI * 2 / 8) * pi2 + 0.39;
for (sy = smockY0; sy <= smockY1; sy++) {
var rr = smockR(sy) + 0.5;
pb(Math.round(Math.cos(ang) * rr), sy, Math.round(Math.sin(ang) * rr), "dark_oak_log[axis=y]");
}
}
makeCylinder(0, 12, 0, "spruce_slab[type=top]", smockR(12) + 0.5, 1, true);
makeCylinder(0, 16, 0, "spruce_slab[type=top]", smockR(16) + 0.5, 1, true);
// ---------- STAGE GALLERY (Y7 ring) ----------
var stageMat = noisePalette([{ block: "spruce_planks", weight: 58 }, { block: "stripped_spruce_wood", weight: 26 }, { block: "dark_oak_planks", weight: 16 }], { seed: 88, freq: 0.22 });
var gx, gz, d2;
for (gx = -12; gx <= 12; gx++) {
for (gz = -12; gz <= 12; gz++) {
d2 = Math.sqrt(gx * gx + gz * gz);
if (d2 <= 11.6 && d2 > 8.4) pb(gx, stageY, gz, stageMat(gx, stageY, gz));
if (d2 <= 11.6 && d2 > 10.6) {
pb(gx, stageY + 1, gz, "spruce_fence");
if ((gx + gz) % 3 === 0) pb(gx, stageY + 2, gz, "spruce_fence");
}
}
}
// brackets under the overhanging deck
for (pi2 = 0; pi2 < 12; pi2++) {
ang = (Math.PI * 2 / 12) * pi2;
var k2;
for (k2 = 0; k2 < 4; k2++) {
var rb = 11.0 - k2 * 0.9;
pb(Math.round(Math.cos(ang) * rb), stageY - 1 - k2, Math.round(Math.sin(ang) * rb), "dark_oak_fence");
}
}
// outside stair up to the stage (ground walkY -> stage deck walk level)
staircase(0, 17, walkY, stageY + 1, "north");
// ---------- CONE CAP + CROWN ----------
var thatch = noisePalette([{ block: "hay_block", weight: 52 }, { block: "stripped_oak_wood", weight: 22 }, { block: "stripped_birch_wood", weight: 16 }, { block: "hay_block[axis=x]", weight: 10 }], { seed: 13, freq: 0.19 });
var capI;
for (capI = 0; capI < capH; capI++) {
var rcap = 7 * (1 - capI / capH);
if (rcap < 1.2) rcap = 1.2;
makeCylinder(0, capBaseY + capI, 0, thatch, rcap, 1, false); // SOLID disc = no sky gaps
}
// CROWN — never leave the apex open
fill(-1, capBaseY + capH - 1, -1, 1, capBaseY + capH, 1, "hay_block");
pb(0, capBaseY + capH + 1, 0, "dark_oak_fence");
pb(0, capBaseY + capH + 2, 0, "dark_oak_fence");
ps(1, capBaseY + capH + 2, 0, "copper_trapdoor[facing=west,half=bottom,open=true]");
pb(0, capBaseY + capH + 3, 0, "lightning_rod[facing=up]");
// eave trim under the cone
var ex, ez, de;
for (ex = -9; ex <= 9; ex++) {
for (ez = -9; ez <= 9; ez++) {
de = Math.sqrt(ex * ex + ez * ez);
if (de <= 7.8 && de > 6.6) {
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 (south face) ----------
var hubY = 27, bladeZ = 8;
fill(0, hubY, 0, 0, hubY, 7, "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 pux = -ddy, puy = ddx;
var b0x = Math.round(ddx * 2), b0y = hubY + Math.round(ddy * 2);
var b1x = Math.round(ddx * 17), b1y = hubY + Math.round(ddy * 17);
var ofx = Math.round(pux * 3), ofy = Math.round(puy * 3);
drawLine(b0x, b0y, bladeZ, b1x, b1y, bladeZ, "spruce_fence", 1);
drawLine(b0x + ofx, b0y + ofy, bladeZ, b1x + ofx, b1y + ofy, bladeZ, "spruce_fence", 1);
for (tt = 3; tt <= 17; tt += 2) {
var qx0 = Math.round(ddx * tt), qy0 = hubY + Math.round(ddy * tt);
drawLine(qx0, qy0, bladeZ, qx0 + ofx, qy0 + ofy, bladeZ, "spruce_fence", 1);
}
for (tt = 3; tt <= 10; tt++) {
var vx0 = Math.round(ddx * tt + pux * 1), vy0 = hubY + Math.round(ddy * tt + puy * 1);
var vx1 = Math.round(ddx * tt + pux * 2.2), vy1 = hubY + Math.round(ddy * tt + puy * 2.2);
drawLine(vx0, vy0, bladeZ, vx1, vy1, bladeZ, "white_wool", 1);
}
}
// ---------- BAKEHOUSE ANNEX (gabled wing, west) ----------
var ax1 = -19, ax2 = -10, az1 = -5, az2 = 4;
var annexTopY = 5;
var plaster = noisePalette([{ block: "white_terracotta", weight: 60 }, { block: "bone_block[axis=y]", weight: 22 }, { block: "smooth_quartz", weight: 18 }], { seed: 33, freq: 0.2 });
fill(ax1, floorY, az1, ax2, floorY, az2, noisePalette([{ block: "polished_andesite", weight: 55 }, { block: "andesite", weight: 25 }, { block: "cobblestone", weight: 20 }], { seed: 41, freq: 0.22 }));
makeWalls(ax1, walkY, az1, ax2, annexTopY, az2, plaster);
// half-timber frame: dark posts at every 3rd column + sill/head beams (contrast frame, real depth)
var hx, hz;
for (hx = ax1; hx <= ax2; hx += 3) {
for (hz = az1; hz <= az2; hz += 9) {
var yy2;
for (yy2 = walkY; yy2 <= annexTopY; yy2++) { pb(hx, yy2, hz, "dark_oak_log[axis=y]"); }
}
}
for (hz = az1; hz <= az2; hz += 3) {
var yy3;
for (yy3 = walkY; yy3 <= annexTopY; yy3++) { pb(ax1, yy3, hz, "dark_oak_log[axis=y]"); pb(ax2, yy3, hz, "dark_oak_log[axis=y]"); }
}
fill(ax1, annexTopY, az1, ax2, annexTopY, az2, "dark_oak_log[axis=x]");
makeWalls(ax1, annexTopY, az1, ax2, annexTopY, az2, "dark_oak_log[axis=x]");
// gable roof, ridge along Z (slopes E/W), end gables auto-filled, SOLID ridge cap
placeGableRoof(ax1, ax2, az1, az2, annexTopY + 1, "spruce_stairs", "spruce_slab", "dark_oak_planks");
// chimney bump-out on the annex
fill(-17, walkY, az1 - 1, -16, annexTopY + 6, az1 - 1, noisePalette([{ block: "bricks", weight: 65 }, { block: "mossy_stone_bricks", weight: 20 }, { block: "cracked_stone_bricks", weight: 15 }], { seed: 9, freq: 0.2 }));
pb(-17, annexTopY + 7, az1 - 1, "brick_slab"); pb(-16, annexTopY + 7, az1 - 1, "brick_slab");
pb(-17, annexTopY + 8, az1 - 1, "campfire[lit=true]");
// annex windows
var awz;
for (awz = -3; awz <= 2; awz += 3) {
pb(ax1, 3, awz, "glass_pane"); pb(ax1, 4, awz, "glass_pane");
pb(ax1 - 1, 2, awz, "spruce_slab[type=top]");
ps(ax1, 3, awz - 1, "spruce_trapdoor[facing=east,half=bottom,open=true]");
ps(ax1, 3, awz + 1, "spruce_trapdoor[facing=east,half=bottom,open=true]");
}
pb(-15, 3, az2, "glass_pane"); pb(-15, 4, az2, "glass_pane");
pb(-13, 3, az2, "glass_pane"); pb(-13, 4, az2, "glass_pane");
// ---------- CLEAR INTERIORS ----------
var iy, ix, iz, dd;
for (iy = walkY; iy <= smockY1; iy++) {
var rin = (iy <= drumTopY) ? 8.0 : (smockR(iy) - 1.0);
var Ri = Math.ceil(rin);
for (ix = -Ri; ix <= Ri; ix++) {
for (iz = -Ri; iz <= Ri; iz++) {
dd = Math.sqrt(ix * ix + iz * iz);
if (dd <= rin) pb(ix, iy, iz, "air");
}
}
}
fill(ax1 + 1, walkY, az1 + 1, ax2 - 1, annexTopY + 4, az2 - 1, "air");
fill(ax1 + 1, floorY, az1 + 1, ax2 - 1, floorY, az2 - 1, "polished_andesite");
// grinding floor deck
makeCylinder(0, smockY0, 0, noisePalette([{ block: "spruce_planks", weight: 60 }, { block: "dark_oak_planks", weight: 22 }, { block: "stripped_spruce_wood", weight: 18 }], { seed: 7, freq: 0.2 }), 7.4, 1, false);
// joists under the cap
for (ix = -6; ix <= 6; ix += 3) {
for (iz = -6; iz <= 6; iz++) {
if (Math.sqrt(ix * ix + iz * iz) <= 6.2) pb(ix, smockY1, iz, "dark_oak_log[axis=z]");
}
}
// ---------- DOORS & WINDOWS ----------
// front door (south) with a small porch hood
fill(0, walkY, 7, 0, walkY + 1, 10, "air");
ps(0, walkY, 9, "spruce_door[facing=south,half=lower,hinge=left]");
ps(0, walkY + 1, 9, "spruce_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, "dark_oak_fence"); pb(1, walkY, 10, "dark_oak_fence");
pb(-1, walkY + 1, 10, "dark_oak_fence"); pb(1, walkY + 1, 10, "dark_oak_fence");
// connecting door mill <-> bakehouse
fill(-10, walkY, 0, -8, walkY + 1, 0, "air");
ps(-9, walkY, 0, "spruce_door[facing=west,half=lower,hinge=left]");
ps(-9, walkY + 1, 0, "spruce_door[facing=west,half=upper,hinge=left]");
// drum windows (recessed, sill + shutters)
var wAng = [0.6, 1.6, 2.6, 3.8, 4.9, 5.7];
var wi2;
for (wi2 = 0; wi2 < wAng.length; wi2++) {
var wx2 = Math.round(Math.cos(wAng[wi2]) * 9), wz2 = Math.round(Math.sin(wAng[wi2]) * 9);
pb(wx2, 3, wz2, "glass_pane"); pb(wx2, 4, wz2, "glass_pane");
var ox2 = Math.round(Math.cos(wAng[wi2]) * 10), oz2 = Math.round(Math.sin(wAng[wi2]) * 10);
pb(ox2, 2, oz2, "smooth_quartz_slab");
pb(ox2, 5, oz2, "spruce_slab[type=top]");
}
// smock dormer windows with stair hoods
var dAng = [0.0, 1.57, 3.14, 4.71];
var wy0 = 13;
for (wi2 = 0; wi2 < 4; wi2++) {
var rw = smockR(wy0);
var dx2 = Math.round(Math.cos(dAng[wi2]) * rw), dz2 = Math.round(Math.sin(dAng[wi2]) * rw);
pb(dx2, wy0, dz2, "glass_pane"); pb(dx2, wy0 + 1, dz2, "glass_pane");
var ux4 = Math.round(Math.cos(dAng[wi2])), uz4 = Math.round(Math.sin(dAng[wi2]));
var edge2 = ux4 === 1 ? "east" : (ux4 === -1 ? "west" : (uz4 === 1 ? "south" : "north"));
roofStair(dx2 + ux4, wy0 + 2, dz2 + uz4, "spruce_stairs", edge2);
pb(dx2 + ux4, wy0 - 1, dz2 + uz4, "spruce_slab[type=top]");
}
// ---------- STAIRCASE ----------
staircase(-4, -4, walkY, walkY2, "east");
// ---------- INTERIOR: PARLOUR (ground floor of the mill) ----------
// hearth against the north-east arc
fill(4, walkY, -6, 6, walkY + 2, -6, "bricks");
pb(5, walkY, -5, "campfire[lit=true]");
ps(4, walkY + 1, -5, "brick_stairs[facing=east,half=top]");
ps(6, walkY + 1, -5, "brick_stairs[facing=west,half=top]");
fill(4, walkY + 2, -5, 6, walkY + 2, -5, "brick_slab[type=bottom]");
pb(5, walkY + 3, -6, "lantern");
// dresser / shelf wall
pb(7, walkY, -2, "barrel[facing=up]"); pb(7, walkY + 1, -2, "bookshelf");
pb(7, walkY, -1, "cartography_table"); pb(7, walkY + 1, -1, "bookshelf");
pb(7, walkY, 0, "barrel[facing=up]");
// table + 3 chairs
pb(3, walkY, 3, "dark_oak_fence"); pb(3, walkY + 1, 3, "oak_pressure_plate");
pb(4, walkY, 3, "dark_oak_fence"); pb(4, walkY + 1, 3, "oak_pressure_plate");
chairStair(3, walkY, 2, "spruce_stairs", "south");
chairStair(4, walkY, 4, "spruce_stairs", "north");
chairStair(5, walkY, 3, "spruce_stairs", "west");
pb(3, walkY + 3, 3, "dark_oak_fence"); pb(3, walkY + 2, 3, "lantern[hanging=true]");
// rug
var rx, rz;
for (rx = 0; rx <= 3; rx++) for (rz = -3; rz <= 0; rz++) pb(rx, walkY, rz, (rx + rz) % 2 === 0 ? "brown_carpet" : "orange_carpet");
// bench under the south windows + storage by the door
chairStair(-2, walkY, 6, "spruce_stairs", "north");
chairStair(-1, walkY, 6, "spruce_stairs", "north");
pb(2, walkY, 6, "barrel[facing=up]"); pb(2, walkY + 1, 6, "hay_block");
pb(-6, walkY, 5, "chest[facing=north]");
pb(-5, walkY, -6, "flower_pot");
pb(0, drumTopY, 0, "lantern[hanging=true]");
pb(-4, drumTopY, 3, "lantern[hanging=true]");
pb(5, drumTopY, 2, "lantern[hanging=true]");
// ---------- INTERIOR: BAKEHOUSE ANNEX ----------
ps(-18, walkY, -4, "smoker[facing=south,lit=true]");
ps(-17, walkY, -4, "furnace[facing=south,lit=true]");
ps(-16, walkY, -4, "furnace[facing=south,lit=false]");
ps(-18, walkY + 1, -4, "iron_trapdoor[facing=south,half=bottom]");
ps(-17, walkY + 1, -4, "iron_trapdoor[facing=south,half=bottom]");
pb(-15, walkY, -4, "stripped_spruce_log"); ps(-15, walkY + 1, -4, "spruce_stairs[facing=south,half=top]");
// kneading table
pb(-17, walkY, -1, "stripped_oak_log[axis=y]"); pb(-17, walkY + 1, -1, "smooth_quartz_slab");
pb(-16, walkY, -1, "stripped_oak_log[axis=y]"); pb(-16, walkY + 1, -1, "smooth_quartz_slab");
chairStair(-17, walkY, 0, "spruce_stairs", "north");
// flour store
pb(-18, walkY, 2, "barrel[facing=up]"); pb(-18, walkY + 1, 2, "barrel[facing=up]");
pb(-17, walkY, 2, "barrel[facing=up]"); pb(-18, walkY, 3, "hay_block"); pb(-17, walkY, 3, "hay_block");
pb(-13, walkY, 2, "cauldron[level=0]"); pb(-12, walkY, 2, "composter");
pb(-14, walkY, -3, "crafting_table");
pb(-15, annexTopY - 1, 0, "lantern[hanging=true]");
pb(-13, annexTopY - 1, -3, "lantern[hanging=true]");
for (rx = -15; rx <= -12; rx++) for (rz = -1; rz <= 1; rz++) pb(rx, walkY, rz, "white_carpet");
// ---------- INTERIOR: GRINDING FLOOR ----------
fill(-2, walkY2, -2, 0, walkY2, 0, "polished_andesite");
ps(-1, walkY2 + 1, -1, "stonecutter[facing=south]");
pb(-2, walkY2 + 1, -2, "andesite_wall"); pb(0, walkY2 + 1, 0, "andesite_wall");
fill(-1, walkY2 + 2, -1, -1, smockY1 - 1, -1, "dark_oak_log[axis=y]");
pb(3, walkY2, 3, "hay_block"); pb(3, walkY2 + 1, 3, "hay_block"); pb(4, walkY2, 3, "hay_block");
pb(3, walkY2, 4, "barrel[facing=up]"); pb(2, walkY2, 4, "barrel[facing=up]");
placeBed(3, walkY2, -3, "light_blue", "north");
pb(4, walkY2, -3, "spruce_fence"); pb(4, walkY2 + 1, -3, "oak_pressure_plate"); pb(4, walkY2 + 2, -3, "lantern");
pb(1, walkY2, -5, "chest[facing=east]");
ps(-4, walkY2, 2, "lectern[facing=east]");
chairStair(-3, walkY2, 2, "dark_oak_stairs", "west");
pb(-5, walkY2, 2, "bookshelf"); pb(-5, walkY2 + 1, 2, "bookshelf");
pb(-4, walkY2, -2, "loom[facing=south]");
for (rx = -2; rx <= 0; rx++) for (rz = 2; rz <= 4; rz++) pb(rx, walkY2, rz, "light_gray_carpet");
pb(2, smockY1 - 1, 2, "lantern[hanging=true]");
pb(-3, smockY1 - 1, -3, "lantern[hanging=true]");
pb(2, smockY1 - 1, -3, "lantern[hanging=true]");
// ---------- EXTERIOR ----------
var pathMat = noisePalette([{ block: "gravel", weight: 42 }, { block: "cobblestone", weight: 28 }, { block: "andesite", weight: 18 }, { block: "coarse_dirt", weight: 12 }], { seed: 55, freq: 0.25 });
var pz3;
for (pz3 = 10; pz3 <= 20; pz3++) {
var wpath = (pz3 > 15) ? 2 : 1;
var pxx;
for (pxx = -wpath; pxx <= wpath; pxx++) pb(pxx, floorY, pz3, pathMat(pxx, floorY, pz3));
}
var pxx3;
for (pxx3 = -23; pxx3 <= -8; pxx3++) { pb(pxx3, floorY, 7, pathMat(pxx3, floorY, 7)); pb(pxx3, floorY, 8, pathMat(pxx3, floorY, 8)); }
// jetty over the canal (west)
var jx;
for (jx = -29; jx <= -23; jx++) {
pb(jx, 0, 7, "spruce_planks"); pb(jx, 0, 8, "spruce_planks");
if (jx < -23) { pb(jx, -1, 7, "spruce_fence"); pb(jx, -1, 8, "spruce_fence"); }
}
pb(-29, 1, 7, "spruce_fence"); pb(-29, 1, 8, "spruce_fence");
pb(-26, 1, 6, "barrel[facing=up]"); pb(-27, 1, 6, "barrel[facing=up]");
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, 13); lamp(3, 13); lamp(-22, 6); lamp(-8, -8);
// orchard + kitchen garden east
var gx3, gz3;
for (gx3 = 13; gx3 <= 19; gx3++) {
for (gz3 = -4; gz3 <= 4; gz3++) {
pb(gx3, floorY, gz3, "farmland[moisture=7]");
pb(gx3, floorY + 1, gz3, ((gx3 + gz3) % 3 === 0) ? "beetroots[age=3]" : (((gx3 + gz3) % 3 === 1) ? "wheat[age=7]" : "potatoes[age=7]"));
}
}
for (gx3 = 12; gx3 <= 20; gx3++) { pb(gx3, floorY + 1, -5, "oak_fence"); pb(gx3, floorY + 1, 5, "oak_fence"); }
for (gz3 = -5; gz3 <= 5; gz3++) { pb(20, floorY + 1, gz3, "oak_fence"); }
function tree(tx, tz, th, leafSeed) {
var i3;
for (i3 = 0; i3 < th; i3++) pb(tx, floorY + 1 + i3, tz, "oak_log[axis=y]");
makeSphere(tx, floorY + th, tz, noisePalette([{ block: "oak_leaves[persistent=true]", weight: 62 }, { block: "birch_leaves[persistent=true]", weight: 20 }, { block: "azalea_leaves[persistent=true]", weight: 18 }], { seed: leafSeed, freq: 0.3 }), 3.2, false);
pb(tx, floorY + th + 3, tz, "oak_leaves[persistent=true]");
}
tree(14, 10, 5, 3); tree(9, -13, 5, 6); tree(-14, 12, 4, 11); tree(-18, -12, 5, 15);
var fi;
for (fi = 0; fi < 90; fi++) {
var fx = Math.floor(noise2d(fi * 2.7, 0.9) * 48) - 22;
var fz = Math.floor(noise2d(1.3, fi * 3.3) * 46) - 22;
if (fx < -22) continue;
if (fx >= -20 && fx <= -9 && fz >= -6 && fz <= 5) continue;
if (Math.sqrt(fx * fx + fz * fz) < 13) continue;
var fb = (fi % 5 === 0) ? "cornflower" : (fi % 5 === 1 ? "dandelion" : (fi % 5 === 2 ? "oxeye_daisy" : (fi % 5 === 3 ? "azure_bluet" : "short_grass")));
pb(fx, floorY + 1, fz, fb);
}
pb(-2, walkY, 10, "flower_pot"); pb(2, walkY, 10, "flower_pot");