// === 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 finial Y28
// Facade faces +Z (the canal) so the isometric/front cameras see the gable, not the back.
//
// GROUND FLOOR (top-down, 1 char = 1 block, +Z downward = toward canal):
// x18 x30 x38
// ###W#####W##### (z30 back wall)
// #CC #
// #CC store W (z35) ##########
// W hall # # count W
// # S #=========D ing #
// W S W # house W
// #WW DD WW ###WW DD WW######### (z44 = quay facade, faces +Z)
// Legend: # brick wall, W arched window, D door, S staircase up, C chimney/hearth
//
// FRONT ELEVATION (crow-stepped gable, hoist beam at peak):
// | <- brick_wall finial
// _#_ <- hoist beam projecting over the quay + chain & pulley
// |#####|
// |#########| <- diorite step treads on every crow step
// |## o o ##| <- gable roundels
// |################|
// | W [HOIST] W | <- loft hoist doors + arched loft windows
// |================| <- white polished_diorite string course at Y13
// | W [DOOR] W | <- ground arched windows + arched double door
// |#| #| |# |#| <- proud brick pilasters (lesenes) at z45
// ~~~~ cobbled quay ~~~ bollards ~~~ canal water
//
// MATERIALS PLAN (palette by VOLUME - gradient for age/height, white stone for CONTRAST):
// walls : gradientPalette mud_bricks(low, damp) -> bricks -> granite(high, sun-bleached), noise .22
// WHY: a red-brick value ramp fakes ambient occlusion on a tall otherwise-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/granite/mud_brick STAIRS fed per-stair so facing survives
// floors : spruce plank noise (ground), oak plank noise (loft)
// quay : cobble/mossy/andesite/stone_bricks/gravel noise
// Rooms: Store hall (counter, hearth, crates, barrels, table+chairs, shelves, beams),
// Loft (sack stacks, barrel pyramid, hoist bay, ledger lectern, lamp posts),
// Counting-house wing (desk, lectern, bookshelf run, chests, rug, lanterns)
// STAIR PLAN: delta = walk2Y-walkY = 14-8 = 6 -> staircase(28,33,8,14,'south'), one flush 7-cell run, width 2
// PROCESS: LAYERED (placeholder 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; flatten's return is captured and used) ----------
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 ----------
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));
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;
carveZ(Z2, walkY, 23, 24);
carveZ(Z2, gy, 20, 21); carveZ(Z2, gy, 27, 28);
carveZ(Z2, walk2Y, 23, 24);
carveZ(Z2, ly, 20, 20); carveZ(Z2, ly, 27, 28);
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);
carveX(X2, gy, 32, 33); carveX(X2, ly, 32, 33);
carveZ(Z1, gy, 21, 22); carveZ(Z1, gy, 26, 27); carveZ(Z1, ly, 23, 24);
clearMasked(X2, walkY, 41, X2, walkY + 1, 41, onlyMaterial(PH));
carveZ(WZ2, walkY, 34, 35);
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 ----------
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);
}
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;
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);
ring(f2Y, X1, Z1, X2, Z2, 'polished_diorite');
ring(wallTopY, X1, Z1, X2, Z2, 'polished_diorite');
ring(wTopY, WX1, WZ1, WX2, WZ2, 'polished_diorite');
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 wzs = [33, 37, 41];
for (pi = 0; pi < wzs.length; pi++) {
for (py = floorY + 2; py <= wallTopY - 1; py++) pb(X1 - 1, py, wzs[pi], 'bricks');
ps(X1 - 1, wallTopY, wzs[pi], 'polished_diorite_slab[type=bottom]');
}
// ---------- 7. ROOF ----------
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');
}
for (s = 0; s < HALF; s++) fill(X1 + s, roofBaseY + s, Z1, X2 - s, roofBaseY + s, Z1, gablePat);
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');
ps(22, roofBaseY + 2, Z2, 'brown_stained_glass'); ps(26, roofBaseY + 2, Z2, 'brown_stained_glass');
ps(CX, roofBaseY + 4, Z2, 'brown_stained_glass');
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 + 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');
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');
// ---------- 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');
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]');
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]');
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 ----------
staircase(28, 33, walkY, walk2Y, 'south', { width: 2, material: 'spruce_stairs', rail: true, support: 'stripped_spruce_log' });
// ---------- 12. GROUND FLOOR - STORE HALL ----------
rug(22, walkY, 35, 6, 5, 'brown', 'red');
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]');
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');
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');
shelfWall(27, walkY, 36, 'north', 4, 2);
pb(26, walkY, 31, 'cartography_table'); pb(27, walkY, 31, 'barrel[facing=up]');
ps(25, walkY, 31, 'cauldron[level=2]');
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');
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 ----------
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');
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]');
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]');
lampPost(19, walk2Y, 43, 2, 'oak_fence');
lampPost(29, walk2Y, 43, 2, 'oak_fence');
lampPost(19, walk2Y, 37, 2, 'oak_fence');
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'); ps(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]');
}
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]');
}
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');
lampPost(16, padY + 1, 46, 4, 'cobblestone_wall');
lampPost(31, padY + 1, 46, 4, 'cobblestone_wall');
lampPost(45, padY + 1, 46, 4, 'cobblestone_wall');
// moored lighter (flat barge)
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, 'short_grass', 0.28, 42);
noisyScatter(4, padY + 1, 22, 50, padY + 1, 44, 'dandelion', 0.05, 17);
noisyScatter(4, padY + 1, 22, 50, padY + 1, 44, 'cornflower', 0.05, 23);
noisyScatter(0, 4, 46, 63, padY - 1, 49, 'mossy_stone_bricks', 0.25, 5);
placeTree(8, padY + 1, 30, 'oak');
placeTree(50, padY + 1, 34, 'birch');
placeTree(11, padY + 1, 40, 'oak');
fill(23, padY, 45, 24, padY, 48, 'polished_andesite');
// ---------- 16. SAFETY: no ground intruding in 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'));
clearMasked(X1 + 1, walkY, Z1 + 1, X2 - 1, walkY, Z2 - 1, onlyMaterial('short_grass'));
// ---- FIX PASS: the scene read thin - dress the quay and green the ground ----
var fx, fz, fi;
// denser ground cover so the bare dirt reads as a working waterfront verge
noisyScatter(2, padY + 1, 18, 52, padY + 1, 44, 'short_grass', 0.55, 101);
noisyScatter(2, padY + 1, 18, 52, padY + 1, 44, 'tall_grass', 0.10, 102);
noisyScatter(2, padY + 1, 18, 52, padY + 1, 44, 'oxeye_daisy', 0.05, 103);
noisyScatter(2, padY + 1, 18, 52, padY + 1, 44, 'poppy', 0.04, 104);
noisyScatter(0, padY, 45, 63, padY, 49, 'moss_block', 0.12, 105);
// hedge line separating the verge from the quay
for (fx = 2; fx <= 15; fx++) { pb(fx, padY + 1, 44, 'oak_leaves[persistent=true]'); if (fx % 5 === 0) pb(fx, padY + 2, 44, 'oak_leaves[persistent=true]'); }
for (fx = 43; fx <= 60; fx++) { pb(fx, padY + 1, 44, 'oak_leaves[persistent=true]'); if (fx % 5 === 0) pb(fx, padY + 2, 44, 'oak_leaves[persistent=true]'); }
// more trees set back from the water
placeTree(5, padY + 1, 26, 'birch');
placeTree(15, padY + 1, 24, 'oak');
placeTree(38, padY + 1, 24, 'oak');
placeTree(55, padY + 1, 28, 'birch');
placeTree(58, padY + 1, 40, 'oak');
// timber quay crane east of the warehouse
fill(47, padY + 1, 46, 47, padY + 7, 46, 'stripped_spruce_log[axis=y]');
for (fi = 0; fi < 4; fi++) ps(47, padY + 7, 47 + fi, 'spruce_log[axis=z]');
ps(47, padY + 6, 50, 'iron_chain[axis=y]');
ps(47, padY + 5, 50, 'iron_chain[axis=y]');
pb(47, padY + 4, 50, 'barrel[facing=up]');
seg2(46, padY + 6, 46, 47, padY + 7, 47);
function seg2(a, b, c, d, e, f) { pb(a, b, c, 'spruce_fence'); pb(d - 1, e - 1, f - 1, 'spruce_fence'); }
pb(46, padY + 1, 46, 'stripped_spruce_log[axis=y]'); pb(48, padY + 1, 46, 'stripped_spruce_log[axis=y]');
// more cargo and traffic along the quay
pb(14, padY + 1, 46, 'barrel[facing=up]'); pb(15, padY + 1, 46, 'barrel[facing=up]'); pb(14, padY + 2, 46, 'barrel[facing=up]');
pb(36, padY + 1, 46, 'hay_block'); pb(37, padY + 1, 46, 'hay_block'); pb(36, padY + 2, 46, 'hay_block');
pb(44, padY + 1, 46, 'chest[facing=south,type=single]'); pb(50, padY + 1, 46, 'barrel[facing=up]');
pb(52, padY + 1, 46, 'hay_block'); pb(53, padY + 1, 46, 'barrel[facing=up]');
// a handcart waiting by the door
pb(18, padY + 1, 45, 'oak_slab[type=bottom]'); pb(17, padY + 1, 45, 'oak_slab[type=bottom]');
ps(16, padY + 1, 45, 'oak_trapdoor[facing=south,half=bottom,open=false]');
pb(17, padY + 2, 45, 'barrel[facing=up]');
// extra quay lighting and bollard chains
lampPost(9, padY + 1, 46, 4, 'cobblestone_wall');
lampPost(38, padY + 1, 46, 4, 'cobblestone_wall');
lampPost(54, padY + 1, 46, 4, 'cobblestone_wall');
for (fx = 13; fx <= 47; fx++) { if (fx % 6 !== 0) ps(fx, padY + 2, 47, 'iron_chain[axis=x]'); }
// flower beds flanking the door
ps(21, padY + 1, 45, 'potted_cornflower'); ps(26, padY + 1, 45, 'potted_poppy');
ps(31, padY + 1, 45, 'potted_dandelion');
// a second small skiff moored west of the barge
fill(12, 3, 52, 16, 3, 55, 'spruce_planks');
fill(12, 4, 52, 16, 4, 52, 'spruce_planks'); fill(12, 4, 55, 16, 4, 55, 'spruce_planks');
fill(12, 4, 53, 12, 4, 54, 'spruce_planks'); fill(16, 4, 53, 16, 4, 54, 'spruce_planks');
pb(14, 4, 53, 'barrel[facing=up]'); pb(13, 4, 54, 'oak_fence'); ps(13, 5, 54, 'lantern');