// === BUILD PLAN ===
// Style: North-German / Hanseatic BRICK GOTHIC warehouse-house (Speicher) on a canal quay
// Footprint: L-shape. Main store block 13x15 (x18-30, z30-44) + counting-house wing 9x10 (x30-38, z35-44)
// Height: floor Y7, ground walk Y8, loft floor Y13, loft walk Y14, wall top Y19, ridge Y26, crow-gable finial Y28
// Facade faces +Z (the canal) as required for the isometric/front camera.
//
// GROUND FLOOR (top-down, 1 char = 1 block, +Z downward = toward canal):
// x18 x30 x38
// ############### (z30 back wall)
// #CC W#
// #CC store #
// # # (z35) ##########
// # hall # # count #
// W W==========D ing W
// # S # # house #
// # S W # #
// #WW DD WW ##WW DD WW######### (z44 quay facade)
// Legend: # brick wall, W arched window, D door, S staircase up, C chimney/hearth
//
// FRONT ELEVATION (crow-stepped gable, hoist beam at peak):
// _|_ <- finial + hoist beam over the quay
// |###|
// |#######|
// |###########|
// |## W W ##| <- gable windows
// |###############|
// | W [HOIST] W | <- loft hoist doors + arched windows (string course under)
// |=================| <- white diorite string course
// | W [DOOR] W | <- ground arched windows + arched door
// |###|###|###|###| <- proud brick pilasters at z45
// ~~~~ cobbled quay ~~~~ bollards ~~~~ water
//
// MATERIALS PLAN (palette by VOLUME — gradient for age/height, white stone for CONTRAST):
// walls : gradientPalette mud_bricks(low, weathered) -> bricks -> granite(high, sun-bleached), noise .22
// WHY: a red-brick value ramp fakes ambient occlusion on a tall flat warehouse face
// plinth : noisePalette cobble/mossy/andesite/stone_bricks — WHY: wet, mossy base at the waterline
// trim : polished_diorite string course + crow-step treads — WHY: the signature white-on-red contrast
// roof : noisePalette brick_stairs(50)/granite_stairs(28)/mud_brick_stairs(22) fed per-stair so facing survives
// floors : spruce plank noise (ground), oak plank noise (loft)
// quay : cobble/mossy/andesite/gravel noise
// Rooms: Store hall (counter, hearth, crates, barrels, table, shelves), Loft (sacks, barrels, hoist, ledger),
// Counting house wing (desk, lectern, bookshelves, hearthless but lit, rug)
// STAIR PLAN: delta = 14-8 = 6 -> staircase(28, 33, 8, 14, 'south') = single 7-cell flush run, width 2, inside the hall
// PROCESS: LAYERED (placeholder blue_wool form -> mask-hollow -> mask-carve openings -> replaceMasked texture -> glaze)
// === END PLAN ===
var padY = 6, floorY = 7, walkY = 8, f2Y = 13, walk2Y = 14, wallTopY = 19, roofBaseY = 20;
var X1 = 18, X2 = 30, Z1 = 30, Z2 = 44;
var WX1 = 30, WX2 = 38, WZ1 = 35, WZ2 = 44, wTopY = 13, wRoofY = 14, wHalf = 5;
var CX = 24, HALF = 7;
var PH = 'blue_wool';
// ---------- PALETTES ----------
var wallPat = gradientPalette(floorY, wallTopY, [
{ block: 'mud_bricks', from: 0 },
{ block: 'bricks', from: 0.30 },
{ block: 'granite', from: 0.82 }
], { noise: 0.22 });
var plinthPat = noisePalette([
{ block: 'cobblestone', weight: 38 }, { block: 'mossy_cobblestone', weight: 24 },
{ block: 'andesite', weight: 20 }, { block: 'stone_bricks', weight: 18 }
], { freq: 0.18 });
var rmat = noisePalette([
{ block: 'brick_stairs', weight: 50 }, { block: 'granite_stairs', weight: 28 },
{ block: 'mud_brick_stairs', weight: 22 }
], { freq: 0.14 });
var gablePat = noisePalette([
{ block: 'bricks', weight: 60 }, { block: 'mud_bricks', weight: 22 }, { block: 'granite', weight: 18 }
], { freq: 0.15 });
var floorPat = noisePalette([
{ block: 'spruce_planks', weight: 60 }, { block: 'stripped_spruce_wood', weight: 25 },
{ block: 'dark_oak_planks', weight: 15 }
], { freq: 0.2 });
var loftPat = noisePalette([
{ block: 'oak_planks', weight: 62 }, { block: 'stripped_oak_wood', weight: 23 },
{ block: 'spruce_planks', weight: 15 }
], { freq: 0.2 });
var quayPat = noisePalette([
{ block: 'cobblestone', weight: 36 }, { block: 'mossy_cobblestone', weight: 22 },
{ block: 'andesite', weight: 18 }, { block: 'stone_bricks', weight: 14 }, { block: 'gravel', weight: 10 }
], { freq: 0.16 });
// ---------- 1. TERRAIN (superpowers, flat pad captured) ----------
var land = zoneRect(0, 0, 63, 49);
var h = hills({ base: padY, amp: 2, scale: 0.05, seed: 9 });
var pad = flatten(h, { x0: 6, z0: 22, x1: 50, z1: 49 }, padY, 7);
var gmat = patches([{ block: 'grass_block', w: 70 }, { block: 'coarse_dirt', w: 18 }, { block: 'podzol', w: 12 }], 0.06, 4);
fill(0, 0, 0, 63, padY - 3, 49, 'stone');
surface(land, pad, gmat, { sub: 'dirt', deep: 'stone', depth: 5 });
// canal
fill(0, 0, 50, 63, 1, 63, 'gravel');
fill(0, 2, 50, 63, 4, 63, 'water');
// masonry quay revetment + cobbled quay top
fill(0, 0, 45, 63, padY, 49, 'stone_bricks');
fill(0, 4, 49, 63, padY, 49, 'mossy_stone_bricks');
fill(0, padY, 45, 63, padY, 49, quayPat);
// ---------- 2. FORM IN PLACEHOLDERS (LAYERED step 1) ----------
fill(X1, floorY, Z1, X2, wallTopY, Z2, PH);
fill(WX1, floorY, WZ1, WX2, wTopY, WZ2, PH);
// ---------- 3. HOLLOW BY MASK (never touches anything but the placeholder) ----------
clearMasked(X1 + 1, floorY, Z1 + 1, X2 - 1, wallTopY, Z2 - 1, onlyMaterial(PH));
clearMasked(WX1 + 1, floorY, WZ1 + 1, WX2 - 1, wTopY, WZ2 - 1, onlyMaterial(PH));
// floors
fill(X1 + 1, floorY, Z1 + 1, X2 - 1, floorY, Z2 - 1, floorPat);
fill(X1 + 1, f2Y, Z1 + 1, X2 - 1, f2Y, Z2 - 1, loftPat);
fill(WX1 + 1, floorY, WZ1 + 1, WX2 - 1, floorY, WZ2 - 1, floorPat);
// ---------- 4. CARVE OPENINGS BY MASK (wall only) ----------
function carveX(xp, y, z0, z1) { clearMasked(xp, y, z0, xp, y + 2, z1, onlyMaterial(PH)); }
function carveZ(zp, y, x0, x1) { clearMasked(x0, y, zp, x1, y + 2, zp, onlyMaterial(PH)); }
var gy = walkY + 1, ly = walk2Y + 1; // 9 and 15 - irregular rows, clear of the Y13 string course
// FRONT facade (z44): ground windows + door, loft windows + hoist doors
carveZ(Z2, walkY, 23, 24); // main door 2w x 3h
carveZ(Z2, gy, 20, 21); carveZ(Z2, gy, 27, 28);
carveZ(Z2, walk2Y, 23, 24); // hoist doors
carveZ(Z2, ly, 20, 20); carveZ(Z2, ly, 27, 28);
// WEST wall (x18) - deliberately irregular rows
carveX(X1, gy, 33, 34); carveX(X1, gy, 39, 40); carveX(X1, gy + 1, 36, 36);
carveX(X1, ly, 32, 33); carveX(X1, ly, 38, 39); carveX(X1, ly - 1, 42, 42);
// EAST wall (x30) - only the stretch not covered by the wing
carveX(X2, gy, 32, 33); carveX(X2, ly, 32, 33);
// BACK wall (z30)
carveZ(Z1, gy, 21, 22); carveZ(Z1, gy, 26, 27); carveZ(Z1, ly, 23, 24);
// connecting doorway main <-> wing
clearMasked(X2, walkY, 41, X2, walkY + 1, 41, onlyMaterial(PH));
// WING openings
carveZ(WZ2, walkY, 34, 35); // wing door
carveZ(WZ2, gy, 31, 32); carveZ(WZ2, gy, 37, 37);
carveX(WX2, gy, 38, 39); carveX(WX2, gy, 41, 42);
carveZ(WZ1, gy, 33, 34);
// ---------- 5. TEXTURE LAST (placeholder -> real palette) ----------
replaceMasked(X1, floorY, Z1, X2, wallTopY, Z2, wallPat, onlyMaterial(PH));
replaceMasked(WX1, floorY, WZ1, WX2, wTopY, WZ2, wallPat, onlyMaterial(PH));
// ---------- 6. WALL DEPTH: plinth, pilasters, string course, cornice ----------
function ring(y, x1, z1, x2, z2, blk) {
fill(x1, y, z1, x2, y, z1, blk); fill(x1, y, z2, x2, y, z2, blk);
fill(x1, y, z1, x1, y, z2, blk); fill(x2, y, z1, x2, y, z2, blk);
}
// 2-row mossy plinth, proud by 1 block all round the main block
var px, pz;
for (px = X1 - 1; px <= X2 + 1; px++) {
for (pz = Z1 - 1; pz <= Z2 + 1; pz++) {
if (px === X1 - 1 || px === X2 + 1 || pz === Z1 - 1 || pz === Z2 + 1) {
if (px >= WX1 && pz >= WZ1 - 1) continue; // skip where the wing sits
fill(px, floorY, pz, px, floorY + 1, pz, plinthPat);
}
}
}
ring(floorY, X1, Z1, X2, Z2, plinthPat);
ring(floorY + 1, X1, Z1, X2, Z2, plinthPat);
ring(floorY, WX1, WZ1, WX2, WZ2, plinthPat);
ring(floorY + 1, WX1, WZ1, WX2, WZ2, plinthPat);
// white string course under the loft + cornice under the eaves
ring(f2Y, X1, Z1, X2, Z2, 'polished_diorite');
ring(wallTopY, X1, Z1, X2, Z2, 'polished_diorite');
ring(wTopY, WX1, WZ1, WX2, WZ2, 'polished_diorite');
// proud brick pilasters (lesenes) on the facade + west flank
var pil = [18, 21, 26, 30], pi, py;
for (pi = 0; pi < pil.length; pi++) {
for (py = padY + 1; py <= wallTopY; py++) pb(pil[pi], py, Z2 + 1, 'bricks');
ps(pil[pi], wallTopY + 1, Z2 + 1, 'polished_diorite_slab[type=bottom]');
}
var wz = [33, 37, 41];
for (pi = 0; pi < wz.length; pi++) {
for (py = floorY + 2; py <= wallTopY - 1; py++) pb(X1 - 1, py, wz[pi], 'bricks');
ps(X1 - 1, wallTopY, wz[pi], 'polished_diorite_slab[type=bottom]');
}
// ---------- 7. ROOF (direct, palette fed per stair so facing survives) ----------
var z, s, x;
for (z = Z1 - 1; z <= Z2 - 1; z++) {
for (s = 0; s < HALF; s++) {
roofStair(X1 - 1 + s, roofBaseY + s, z, rmat(X1 - 1 + s, 0, z), 'west');
roofStair(X2 + 1 - s, roofBaseY + s, z, rmat(X2 + 1 - s, 0, z), 'east');
}
pb(CX, roofBaseY + HALF - 1, z, 'bricks'); // SOLID ridge beam - no ridge gap
}
// back gable triangle (z30) filled solid
for (s = 0; s < HALF; s++) fill(X1 + s, roofBaseY + s, Z1, X2 - s, roofBaseY + s, Z1, gablePat);
// FRONT CROW-STEPPED GABLE (z44) with white diorite treads
for (s = 0; s < HALF; s++) {
fill(X1 + s, roofBaseY + s, Z2, X2 - s, roofBaseY + s, Z2, gablePat);
ps(X1 + s, roofBaseY + s + 1, Z2, 'polished_diorite_slab[type=bottom]');
ps(X2 - s, roofBaseY + s + 1, Z2, 'polished_diorite_slab[type=bottom]');
}
pb(CX, roofBaseY + HALF, Z2, 'polished_diorite');
pb(CX, roofBaseY + HALF + 1, Z2, 'brick_wall');
// gable roundel windows
ps(22, roofBaseY + 2, Z2, 'brown_stained_glass'); ps(26, roofBaseY + 2, Z2, 'brown_stained_glass');
ps(CX, roofBaseY + 4, Z2, 'brown_stained_glass');
// WING roof (ridge along X, slopes N/S)
for (x = WX1 + 1; x <= WX2 + 1; x++) {
for (s = 0; s < wHalf; s++) {
roofStair(x, wRoofY + s, WZ1 - 1 + s, rmat(x, 0, WZ1 - 1 + s), 'north');
roofStair(x, wRoofY + s, WZ2 + 1 - s, rmat(x, 0, WZ2 + 1 - s), 'south');
}
pb(x, wRoofY + wHalf - 1, 39, 'bricks');
pb(x, wRoofY + wHalf - 1, 40, 'bricks');
}
for (s = 0; s < wHalf; s++) fill(WX2, wRoofY + s, WZ1 + s, WX2, wRoofY + s, WZ2 - s, gablePat);
// ---------- 8. CHIMNEY (pierces the roof) + HEARTH ----------
fill(20, floorY, 31, 21, 30, 32, 'bricks');
ring(28, 20, 31, 21, 32, 'polished_diorite');
ps(20, 31, 31, 'brick_wall'); ps(21, 31, 32, 'brick_wall');
// firebox facing +Z
fill(20, walkY, 31, 21, walkY + 1, 32, 'air');
fill(20, walkY - 1, 31, 21, walkY - 1, 32, 'netherrack');
ps(20, walkY, 31, 'campfire[lit=true,facing=south]');
ps(21, walkY, 31, 'campfire[lit=true,facing=south]');
ps(20, walkY + 2, 32, 'brick_stairs[facing=south,half=top]');
ps(21, walkY + 2, 32, 'brick_stairs[facing=south,half=top]');
fill(20, walkY + 2, 31, 21, 27, 31, 'air'); // flue
// ---------- 9. GLAZE + ARCH HEADS ----------
function glazeZ(zp, y, x0, x1, pane, stairId) {
fillMasked(x0, y, zp, x1, y + 1, zp, pane, onlyAir());
ps(x0, y + 2, zp, stairId + '[facing=east,half=top]');
ps(x1, y + 2, zp, stairId + '[facing=west,half=top]');
var xx; for (xx = x0 + 1; xx <= x1 - 1; xx++) ps(xx, y + 2, zp, 'brick_slab[type=top]');
}
function glazeX(xp, y, z0, z1, pane, stairId) {
fillMasked(xp, y, z0, xp, y + 1, z1, pane, onlyAir());
ps(xp, y + 2, z0, stairId + '[facing=south,half=top]');
ps(xp, y + 2, z1, stairId + '[facing=north,half=top]');
var zz; for (zz = z0 + 1; zz <= z1 - 1; zz++) ps(xp, y + 2, zz, 'brick_slab[type=top]');
}
var PANE = 'brown_stained_glass_pane';
glazeZ(Z2, gy, 20, 21, PANE, 'brick_stairs'); glazeZ(Z2, gy, 27, 28, PANE, 'brick_stairs');
glazeZ(Z2, ly, 20, 20, PANE, 'brick_stairs'); glazeZ(Z2, ly, 27, 28, PANE, 'brick_stairs');
glazeX(X1, gy, 33, 34, PANE, 'brick_stairs'); glazeX(X1, gy, 39, 40, PANE, 'brick_stairs');
glazeX(X1, gy + 1, 36, 36, PANE, 'brick_stairs');
glazeX(X1, ly, 32, 33, PANE, 'brick_stairs'); glazeX(X1, ly, 38, 39, PANE, 'brick_stairs');
glazeX(X1, ly - 1, 42, 42, PANE, 'brick_stairs');
glazeX(X2, gy, 32, 33, PANE, 'brick_stairs'); glazeX(X2, ly, 32, 33, PANE, 'brick_stairs');
glazeZ(Z1, gy, 21, 22, PANE, 'brick_stairs'); glazeZ(Z1, gy, 26, 27, PANE, 'brick_stairs');
glazeZ(Z1, ly, 23, 24, PANE, 'brick_stairs');
glazeZ(WZ2, gy, 31, 32, PANE, 'brick_stairs'); glazeZ(WZ2, gy, 37, 37, PANE, 'brick_stairs');
glazeX(WX2, gy, 38, 39, PANE, 'brick_stairs'); glazeX(WX2, gy, 41, 42, PANE, 'brick_stairs');
glazeZ(WZ1, gy, 33, 34, PANE, 'brick_stairs');
// doors (arched heads)
ps(23, walkY, Z2, 'dark_oak_door[facing=south,half=lower,hinge=left]');
ps(23, walkY + 1, Z2, 'dark_oak_door[facing=south,half=upper,hinge=left]');
ps(24, walkY, Z2, 'dark_oak_door[facing=south,half=lower,hinge=right]');
ps(24, walkY + 1, Z2, 'dark_oak_door[facing=south,half=upper,hinge=right]');
ps(23, walkY + 2, Z2, 'brick_stairs[facing=east,half=top]');
ps(24, walkY + 2, Z2, 'brick_stairs[facing=west,half=top]');
ps(34, walkY, WZ2, 'spruce_door[facing=south,half=lower,hinge=left]');
ps(34, walkY + 1, WZ2, 'spruce_door[facing=south,half=upper,hinge=left]');
ps(35, walkY, WZ2, 'spruce_door[facing=south,half=lower,hinge=right]');
ps(35, walkY + 1, WZ2, 'spruce_door[facing=south,half=upper,hinge=right]');
ps(34, walkY + 2, WZ2, 'brick_stairs[facing=east,half=top]');
ps(35, walkY + 2, WZ2, 'brick_stairs[facing=west,half=top]');
// loft hoist doors (dark oak, shuttered)
ps(23, walk2Y, Z2, 'dark_oak_door[facing=south,half=lower,hinge=left]');
ps(23, walk2Y + 1, Z2, 'dark_oak_door[facing=south,half=upper,hinge=left]');
ps(24, walk2Y, Z2, 'dark_oak_door[facing=south,half=lower,hinge=right]');
ps(24, walk2Y + 1, Z2, 'dark_oak_door[facing=south,half=upper,hinge=right]');
ps(23, walk2Y + 2, Z2, 'brick_stairs[facing=east,half=top]');
ps(24, walk2Y + 2, Z2, 'brick_stairs[facing=west,half=top]');
// shutters beside the loft doors
ps(22, walk2Y + 1, Z2 + 1, 'dark_oak_trapdoor[facing=north,half=top,open=true]');
ps(25, walk2Y + 1, Z2 + 1, 'dark_oak_trapdoor[facing=north,half=top,open=true]');
// ---------- 10. HOIST BEAM + PULLEY ----------
ps(CX, roofBaseY + 5, Z2 + 1, 'spruce_log[axis=z]');
ps(CX, roofBaseY + 5, Z2 + 2, 'spruce_log[axis=z]');
ps(CX, roofBaseY + 5, Z2 + 3, 'spruce_log[axis=z]');
pb(CX, roofBaseY + 4, Z2 + 1, 'spruce_fence');
ps(CX, roofBaseY + 4, Z2 + 3, 'iron_chain[axis=y]');
ps(CX, roofBaseY + 3, Z2 + 3, 'iron_chain[axis=y]');
ps(CX, roofBaseY + 2, Z2 + 3, 'iron_chain[axis=y]');
ps(CX, roofBaseY + 1, Z2 + 3, 'iron_chain[axis=y]');
pb(CX, roofBaseY, Z2 + 3, 'barrel[facing=up]');
pb(CX - 1, roofBaseY, Z2 + 3, 'hay_block');
// ---------- 11. STAIRCASE BETWEEN FLOORS ----------
var top = staircase(28, 33, walkY, walk2Y, 'south', { width: 2, material: 'spruce_stairs', rail: true, support: 'stripped_spruce_log' });
// ---------- 12. GROUND FLOOR - THE STORE HALL ----------
rug(22, walkY, 35, 6, 5, 'brown', 'red');
// merchant's counter facing the door
var i;
for (i = 0; i < 4; i++) { pb(21 + i, walkY, 40, 'stripped_spruce_log'); ps(21 + i, walkY + 1, 40, 'spruce_stairs[facing=south,half=top]'); }
pb(25, walkY, 40, 'barrel[facing=north]');
ps(22, walkY + 1, 39, 'oak_wall_sign[facing=south]');
pb(23, f2Y - 1, 40, 'iron_chain[axis=y]'); ps(23, f2Y - 2, 40, 'lantern[hanging=true]');
// crates and sacks along the west wall
pb(19, walkY, 35, 'barrel[facing=up]'); pb(19, walkY + 1, 35, 'barrel[facing=up]');
pb(19, walkY, 36, 'chest[facing=east,type=single]');
pb(19, walkY, 38, 'hay_block'); pb(20, walkY, 38, 'hay_block'); pb(19, walkY + 1, 38, 'hay_block');
pb(19, walkY, 41, 'barrel[facing=up]'); pb(20, walkY, 41, 'barrel[facing=up]');
pb(19, walkY, 42, 'composter');
// big table + chairs in the middle
pb(24, walkY, 33, 'dark_oak_fence'); pb(25, walkY, 33, 'dark_oak_fence');
ps(24, walkY + 1, 33, 'dark_oak_pressure_plate'); ps(25, walkY + 1, 33, 'dark_oak_pressure_plate');
chairStair(24, walkY, 34, 'spruce_stairs', 'north'); chairStair(25, walkY, 34, 'spruce_stairs', 'north');
chairStair(26, walkY, 33, 'spruce_stairs', 'west');
ps(24, walkY + 2, 33, 'lantern');
// shelves + scales on the east side
shelfWall(27, walkY, 36, 'north', 4, 2);
pb(26, walkY, 31, 'cartography_table'); pb(27, walkY, 31, 'barrel[facing=up]');
pb(25, walkY, 31, 'cauldron[level=2]');
// lighting
pb(22, f2Y - 1, 34, 'iron_chain[axis=y]'); ps(22, f2Y - 2, 34, 'lantern[hanging=true]');
pb(27, f2Y - 1, 41, 'iron_chain[axis=y]'); ps(27, f2Y - 2, 41, 'lantern[hanging=true]');
ps(19, walkY + 2, 33, 'lantern');
// exposed ceiling beams
for (z = 32; z <= 42; z += 3) fill(19, f2Y - 1, z, 29, f2Y - 1, z, 'stripped_dark_oak_wood');
// ---------- 13. LOFT - SACKS AND BARRELS ----------
// sack stacks (hay bales) in rows
var lz;
for (lz = 31; lz <= 36; lz += 2) {
pb(19, walk2Y, lz, 'hay_block'); pb(20, walk2Y, lz, 'hay_block');
pb(19, walk2Y + 1, lz, 'hay_block');
pb(21, walk2Y, lz, 'barrel[facing=up]');
}
pb(22, walk2Y, 32, 'hay_block'); pb(22, walk2Y + 1, 32, 'hay_block'); pb(23, walk2Y, 32, 'hay_block');
// barrel pyramid
pb(26, walk2Y, 33, 'barrel[facing=up]'); pb(27, walk2Y, 33, 'barrel[facing=up]');
pb(26, walk2Y, 34, 'barrel[facing=up]'); pb(27, walk2Y, 34, 'barrel[facing=up]');
pb(26, walk2Y + 1, 33, 'barrel[facing=up]'); pb(27, walk2Y + 1, 34, 'barrel[facing=up]');
pb(28, walk2Y, 31, 'chest[facing=south,type=single]'); pb(27, walk2Y, 31, 'chest[facing=south,type=single]');
// loading area by the hoist doors
rug(22, walk2Y, 41, 4, 2, 'gray', 'brown');
pb(21, walk2Y, 42, 'barrel[facing=up]'); pb(26, walk2Y, 42, 'barrel[facing=up]');
pb(20, walk2Y, 40, 'hay_block'); pb(20, walk2Y + 1, 40, 'hay_block');
ps(25, walk2Y, 39, 'lectern[facing=west]');
chairStair(26, walk2Y, 39, 'spruce_stairs', 'west');
pb(27, walk2Y, 38, 'barrel[facing=up]');
// loft lighting on posts (never floats)
lampPost(19, walk2Y, 43, 2, 'oak_fence');
lampPost(29, walk2Y, 43, 2, 'oak_fence');
lampPost(19, walk2Y, 37, 2, 'oak_fence');
// rope coil + tools
ps(22, walk2Y, 43, 'iron_chain[axis=y]');
pb(29, walk2Y, 36, 'barrel[facing=up]');
// ---------- 14. COUNTING HOUSE WING ----------
rug(32, walkY, 38, 5, 4, 'red', 'orange');
shelfWall(31, walkY, 37, 'south', 5, 2);
ps(34, walkY, 37, 'lectern[facing=south]');
chairStair(34, walkY, 38, 'dark_oak_stairs', 'north');
pb(36, walkY, 37, 'dark_oak_fence'); pb(36, walkY + 1, 37, 'dark_oak_pressure_plate');
chairStair(37, walkY, 37, 'dark_oak_stairs', 'west');
pb(36, walkY, 42, 'chest[facing=north,type=single]'); pb(37, walkY, 42, 'barrel[facing=up]');
pb(32, walkY, 42, 'cartography_table'); pb(33, walkY, 42, 'barrel[facing=up]');
pb(34, wTopY - 1, 39, 'iron_chain[axis=y]'); ps(34, wTopY - 2, 39, 'lantern[hanging=true]');
pb(36, wTopY - 1, 41, 'iron_chain[axis=y]'); ps(36, wTopY - 2, 41, 'lantern[hanging=true]');
ps(31, walkY + 2, 40, 'lantern');
for (x = 31; x <= 37; x += 3) fill(x, wTopY - 1, 36, x, wTopY - 1, 43, 'stripped_dark_oak_wood');
// ---------- 15. QUAY, BOLLARDS, CARGO, VEGETATION ----------
var bx;
for (bx = 12; bx <= 48; bx += 6) {
pb(bx, padY + 1, 47, 'stripped_dark_oak_log[axis=y]');
ps(bx, padY + 2, 47, 'dark_oak_slab[type=bottom]');
}
// mooring posts standing in the water
for (bx = 20; bx <= 40; bx += 7) {
fill(bx, 2, 51, bx, 6, 51, 'stripped_spruce_log[axis=y]');
ps(bx, 7, 51, 'spruce_slab[type=bottom]');
}
// cargo waiting on the quay
pb(27, padY + 1, 46, 'barrel[facing=up]'); pb(28, padY + 1, 46, 'barrel[facing=up]');
pb(27, padY + 2, 46, 'barrel[facing=up]');
pb(20, padY + 1, 46, 'hay_block'); pb(21, padY + 1, 46, 'hay_block'); pb(20, padY + 2, 46, 'hay_block');
pb(32, padY + 1, 46, 'chest[facing=south,type=single]');
pb(40, padY + 1, 46, 'barrel[facing=up]'); pb(41, padY + 1, 46, 'hay_block');
// quay lamps
lampPost(16, padY + 1, 46, 4, 'cobblestone_wall');
lampPost(31, padY + 1, 46, 4, 'cobblestone_wall');
lampPost(45, padY + 1, 46, 4, 'cobblestone_wall');
// a moored lighter (flat barge) alongside
fill(33, 3, 51, 39, 3, 55, 'spruce_planks');
ring(4, 33, 51, 39, 55, 'spruce_planks');
ps(36, 4, 51, 'spruce_stairs[facing=north,half=bottom]');
pb(35, 4, 53, 'barrel[facing=up]'); pb(36, 4, 53, 'hay_block'); pb(37, 4, 53, 'barrel[facing=up]');
pb(34, 4, 54, 'oak_fence'); ps(34, 5, 54, 'lantern');
// vegetation + weathering
ps(19, padY + 1, 45, 'potted_azure_bluet'); ps(29, padY + 1, 45, 'potted_red_tulip');
ps(33, padY + 1, 45, 'potted_oxeye_daisy');
var vz;
for (vz = 45; vz <= 48; vz++) { ps(X1 - 2, padY + 1, vz, 'vine[south=true]'); }
noisyScatter(4, padY + 1, 22, 50, padY + 1, 44, [{ block: 'short_grass', weight: 60 }, { block: 'oxeye_daisy', weight: 12 }, { block: 'dandelion', weight: 14 }, { block: 'cornflower', weight: 14 }], 0.16);
placeTree(8, padY + 1, 30, 'oak');
placeTree(50, padY + 1, 34, 'birch');
placeTree(11, padY + 1, 40, 'oak');
// cobbled approach path along the quay to the door
fill(23, padY, 45, 24, padY, 48, 'polished_andesite');
// ---------- 16. SAFETY: no ground inside the shells ----------
clearMasked(X1 + 1, walkY, Z1 + 1, X2 - 1, walkY, Z2 - 1, onlyMaterial('grass_block'));
clearMasked(X1 + 1, walkY, Z1 + 1, X2 - 1, walkY, Z2 - 1, onlyMaterial('dirt'));