// === BUILD PLAN ===
// Style: Scottish Highland distillery (vernacular harled stone + slate + pagoda kiln)
// Footprint: composite L — still house 23x13 (x18..40,z22..34) + malt kiln tower 9x9 (x40..48,z24..32)
// + detached cask store 11x9 (x20..30,z38..46). Low stone wall yard, stream to the west.
// Height: still house walls floorY..18 (8 air) + gable ridge Y25 ; kiln tower to Y26 + pagoda tiers to ~Y38
//
// GROUND FLOOR (top-down, 1 char = 1 block, Z down):
// z22 #####W##D##W#####W## <- front (north) facade
// z23 # s t i l l r o o m #########
// z25 # (O) (O) (O) # KILN # O = copper pot still
// z28 # [stair up] D fire # D = internal doorway
// z30 # casks #########
// z34 #############
// (mezzanine over z28..33 at Y14, reached by staircase())
//
// FRONT ELEVATION:
// /\_____/\ pagoda
// / slate \ /____\
// |W W D W W| | |
// |___________| |__|
//
// MATERIALS PLAN:
// base : gradientPalette mossy_cobble -> cobble -> stone_bricks (rows 0..3) — WHY: damp riverside patina, grounds it
// walls : noisePalette white_terracotta45/calcite25/smooth_quartz15/diorite10/bone5 — WHY: harled whitewash, warm-grey mottle
// frame : stone_bricks pilasters every 5 blocks + recessed windows — WHY: facade depth (weakness #1)
// roof : deepslate_tile_stairs shingles, deepslate ridge beam (solid, never slab) — WHY: Highland slate
// accents: waxed copper stills, spruce beams/mezzanine, lanterns, oak barrels
// Rooms: Still room (3 pot stills, spirit safe, casks, mezzanine office), Malt kiln (fire pit, barley, drying floor), Cask store
// STAIR PLAN: delta = walkY10 -> walkY15 = 5 -> staircase(20,24,10,15,'south') single flight, lands flush on mezzanine z29
// === END PLAN ===
var padY = 8;
var floorY = padY + 1; // 9
var walkY = floorY + 1; // 10
var wallTopY = 18; // 8 blocks of interior air
var roofBaseY = wallTopY + 1;
var mezzFloorY = 14;
var mezzWalkY = mezzFloorY + 1;
// === TERRAIN ===
var groundH = terrain({
cx: 33, cz: 32, radius: 42, baseY: padY - 1, amp: 3, scale: 0.045, seed: 21,
surface: [{block: 'grass_block', w: 50}, {block: 'moss_block', w: 24}, {block: 'coarse_dirt', w: 14}, {block: 'stone', w: 12}],
sub: 'dirt', deep: 'stone', depth: 4,
pads: [{cx: 33, cz: 30, r: 26, y: padY, falloff: 9}]
});
// stream along the west edge (mossy riverside)
var chan = meander(6, 0, 13, 67, {seed: 3});
for (var rx = 0; rx <= 18; rx++) {
for (var rz = 0; rz <= 67; rz++) {
var d = chan(rx, rz);
if (d < 4.2) {
var gh = Math.floor(groundH(rx, rz));
fill(rx, padY - 3, rz, rx, gh + 3, rz, 'air');
pb(rx, padY - 4, rz, 'gravel');
fill(rx, padY - 3, rz, rx, padY - 1, rz, 'water');
if (d > 3.1) { pb(rx, padY - 1, rz, 'mossy_cobblestone'); pb(rx, padY, rz, 'mossy_cobblestone'); }
}
}
}
// === PALETTES ===
var basePal = gradientPalette(floorY, floorY + 3, [
{block: 'mossy_cobblestone', from: 0}, {block: 'cobblestone', from: 0.45}, {block: 'stone_bricks', from: 0.8}
], {noise: 0.28, seed: 4});
var wallPal = noisePalette([
{block: 'white_terracotta', weight: 45}, {block: 'calcite', weight: 25},
{block: 'smooth_quartz', weight: 15}, {block: 'diorite', weight: 10}, {block: 'bone_block', weight: 5}
], {seed: 11, freq: 0.09});
var slatePal = noisePalette([
{block: 'deepslate_tile_stairs', weight: 50}, {block: 'cobbled_deepslate_stairs', weight: 28}, {block: 'deepslate_brick_stairs', weight: 22}
], {seed: 9, freq: 0.16});
var floorPal = noisePalette([
{block: 'stone_bricks', weight: 40}, {block: 'andesite', weight: 25}, {block: 'cobblestone', weight: 20}, {block: 'mossy_stone_bricks', weight: 15}
], {seed: 17, freq: 0.13});
var copperPal = noisePalette([
{block: 'waxed_copper_block', weight: 55}, {block: 'waxed_exposed_copper', weight: 30}, {block: 'waxed_cut_copper', weight: 15}
], {seed: 33, freq: 0.25});
function perim(x1, z1, x2, z2, y1, y2, pat) {
fill(x1, y1, z1, x2, y2, z1, pat);
fill(x1, y1, z2, x2, y2, z2, pat);
fill(x1, y1, z1, x1, y2, z2, pat);
fill(x2, y1, z1, x2, y2, z2, pat);
}
// === STRUCTURE : STILL HOUSE ===
var hx1 = 18, hx2 = 40, hz1 = 22, hz2 = 34;
// plinth + floor
fill(hx1 - 1, padY - 2, hz1 - 1, hx2 + 1, floorY - 1, hz2 + 1, 'cobblestone');
fill(hx1, floorY, hz1, hx2, floorY, hz2, floorPal);
perim(hx1, hz1, hx2, hz2, floorY, floorY + 2, basePal);
perim(hx1, hz1, hx2, hz2, floorY + 3, wallTopY, wallPal);
// clear interior
fill(hx1 + 1, walkY, hz1 + 1, hx2 - 1, wallTopY + 6, hz2 - 1, 'air');
fill(hx1 + 1, floorY, hz1 + 1, hx2 - 1, floorY, hz2 - 1, floorPal);
// pilasters (facade depth) on long walls
for (var px = hx1; px <= hx2; px += 5) {
fill(px, floorY, hz1 - 1, px, wallTopY, hz1 - 1, 'stone_bricks');
fill(px, floorY, hz2 + 1, px, wallTopY, hz2 + 1, 'stone_bricks');
ps(px, wallTopY + 1, hz1 - 1, 'stone_brick_stairs[facing=north,half=top]');
ps(px, wallTopY + 1, hz2 + 1, 'stone_brick_stairs[facing=south,half=top]');
}
for (var pz = hz1 + 3; pz <= hz2 - 3; pz += 5) {
fill(hx1 - 1, floorY, pz, hx1 - 1, wallTopY, pz, 'stone_bricks');
}
// cornice band
perim(hx1 - 1, hz1 - 1, hx2 + 1, hz2 + 1, wallTopY, wallTopY, 'stone_brick_slab[type=top]');
// small-paned windows (recessed, stone surround) on both long walls
function window2(x, z, wallDirZ) {
fill(x, walkY + 2, z, x + 1, walkY + 4, z, 'glass_pane');
pb(x, walkY + 5, z, 'stone_bricks'); pb(x + 1, walkY + 5, z, 'stone_bricks');
pb(x - 1, walkY + 2, z, 'stone_bricks'); pb(x - 1, walkY + 3, z, 'stone_bricks'); pb(x - 1, walkY + 4, z, 'stone_bricks');
pb(x + 2, walkY + 2, z, 'stone_bricks'); pb(x + 2, walkY + 3, z, 'stone_bricks'); pb(x + 2, walkY + 4, z, 'stone_bricks');
ps(x, walkY + 1, z, 'stone_brick_slab[type=top]'); ps(x + 1, walkY + 1, z, 'stone_brick_slab[type=top]');
// mullion
pb(x, walkY + 3, z, 'iron_bars'); pb(x + 1, walkY + 3, z, 'iron_bars');
}
window2(21, hz1, -1); window2(25, hz1, -1); window2(33, hz1, -1); window2(37, hz1, -1);
window2(21, hz2, 1); window2(26, hz2, 1); window2(32, hz2, 1); window2(37, hz2, 1);
// upper (mezzanine level) windows on south wall
fill(24, mezzWalkY + 1, hz2, 25, mezzWalkY + 2, hz2, 'glass_pane');
fill(34, mezzWalkY + 1, hz2, 35, mezzWalkY + 2, hz2, 'glass_pane');
// west gable window
fill(hx1, walkY + 2, 27, hx1, walkY + 4, 29, 'glass_pane');
// main entrance (double door, porch)
fill(28, walkY, hz1, 29, walkY + 2, hz1, 'air');
ps(28, walkY, hz1, 'spruce_door[facing=south,half=lower,hinge=left]');
ps(28, walkY + 1, hz1, 'spruce_door[facing=south,half=upper,hinge=left]');
ps(29, walkY, hz1, 'spruce_door[facing=south,half=lower,hinge=right]');
ps(29, walkY + 1, hz1, 'spruce_door[facing=south,half=upper,hinge=right]');
// porch canopy on posts
fill(27, walkY, hz1 - 3, 27, walkY + 3, hz1 - 3, 'spruce_fence');
fill(30, walkY, hz1 - 3, 30, walkY + 3, hz1 - 3, 'spruce_fence');
for (var cx = 26; cx <= 31; cx++) {
roofStair(cx, walkY + 4, hz1 - 3, 'spruce_stairs', 'north');
pb(cx, walkY + 4, hz1 - 2, 'spruce_planks');
pb(cx, walkY + 4, hz1 - 1, 'spruce_slab[type=top]');
}
ps(27, walkY + 3, hz1 - 2, 'spruce_wall_sign[facing=north]');
// === ROOF : slate gable, ridge along X (slopes N/S) ===
var halfD = 7; // depth 13 -> ceil(13/2)
for (var x = hx1 - 1; x <= hx2 + 1; x++) {
for (var step = 0; step < halfD; step++) {
var zn = hz1 - 1 + step, zs = hz2 + 1 - step, ry = roofBaseY + step;
roofStair(x, ry, zn, slatePal(x, 0, zn), 'north');
roofStair(x, ry, zs, slatePal(x, 0, zs), 'south');
}
pb(x, roofBaseY + halfD - 1, 28, 'deepslate_tiles'); // SOLID ridge beam, no ridge gap
}
// gable triangles (west/east ends)
for (var step2 = 0; step2 < halfD; step2++) {
for (var gz = hz1 + step2; gz <= hz2 - step2; gz++) {
pb(hx1, roofBaseY + step2, gz, wallPal(hx1, roofBaseY + step2, gz));
pb(hx2, roofBaseY + step2, gz, wallPal(hx2, roofBaseY + step2, gz));
}
}
// ridge crest + two dormers for roof character
for (var rxx = hx1; rxx <= hx2; rxx += 1) {
if (rxx % 6 === 0) ps(rxx, roofBaseY + halfD, 28, 'deepslate_brick_wall');
}
function dormer(dx, dz, edge) {
var by = roofBaseY + 3;
fill(dx - 1, by, dz - 1, dx + 1, by + 2, dz + 1, 'air');
perim(dx - 1, dz - 1, dx + 1, dz + 1, by, by + 1, 'spruce_planks');
fill(dx, by, dz, dx, by + 1, dz, 'glass_pane');
roofStair(dx - 1, by + 2, dz, 'spruce_stairs', 'west');
roofStair(dx + 1, by + 2, dz, 'spruce_stairs', 'east');
pb(dx, by + 2, dz, 'spruce_planks');
pb(dx, by + 2, dz - 1, 'spruce_slab[type=top]');
pb(dx, by + 2, dz + 1, 'spruce_slab[type=top]');
}
dormer(24, hz1 + 2, 'north'); dormer(35, hz1 + 2, 'north');
// chimney — moved OUTSIDE the west gable (it was sitting on the mezzanine stair column)
fill(16, padY, 26, 17, roofBaseY + 7, 27, 'cobblestone');
fill(16, roofBaseY + 8, 26, 17, roofBaseY + 8, 27, 'stone_brick_slab[type=top]');
pb(16, roofBaseY + 8, 26, 'campfire[lit=true]');
// corbelled shoulders where the stack meets the gable (facade depth)
fill(17, walkY + 4, 26, 18, walkY + 4, 27, 'stone_brick_slab[type=top]');
fill(17, walkY + 8, 26, 18, walkY + 8, 27, 'stone_brick_slab[type=top]');
// keep the stair column clear of clutter
fill(19, walkY, 23, 21, mezzFloorY - 1, 27, 'air');
// === STRUCTURE : MALT KILN TOWER (pagoda) ===
var kx1 = 40, kx2 = 48, kz1 = 24, kz2 = 32;
var kTopY = 26;
fill(kx1, padY - 2, kz1, kx2, floorY - 1, kz2, 'cobblestone');
fill(kx1, floorY, kz1, kx2, floorY, kz2, floorPal);
perim(kx1, kz1, kx2, kz2, floorY, floorY + 2, basePal);
perim(kx1, kz1, kx2, kz2, floorY + 3, kTopY, wallPal);
fill(kx1 + 1, walkY, kz1 + 1, kx2 - 1, kTopY + 10, kz2 - 1, 'air');
fill(kx1 + 1, floorY, kz1 + 1, kx2 - 1, floorY, kz2 - 1, floorPal);
// quoins on the tower corners
fill(kx1, floorY, kz1, kx1, kTopY, kz1, 'stone_bricks');
fill(kx2, floorY, kz1, kx2, kTopY, kz1, 'stone_bricks');
fill(kx1, floorY, kz2, kx1, kTopY, kz2, 'stone_bricks');
fill(kx2, floorY, kz2, kx2, kTopY, kz2, 'stone_bricks');
// tower slit windows
for (var wy = walkY + 3; wy <= kTopY - 3; wy += 4) {
fill(kx2, wy, 27, kx2, wy + 1, 29, 'glass_pane');
fill(43, wy, kz1, 45, wy + 1, kz1, 'glass_pane');
fill(43, wy, kz2, 45, wy + 1, kz2, 'glass_pane');
}
// kiln outer door (east) with arch
fill(kx2, walkY, 43 - 15, kx2, walkY + 2, 43 - 15, 'air');
fill(kx2, walkY, 27, kx2, walkY + 2, 29, 'air');
ps(kx2, walkY, 28, 'spruce_door[facing=west,half=lower,hinge=left]');
ps(kx2, walkY + 1, 28, 'spruce_door[facing=west,half=upper,hinge=left]');
pb(kx2, walkY, 27, 'stone_bricks'); pb(kx2, walkY, 29, 'stone_bricks');
ps(kx2, walkY + 3, 27, 'stone_brick_stairs[facing=east,half=top]');
ps(kx2, walkY + 3, 29, 'stone_brick_stairs[facing=east,half=top]');
// internal doorway still house <-> kiln
fill(kx1, walkY, 27, kx1, walkY + 2, 29, 'air');
pb(kx1, walkY + 3, 27, 'stone_bricks'); pb(kx1, walkY + 3, 29, 'stone_bricks');
pb(kx1, walkY + 3, 28, 'stone_brick_slab[type=top]');
// pagoda tiers
function pagodaTier(x1, z1, x2, z2, baseY, steps, matFn) {
for (var s = 0; s < steps; s++) {
var ax1 = x1 + s, ax2 = x2 - s, az1 = z1 + s, az2 = z2 - s, y = baseY + s;
for (var tx = ax1; tx <= ax2; tx++) {
roofStair(tx, y, az1, matFn(tx, 0, az1), 'north');
roofStair(tx, y, az2, matFn(tx, 0, az2), 'south');
}
for (var tz = az1 + 1; tz <= az2 - 1; tz++) {
roofStair(ax1, y, tz, matFn(ax1, 0, tz), 'west');
roofStair(ax2, y, tz, matFn(ax2, 0, tz), 'east');
}
}
fill(x1 + steps, baseY + steps - 1, z1 + steps, x2 - steps, baseY + steps - 1, z2 - steps, 'deepslate_tiles');
}
// lower tier (big eaves over the tower)
pagodaTier(kx1 - 2, kz1 - 2, kx2 + 2, kz2 + 2, kTopY + 1, 4, slatePal);
// second stage of the tower
fill(kx1 + 2, kTopY + 4, kz1 + 2, kx2 - 2, 32, kz2 - 2, 'air');
perim(kx1 + 2, kz1 + 2, kx2 - 2, kz2 - 2, kTopY + 4, 32, wallPal);
fill(kx1 + 2, kTopY + 4, kz1 + 2, kx1 + 2, 32, kz1 + 2, 'stone_bricks');
fill(kx2 - 2, kTopY + 4, kz1 + 2, kx2 - 2, 32, kz1 + 2, 'stone_bricks');
fill(kx1 + 2, kTopY + 4, kz2 - 2, kx1 + 2, 32, kz2 - 2, 'stone_bricks');
fill(kx2 - 2, kTopY + 4, kz2 - 2, kx2 - 2, 32, kz2 - 2, 'stone_bricks');
fill(44, 31, kz1 + 2, 44, 31, kz2 - 2, 'spruce_trapdoor[facing=north,half=top,open=false]');
// upper tier
pagodaTier(kx1 + 1, kz1 + 1, kx2 - 1, kz2 - 1, 33, 3, slatePal);
// cowl / vane
fill(43, 36, 27, 45, 36, 29, 'deepslate_tiles');
makeCylinder(44, 37, 28, 'waxed_exposed_copper', 1, 2, true);
pb(44, 39, 28, 'waxed_copper_block');
pb(44, 40, 28, 'lightning_rod');
// === INTERIOR : STILL ROOM ===
// ceiling beams
for (var bx = hx1 + 2; bx <= hx2 - 2; bx += 4) {
fill(bx, wallTopY - 1, hz1 + 1, bx, wallTopY - 1, hz2 - 1, 'spruce_log[axis=z]');
}
// three copper pot stills
function potStill(cx2, cz2) {
fill(cx2 - 2, floorY, cz2 - 2, cx2 + 2, floorY, cz2 + 2, 'polished_andesite');
makeCylinder(cx2, walkY, cz2, 'bricks', 2, 1, true);
ps(cx2, walkY, cz2 + 2, 'campfire[lit=true]');
makeCylinder(cx2, walkY + 1, cz2, copperPal, 2, 3, true);
makeCylinder(cx2, walkY + 4, cz2, copperPal, 1, 3, true);
pb(cx2, walkY + 7, cz2, 'waxed_cut_copper');
// swan neck + lyne arm toward the north wall
pb(cx2, walkY + 8, cz2, 'waxed_copper_block');
pb(cx2, walkY + 8, cz2 - 1, 'waxed_copper_block');
pb(cx2, walkY + 7, cz2 - 2, 'waxed_exposed_copper');
pb(cx2, walkY + 6, cz2 - 2, 'waxed_exposed_copper');
pb(cx2, walkY + 5, cz2 - 2, 'copper_bulb[lit=true]');
// hoops
makeCylinder(cx2, walkY + 2, cz2, 'waxed_oxidized_cut_copper', 2, 1, false);
}
potStill(26, 26); potStill(31, 26); potStill(36, 26);
// spirit safe + workbench along the north wall
pb(22, walkY, hz1 + 1, 'stripped_spruce_log');
ps(22, walkY + 1, hz1 + 1, 'glass');
pb(23, walkY, hz1 + 1, 'stripped_spruce_log');
ps(23, walkY + 1, hz1 + 1, 'brewing_stand');
pb(24, walkY, hz1 + 1, 'barrel[facing=up]');
ps(24, walkY + 1, hz1 + 1, 'cauldron[level=0]');
pb(22, wallTopY - 2, hz1 + 1, 'chain[axis=y]'); ps(22, wallTopY - 3, hz1 + 1, 'lantern[hanging=true]');
// mezzanine floor + posts + railing (built BEFORE the staircase so it cuts its own hole)
fill(hx1 + 1, mezzFloorY, 28, hx2 - 1, mezzFloorY, hz2 - 1, 'spruce_planks');
for (var mx = hx1 + 2; mx <= hx2 - 2; mx += 4) {
for (var mz = 29; mz <= hz2 - 2; mz += 4) {
fill(mx, walkY, mz, mx, mezzFloorY - 1, mz, 'spruce_log[axis=y]');
}
}
for (var rx2 = hx1 + 1; rx2 <= hx2 - 1; rx2++) {
if (rx2 < 19 || rx2 > 21) pb(rx2, mezzWalkY, 28, 'spruce_fence');
}
// staircase to the mezzanine (guaranteed navigable)
staircase(20, 24, walkY, mezzWalkY, 'south', {material: 'spruce_stairs', rail: 'spruce_fence'});
// mezzanine: casks, desk, rug, light
for (var cxx = 24; cxx <= 38; cxx += 3) {
pb(cxx, mezzWalkY, 31, 'barrel[facing=up]');
pb(cxx, mezzWalkY + 1, 31, 'barrel[facing=up]');
pb(cxx + 1, mezzWalkY, 31, 'barrel[facing=up]');
}
rug(29, mezzWalkY, 32, 4, 2, 'brown', 'red');
pb(33, mezzWalkY, 33, 'spruce_fence'); pb(33, mezzWalkY + 1, 33, 'spruce_pressure_plate');
ps(34, mezzWalkY, 33, 'lectern[facing=west]');
chairStair(32, mezzWalkY, 33, 'spruce_stairs', 'east');
pb(30, wallTopY - 1, 32, 'chain[axis=y]'); ps(30, wallTopY - 2, 32, 'lantern[hanging=true]');
pb(37, wallTopY - 1, 32, 'chain[axis=y]'); ps(37, wallTopY - 2, 32, 'lantern[hanging=true]');
// ground floor cask racks under the mezzanine + tools
for (var kxx = 23; kxx <= 37; kxx += 4) {
pb(kxx, walkY, hz2 - 1, 'oak_log[axis=x]'); pb(kxx + 1, walkY, hz2 - 1, 'oak_log[axis=x]');
pb(kxx, walkY + 1, hz2 - 1, 'barrel[facing=up]'); pb(kxx + 1, walkY + 1, hz2 - 1, 'barrel[facing=up]');
pb(kxx, walkY, hz2 - 2, 'oak_slab[type=bottom]');
}
ps(19, walkY, 32, 'cauldron[level=3]');
pb(19, walkY, 31, 'barrel[facing=up]');
pb(21, walkY, hz2 - 1, 'crafting_table');
rug(27, walkY, 30, 5, 3, 'gray', 'light_gray');
// ground lighting
for (var lx = 23; lx <= 38; lx += 5) {
pb(lx, wallTopY - 1, 24, 'chain[axis=y]');
ps(lx, wallTopY - 2, 24, 'lantern[hanging=true]');
}
// === INTERIOR : MALT KILN ===
fill(42, floorY, 26, 46, floorY, 30, 'stone_bricks');
fill(43, walkY, 27, 45, walkY, 29, 'iron_bars'); // drying floor grate
ps(44, walkY - 1, 28, 'campfire[lit=true]');
fill(42, walkY, 26, 42, walkY, 30, 'hay_block');
pb(46, walkY, 26, 'barrel[facing=up]'); pb(46, walkY, 30, 'barrel[facing=up]');
pb(46, walkY, 28, 'composter');
pb(44, walkY + 5, 28, 'chain[axis=y]'); ps(44, walkY + 4, 28, 'lantern[hanging=true]');
pb(41, walkY, 26, 'hay_block'); pb(41, walkY + 1, 26, 'hay_block');
ps(41, walkY, 30, 'ladder[facing=east]');
// === EXTERIOR : YARD, WALL, LANDSCAPE ===
// path to the front door
for (var qz = 12; qz <= 21; qz++) {
for (var qx = 27; qx <= 30; qx++) {
pb(qx, Math.floor(groundH(qx, qz)), qz, noisePalette([{block: 'gravel', weight: 45}, {block: 'cobblestone', weight: 35}, {block: 'andesite', weight: 20}], {seed: 6})(qx, 0, qz));
}
}
// low mossy stone wall around the yard
function yardWall(x1, z1, x2, z2) {
var i;
for (i = x1; i <= x2; i++) {
pb(i, Math.floor(groundH(i, z1)) + 1, z1, 'mossy_cobblestone_wall');
pb(i, Math.floor(groundH(i, z2)) + 1, z2, 'mossy_cobblestone_wall');
}
for (i = z1; i <= z2; i++) {
pb(x1, Math.floor(groundH(x1, i)) + 1, i, 'mossy_cobblestone_wall');
pb(x2, Math.floor(groundH(x2, i)) + 1, i, 'mossy_cobblestone_wall');
}
}
yardWall(14, 14, 56, 50);
// gate gap on the path
fill(27, padY, 14, 30, padY + 2, 14, 'air');
pb(26, padY + 1, 14, 'mossy_cobblestone_wall'); pb(31, padY + 1, 14, 'mossy_cobblestone_wall');
pb(26, padY + 2, 14, 'stone_brick_slab[type=bottom]'); pb(31, padY + 2, 14, 'stone_brick_slab[type=bottom]');
// === STRUCTURE : CASK STORE (detached) ===
var sx1 = 20, sx2 = 30, sz1 = 38, sz2 = 46;
fill(sx1 - 1, padY - 2, sz1 - 1, sx2 + 1, padY, sz2 + 1, 'cobblestone');
fill(sx1, padY + 1, sz1, sx2, padY + 1, sz2, floorPal);
var sFloorY = padY + 1, sWalkY = sFloorY + 1, sTopY = sFloorY + 5;
perim(sx1, sz1, sx2, sz2, sFloorY, sFloorY + 1, basePal);
perim(sx1, sz1, sx2, sz2, sFloorY + 2, sTopY, wallPal);
fill(sx1 + 1, sWalkY, sz1 + 1, sx2 - 1, sTopY + 6, sz2 - 1, 'air');
fill(sx1 + 1, sFloorY, sz1 + 1, sx2 - 1, sFloorY, sz2 - 1, floorPal);
// timber frame for wall depth
for (var fx = sx1; fx <= sx2; fx += 2) {
fill(fx, sFloorY + 2, sz1, fx, sTopY, sz1, 'dark_oak_log[axis=y]');
fill(fx, sFloorY + 2, sz2, fx, sTopY, sz2, 'dark_oak_log[axis=y]');
}
// door + windows
fill(25, sWalkY, sz1, 25, sWalkY + 1, sz1, 'air');
ps(25, sWalkY, sz1, 'dark_oak_door[facing=south,half=lower,hinge=left]');
ps(25, sWalkY + 1, sz1, 'dark_oak_door[facing=south,half=upper,hinge=left]');
fill(22, sWalkY + 1, sz1, 22, sWalkY + 2, sz1, 'glass_pane');
fill(28, sWalkY + 1, sz1, 28, sWalkY + 2, sz1, 'glass_pane');
// shed roof (gable, ridge along X)
var sHalf = 5;
for (var ux = sx1 - 1; ux <= sx2 + 1; ux++) {
for (var us = 0; us < sHalf; us++) {
roofStair(ux, sTopY + 1 + us, sz1 - 1 + us, slatePal(ux, 0, sz1 + us), 'north');
roofStair(ux, sTopY + 1 + us, sz2 + 1 - us, slatePal(ux, 0, sz2 - us), 'south');
}
pb(ux, sTopY + 1 + sHalf - 1, 42, 'deepslate_tiles');
}
for (var us2 = 0; us2 < sHalf; us2++) {
for (var ugz = sz1 + us2; ugz <= sz2 - us2; ugz++) {
pb(sx1, sTopY + 1 + us2, ugz, wallPal(sx1, sTopY + 1 + us2, ugz));
pb(sx2, sTopY + 1 + us2, ugz, wallPal(sx2, sTopY + 1 + us2, ugz));
}
}
// cask store interior
for (var bz = sz1 + 2; bz <= sz2 - 2; bz += 3) {
for (var bx2 = sx1 + 2; bx2 <= sx2 - 2; bx2 += 3) {
pb(bx2, sWalkY, bz, 'oak_log[axis=x]'); pb(bx2 + 1, sWalkY, bz, 'oak_log[axis=x]');
pb(bx2, sWalkY + 1, bz, 'barrel[facing=up]'); pb(bx2 + 1, sWalkY + 1, bz, 'barrel[facing=up]');
}
}
pb(25, sTopY - 1, 42, 'chain[axis=y]'); ps(25, sTopY - 2, 42, 'lantern[hanging=true]');
pb(22, sWalkY, sz2 - 1, 'cartography_table');
// === DETAILS : yard props, lights, greenery ===
lampPost(26, padY + 1, 18, 4, 'cobblestone_wall');
lampPost(32, padY + 1, 18, 4, 'cobblestone_wall');
lampPost(35, padY + 1, 38, 4, 'cobblestone_wall');
lampPost(18, padY + 1, 36, 4, 'cobblestone_wall');
// outdoor cask stack pyramid
for (var oy = 0; oy < 3; oy++) {
for (var oxx = 34 + oy; oxx <= 42 - oy; oxx += 2) {
pb(oxx, padY + 1 + oy, 40, 'barrel[facing=up]');
pb(oxx, padY + 1 + oy, 42, 'barrel[facing=up]');
}
}
pb(36, padY + 1, 44, 'cauldron[level=2]');
pb(38, padY + 1, 44, 'oak_log[axis=x]');
// vegetation
try {
placeTree(20, padY + 1, 20, 'spruce');
placeTree(50, padY + 1, 22, 'spruce');
placeTree(52, padY + 1, 44, 'oak');
placeTree(16, padY + 1, 46, 'spruce');
} catch (e) { }
for (var vx = 12; vx <= 56; vx++) {
for (var vz = 12; vz <= 52; vz++) {
var n = noise2d('perlin', vx * 1.7, vz * 1.7, {seed: 12});
var gy = Math.floor(groundH(vx, vz));
if (n > 0.86 && (vx < 17 || vx > 50 || vz < 20 || vz > 47)) {
var pick = n > 0.94 ? 'fern' : (n > 0.9 ? 'grass' : 'moss_carpet');
pb(vx, gy + 1, vz, pick);
}
}
}
// riverside mossy rocks
for (var mrx = 10; mrx <= 20; mrx += 3) {
makeSphere(mrx, padY, 20 + (mrx % 7) * 4, noisePalette([{block: 'mossy_cobblestone', weight: 60}, {block: 'stone', weight: 25}, {block: 'andesite', weight: 15}], {seed: 8}), 2, true);
}