// === BUILD PLAN ===
// Style: Bhutanese dzong (fortress-monastery), rammed-earth whitewash + kemar red band
// Footprint: square ring block 41x43 (x30..70, z28..70) around a 21x21 courtyard, with a
// central 13x13 utse tower; south gatehouse passage + monumental outdoor stair.
// Height: walls y20..32 (2 storeys, battered/tapering), ceiling y33, ring hip roof y33..39,
// utse y19..47 + gilded stepped roof y48..55 + finial.
//
// GROUND FLOOR (top-down, 1 char = 1 block, schematic):
// ###########################
// # DUKHANG (hall) # north range z30..36
// #####D#############D#######
// # R # # L # R=refectory(west x32..38) L=library(east x62..68)
// # e # COURTYARD # i #
// # f # + UTSE # b #
// # . # # . #
// #####D#####GATE#####D######
// # GUARD |||||| GUARD # south range z60..68
// ##########|GATE|###########
//
// FRONT (south) ELEVATION:
// /\ gilded utse roof
// /__\
// |__| utse tower (tapering)
// ~~~~~~~~~~~ ring hip roof, 2-block overhang
// RRRRRRRRRRR ochre-red kemar band
// | W W W | recessed trefoil windows, black surrounds
// | W W |
// ===[GATE]=== battered whitewashed base on stone plinth
// /|\ monumental stone staircase
//
// MATERIALS PLAN:
// walls : gradientPalette stone_bricks -> white_terracotta -> smooth_quartz -> calcite
// WHY: fakes AO/patina, a plain white box would read flat over 13 rows
// band : red_terracotta(45)+red_concrete(25)+brown_terracotta(20)+granite(10) noisePalette
// WHY: the kemar band is THE signature; noise keeps it from looking like paint
// timber : dark_oak_log frame + spruce planks fill (galleries) — dark/light CONTRAST
// roof : noisePalette spruce_stairs(60)+dark_oak_stairs(40) fed into roofStair material
// gilded : gold_block(50)+raw_gold_block(30)+honeycomb_block(20)
// ground : patches() rock vs grass on hills()+flatten() spur pad at Y19
// Rooms: Dukhang (altar, pillars, benches, butter lamps, rugs), Refectory (tables/barrels/
// kitchen), Library (shelfWall + lecterns), 2 guard rooms, 4 monk cells upstairs, utse shrine.
// STAIR PLAN: ground walk 20 -> upper walk 27 (D=7) via staircase() x2 (west + east range).
// Utse: 20->28 then 28->36, both staircase(). No hand-rolled flights anywhere.
// === END PLAN ===
var padY = 19, floorY = 19, walkY = 20;
var f2Y = 26, walkY2 = 27, wallTopY = 33, roofBaseY = 33;
// ---------- palettes ----------
var wallPal = gradientPalette(19, 33, [
{ block: 'stone_bricks', from: 0 },
{ block: 'white_terracotta', from: 0.16 },
{ block: 'smooth_quartz', from: 0.42 },
{ block: 'calcite', from: 0.82 }
], { noise: 0.28, seed: 7 });
var basePal = noisePalette([
{ block: 'stone_bricks', weight: 40 }, { block: 'cobblestone', weight: 25 },
{ block: 'andesite', weight: 20 }, { block: 'mossy_stone_bricks', weight: 15 }
], { seed: 12 });
var redPal = noisePalette([
{ block: 'red_terracotta', weight: 45 }, { block: 'red_concrete', weight: 25 },
{ block: 'brown_terracotta', weight: 20 }, { block: 'granite', weight: 10 }
], { seed: 3, freq: 0.16 });
var goldPal = noisePalette([
{ block: 'gold_block', weight: 50 }, { block: 'raw_gold_block', weight: 30 },
{ block: 'honeycomb_block', weight: 20 }
], { seed: 21, freq: 0.2 });
var roofMat = noisePalette([
{ block: 'spruce_stairs', weight: 60 }, { block: 'dark_oak_stairs', weight: 40 }
], { seed: 4, freq: 0.14 });
var floorPal = noisePalette([
{ block: 'spruce_planks', weight: 55 }, { block: 'dark_oak_planks', weight: 25 },
{ block: 'stripped_spruce_wood', weight: 20 }
], { seed: 33 });
var paveP = noisePalette([
{ block: 'polished_andesite', weight: 40 }, { block: 'andesite', weight: 25 },
{ block: 'stone', weight: 20 }, { block: 'cobblestone', weight: 15 }
], { seed: 44, freq: 0.1 });
// ============ CHECKPOINT: TERRAIN ============
var land = blob(50, 50, 46, { irregularity: 0.38, seed: 23 });
var hf = hills({ base: 9, amp: 7, scale: 0.028, seed: 11 });
var pad = flatten(hf, { x0: 24, z0: 22, x1: 76, z1: 74 }, padY, 9);
var rockP = patches([{ block: 'stone', w: 32 }, { block: 'andesite', w: 24 },
{ block: 'cobblestone', w: 20 }, { block: 'gravel', w: 14 }, { block: 'coarse_dirt', w: 10 }], 0.06, 4);
var grassP = patches([{ block: 'grass_block', w: 55 }, { block: 'coarse_dirt', w: 20 },
{ block: 'podzol', w: 15 }, { block: 'moss_block', w: 10 }], 0.05, 9);
var matFn = function (x, z) {
var yy = pad(x, z);
if (yy >= 16) return rockP(x, z);
return grassP(x, z);
};
surface(land, pad, matFn, { sub: 'stone', deep: 'deepslate', depth: 6 });
// clear the whole building envelope so no ground intrudes
fill(29, floorY, 27, 71, 62, 71, 'air');
// ============ CHECKPOINT: PLINTH + FLOORS ============
fill(30, floorY, 28, 70, floorY, 70, basePal); // plinth / ground slab
fill(29, floorY - 1, 27, 71, floorY - 1, 71, basePal); // plinth skirt (1 wider, 1 lower)
fill(40, floorY, 38, 60, floorY, 58, paveP); // courtyard paving
// range interiors (the 4 wings between outer wall and courtyard wall)
var rngN = [32, 30, 68, 36], rngS = [32, 60, 68, 68], rngW = [32, 37, 38, 59], rngE = [62, 37, 68, 59];
var ranges = [rngN, rngS, rngW, rngE];
var ri, rr;
for (ri = 0; ri < 4; ri++) {
rr = ranges[ri];
fill(rr[0], floorY, rr[1], rr[2], floorY, rr[3], floorPal); // wooden floors inside
}
// ============ CHECKPOINT: WALLS (battered, 2 thick) ============
function ringBand(x0, z0, x1, z1, y, thick, pat) {
fill(x0, y, z0, x1, y, z0 + thick - 1, pat);
fill(x0, y, z1 - thick + 1, x1, y, z1, pat);
fill(x0, y, z0, x0 + thick - 1, y, z1, pat);
fill(x1 - thick + 1, y, z0, x1, y, z1, pat);
}
var yy, ins, pat;
for (yy = walkY; yy <= wallTopY - 1; yy++) {
ins = (yy >= f2Y) ? 1 : 0; // inward taper at the upper storey
pat = (yy >= wallTopY - 3) ? redPal : wallPal; // ochre-red kemar band below the eaves
ringBand(30 + ins, 28 + ins, 70 - ins, 70 - ins, yy, 2, pat);
}
// cornice: upside-down stair course just under the red band
var cx2, cz2;
for (cx2 = 30; cx2 <= 70; cx2++) {
ps(cx2, wallTopY - 4, 27, 'spruce_stairs[facing=north,half=top]');
ps(cx2, wallTopY - 4, 71, 'spruce_stairs[facing=south,half=top]');
}
for (cz2 = 27; cz2 <= 71; cz2++) {
ps(29, wallTopY - 4, cz2, 'spruce_stairs[facing=west,half=top]');
ps(71, wallTopY - 4, cz2, 'spruce_stairs[facing=east,half=top]');
}
// courtyard inner walls (1 thick) + red band at the top
for (yy = walkY; yy <= wallTopY - 1; yy++) {
pat = (yy >= wallTopY - 3) ? redPal : wallPal;
fill(39, yy, 37, 61, yy, 37, pat);
fill(39, yy, 59, 61, yy, 59, pat);
fill(39, yy, 37, 39, yy, 59, pat);
fill(61, yy, 37, 61, yy, 59, pat);
}
// storey floors + ceilings over the 4 ranges
for (ri = 0; ri < 4; ri++) {
rr = ranges[ri];
fill(rr[0], f2Y, rr[1], rr[2], f2Y, rr[3], floorPal); // 2nd storey floor
fill(rr[0], wallTopY, rr[1], rr[2], wallTopY, rr[3], 'spruce_planks'); // ceiling
}
// ============ CHECKPOINT: WINDOWS (recessed, black surrounds) ============
// west/east faces: outer layer carved back 1 -> deep-set reveal; brown lattice glass inside
function winX(xOut, xIn, y, z, dirOut) {
var k;
for (k = 0; k < 2; k++) { ps(xOut, y + k, z, 'air'); ps(xOut, y + k, z - 1, 'air'); }
ps(xIn, y, z, 'brown_stained_glass_pane'); ps(xIn, y + 1, z, 'brown_stained_glass_pane');
ps(xIn, y, z - 1, 'brown_stained_glass_pane'); ps(xIn, y + 1, z - 1, 'brown_stained_glass_pane');
pb(xOut, y + 2, z, 'black_concrete'); pb(xOut, y + 2, z - 1, 'black_concrete');
pb(xOut, y - 1, z, 'black_concrete'); pb(xOut, y - 1, z - 1, 'black_concrete');
pb(xOut, y, z + 1, 'black_concrete'); pb(xOut, y + 1, z + 1, 'black_concrete');
pb(xOut, y, z - 2, 'black_concrete'); pb(xOut, y + 1, z - 2, 'black_concrete');
ps(xOut, y + 2, z + 1, dirOut === 'west' ? 'polished_blackstone_stairs[facing=east,half=top]' : 'polished_blackstone_stairs[facing=west,half=top]');
ps(xOut, y + 2, z - 2, dirOut === 'west' ? 'polished_blackstone_stairs[facing=east,half=top]' : 'polished_blackstone_stairs[facing=west,half=top]');
}
function winZ(zOut, zIn, y, x, dirOut) {
var k;
for (k = 0; k < 2; k++) { ps(x, y + k, zOut, 'air'); ps(x - 1, y + k, zOut, 'air'); }
ps(x, y, zIn, 'brown_stained_glass_pane'); ps(x, y + 1, zIn, 'brown_stained_glass_pane');
ps(x - 1, y, zIn, 'brown_stained_glass_pane'); ps(x - 1, y + 1, zIn, 'brown_stained_glass_pane');
pb(x, y + 2, zOut, 'black_concrete'); pb(x - 1, y + 2, zOut, 'black_concrete');
pb(x, y - 1, zOut, 'black_concrete'); pb(x - 1, y - 1, zOut, 'black_concrete');
pb(x + 1, y, zOut, 'black_concrete'); pb(x + 1, y + 1, zOut, 'black_concrete');
pb(x - 2, y, zOut, 'black_concrete'); pb(x - 2, y + 1, zOut, 'black_concrete');
ps(x + 1, y + 2, zOut, dirOut === 'north' ? 'polished_blackstone_stairs[facing=south,half=top]' : 'polished_blackstone_stairs[facing=north,half=top]');
ps(x - 2, y + 2, zOut, dirOut === 'north' ? 'polished_blackstone_stairs[facing=south,half=top]' : 'polished_blackstone_stairs[facing=north,half=top]');
}
var wz, wx;
for (wz = 34; wz <= 66; wz += 6) {
winX(30, 31, 22, wz, 'west'); winX(70, 69, 22, wz, 'east');
winX(31, 32, 29, wz, 'west'); winX(69, 68, 29, wz, 'east');
}
for (wx = 36; wx <= 64; wx += 6) {
winZ(28, 29, 22, wx, 'north'); winZ(70, 69, 22, wx, 'south');
winZ(29, 30, 29, wx, 'north'); winZ(69, 68, 29, wx, 'south');
}
// ============ CHECKPOINT: GATE + DOORS ============
fill(48, walkY, 59, 52, walkY + 3, 71, 'air'); // gate passage through the south range
fill(48, walkY, 59, 52, walkY + 3, 59, 'air');
fill(47, walkY, 69, 47, walkY + 4, 71, 'polished_blackstone'); // gate jambs
fill(53, walkY, 69, 53, walkY + 4, 71, 'polished_blackstone');
var gx;
for (gx = 48; gx <= 52; gx++) pb(gx, walkY + 4, 70, 'dark_oak_log[axis=x]');
ps(47, walkY + 5, 70, 'polished_blackstone_stairs[facing=west,half=top]');
ps(53, walkY + 5, 70, 'polished_blackstone_stairs[facing=east,half=top]');
fill(48, walkY + 5, 70, 52, walkY + 5, 70, redPal);
ps(50, walkY + 3, 69, 'gold_block'); // gilded gate boss
// gate passage side walls
fill(47, walkY, 59, 47, walkY + 4, 68, 'stone_bricks');
fill(53, walkY, 59, 53, walkY + 4, 68, 'stone_bricks');
fill(48, walkY + 4, 59, 52, walkY + 4, 68, 'dark_oak_planks');
function doorway(x0, y, z0, x1, z1) { fill(x0, y, z0, x1, y + 1, z1, 'air'); }
doorway(49, walkY, 37, 50, 37); // courtyard -> dukhang
doorway(39, walkY, 47, 39, 48); // courtyard -> refectory
doorway(61, walkY, 47, 61, 48); // courtyard -> library
doorway(48, walkY, 60, 52, 60); // gate -> courtyard side rooms
doorway(47, walkY, 63, 47, 64); // gate passage -> west guard room
doorway(53, walkY, 63, 53, 64); // gate passage -> east guard room
doorway(38, walkY, 33, 38, 34); // refectory -> dukhang
doorway(62, walkY, 33, 62, 34); // library -> dukhang
doorway(35, walkY, 60, 36, 60); // refectory -> south range
doorway(64, walkY, 60, 65, 60); // library -> south range
// ============ CHECKPOINT: TIMBER GALLERY (courtyard side, 2nd storey) ============
var gp, gq;
for (gq = 38; gq <= 58; gq++) {
ps(40, f2Y, gq, 'dark_oak_slab[type=top]'); ps(60, f2Y, gq, 'dark_oak_slab[type=top]');
pb(40, walkY2, gq, 'dark_oak_fence'); pb(60, walkY2, gq, 'dark_oak_fence');
}
for (gp = 40; gp <= 60; gp++) {
ps(gp, f2Y, 38, 'dark_oak_slab[type=top]'); ps(gp, f2Y, 58, 'dark_oak_slab[type=top]');
pb(gp, walkY2, 38, 'dark_oak_fence'); pb(gp, walkY2, 58, 'dark_oak_fence');
}
for (gq = 40; gq <= 56; gq += 4) {
fill(40, walkY, gq, 40, f2Y - 1, gq, 'dark_oak_log'); // gallery posts (never floating)
fill(60, walkY, gq, 60, f2Y - 1, gq, 'dark_oak_log');
fill(gq, walkY, 38, gq, f2Y - 1, 38, 'dark_oak_log');
fill(gq, walkY, 58, gq, f2Y - 1, 58, 'dark_oak_log');
}
// timber framing on the courtyard walls above the gallery
for (yy = walkY2; yy <= walkY2 + 4; yy += 4) {
fill(39, yy, 39, 39, yy, 57, 'dark_oak_log[axis=z]');
fill(61, yy, 39, 61, yy, 57, 'dark_oak_log[axis=z]');
fill(41, yy, 37, 59, yy, 37, 'dark_oak_log[axis=x]');
fill(41, yy, 59, 59, yy, 59, 'dark_oak_log[axis=x]');
}
// gallery openings (upper courtyard windows)
for (gq = 41; gq <= 57; gq += 4) {
fill(39, walkY2 + 1, gq, 39, walkY2 + 2, gq, 'brown_stained_glass_pane');
fill(61, walkY2 + 1, gq, 61, walkY2 + 2, gq, 'brown_stained_glass_pane');
fill(gq, walkY2 + 1, 37, gq, walkY2 + 2, 37, 'brown_stained_glass_pane');
fill(gq, walkY2 + 1, 59, gq, walkY2 + 2, 59, 'brown_stained_glass_pane');
}
// ============ CHECKPOINT: STAIRS BETWEEN FLOORS ============
staircase(34, 41, walkY, walkY2, 'south', { width: 2, material: 'spruce_stairs' });
staircase(65, 55, walkY, walkY2, 'north', { width: 2, material: 'spruce_stairs' });
// ============ CHECKPOINT: RING HIP ROOF ============
var rx, rz, dOut, dIn, dxIn, dzIn, sy, edge, rid;
for (rx = 28; rx <= 72; rx++) {
for (rz = 26; rz <= 72; rz++) {
dxIn = (rx < 41) ? (41 - rx) : ((rx > 59) ? (rx - 59) : 0);
dzIn = (rz < 39) ? (39 - rz) : ((rz > 57) ? (rz - 57) : 0);
dIn = Math.max(dxIn, dzIn) - 1;
if (dIn < 0) continue; // inside the courtyard hole
dOut = Math.min(Math.min(rx - 28, 72 - rx), Math.min(rz - 26, 72 - rz));
if (dOut < 0) continue;
if (dOut <= dIn) {
sy = roofBaseY + dOut;
if (rx - 28 === dOut) edge = 'west';
else if (72 - rx === dOut) edge = 'east';
else if (rz - 26 === dOut) edge = 'north';
else edge = 'south';
} else {
sy = roofBaseY + dIn;
if (dxIn > dzIn) edge = (rx < 41) ? 'east' : 'west';
else if (dzIn > dxIn) edge = (rz < 39) ? 'south' : 'north';
else edge = (rx < 41) ? 'east' : 'west';
}
if (dOut === dIn) pb(rx, sy, rz, 'dark_oak_wood'); // solid ridge, never a slab gap
else { rid = roofMat(rx, 0, rz); roofStair(rx, sy, rz, rid, edge); }
}
}
// ============ CHECKPOINT: UTSE TOWER ============
var uy, uins, upat;
fill(44, floorY, 42, 56, floorY, 54, basePal);
for (uy = walkY; uy <= 47; uy++) {
uins = (uy >= 30) ? ((uy >= 40) ? 2 : 1) : 0;
upat = (uy >= 44) ? redPal : wallPal;
ringBand(44 + uins, 42 + uins, 56 - uins, 54 - uins, uy, 1, upat);
}
fill(45, walkY2, 43, 55, walkY2, 53, floorPal); // utse 2nd floor (walk 28)
fill(46, 35, 44, 54, 35, 52, floorPal); // utse 3rd floor (walk 36)
doorway(49, walkY, 54, 50, 54); // utse entrance from the courtyard
staircase(46, 44, walkY, walkY2 + 1, 'south', { width: 1, material: 'dark_oak_stairs' });
staircase(53, 51, walkY2 + 1, 36, 'north', { width: 1, material: 'dark_oak_stairs' });
// utse windows: black-surrounded openings on all faces, each storey
var us, ub;
for (us = 0; us < 3; us++) {
ub = walkY + 2 + us * 8;
uins = (ub >= 30) ? ((ub >= 40) ? 2 : 1) : 0;
for (ux2 = 47; ux2 <= 53; ux2 += 3) {
ps(ux2, ub, 42 + uins, 'brown_stained_glass_pane'); ps(ux2, ub + 1, 42 + uins, 'brown_stained_glass_pane');
pb(ux2 - 1, ub, 42 + uins, 'black_concrete'); pb(ux2 + 1, ub, 42 + uins, 'black_concrete');
pb(ux2 - 1, ub + 1, 42 + uins, 'black_concrete'); pb(ux2 + 1, ub + 1, 42 + uins, 'black_concrete');
pb(ux2, ub + 2, 42 + uins, 'black_concrete');
ps(ux2, ub, 54 - uins, 'brown_stained_glass_pane'); ps(ux2, ub + 1, 54 - uins, 'brown_stained_glass_pane');
pb(ux2 - 1, ub, 54 - uins, 'black_concrete'); pb(ux2 + 1, ub, 54 - uins, 'black_concrete');
pb(ux2 - 1, ub + 1, 54 - uins, 'black_concrete'); pb(ux2 + 1, ub + 1, 54 - uins, 'black_concrete');
pb(ux2, ub + 2, 54 - uins, 'black_concrete');
}
for (uz2 = 46; uz2 <= 52; uz2 += 3) {
ps(44 + uins, ub, uz2, 'brown_stained_glass_pane'); ps(44 + uins, ub + 1, uz2, 'brown_stained_glass_pane');
pb(44 + uins, ub, uz2 - 1, 'black_concrete'); pb(44 + uins, ub, uz2 + 1, 'black_concrete');
pb(44 + uins, ub + 1, uz2 - 1, 'black_concrete'); pb(44 + uins, ub + 1, uz2 + 1, 'black_concrete');
pb(44 + uins, ub + 2, uz2, 'black_concrete');
ps(56 - uins, ub, uz2, 'brown_stained_glass_pane'); ps(56 - uins, ub + 1, uz2, 'brown_stained_glass_pane');
pb(56 - uins, ub, uz2 - 1, 'black_concrete'); pb(56 - uins, ub, uz2 + 1, 'black_concrete');
pb(56 - uins, ub + 1, uz2 - 1, 'black_concrete'); pb(56 - uins, ub + 1, uz2 + 1, 'black_concrete');
pb(56 - uins, ub + 2, uz2, 'black_concrete');
}
}
// gilded stepped roof + upturned copper eave + finial
var gs;
for (gs = 0; gs <= 5; gs++) {
fill(45 + gs, 48 + gs, 43 + gs, 55 - gs, 48 + gs, 53 - gs, goldPal);
}
for (ux2 = 45; ux2 <= 55; ux2++) {
roofStair(ux2, 48, 42, 'waxed_cut_copper_stairs', 'north');
roofStair(ux2, 48, 54, 'waxed_cut_copper_stairs', 'south');
}
for (uz2 = 43; uz2 <= 53; uz2++) {
roofStair(44, 48, uz2, 'waxed_cut_copper_stairs', 'west');
roofStair(56, 48, uz2, 'waxed_cut_copper_stairs', 'east');
}
fill(49, 54, 47, 51, 55, 49, goldPal);
pb(50, 56, 48, 'gold_block'); pb(50, 57, 48, 'lightning_rod'); pb(50, 58, 48, 'end_rod');
// ============ CHECKPOINT: INTERIOR — DUKHANG (prayer hall) ============
var px, pz;
fill(33, walkY, 31, 67, walkY, 35, 'air');
for (px = 36; px <= 64; px += 7) { // red pillars with gilded capitals
fill(px, walkY, 33, px, walkY + 4, 33, 'dark_oak_log');
pb(px, walkY + 5, 33, 'red_concrete');
ps(px, walkY + 5, 32, 'red_concrete'); ps(px, walkY + 5, 34, 'red_concrete');
}
rug(35, walkY, 31, 30, 5, 'red', 'yellow'); // hall carpet
// altar wall (north)
fill(44, walkY, 30, 56, walkY + 1, 30, goldPal);
fill(46, walkY, 31, 54, walkY, 31, 'polished_blackstone');
pb(50, walkY + 1, 31, 'gold_block'); pb(50, walkY + 2, 31, 'gold_block');
pb(50, walkY + 3, 31, 'shroomlight');
ps(49, walkY + 1, 31, 'gold_block'); ps(51, walkY + 1, 31, 'gold_block');
ps(48, walkY, 31, 'lantern'); ps(52, walkY, 31, 'lantern');
ps(46, walkY, 31, 'candle[candles=3,lit=true]'); ps(54, walkY, 31, 'candle[candles=3,lit=true]');
ps(45, walkY + 2, 30, 'red_wall_banner[facing=south]'); ps(55, walkY + 2, 30, 'red_wall_banner[facing=south]');
ps(47, walkY + 3, 30, 'yellow_wall_banner[facing=south]'); ps(53, walkY + 3, 30, 'yellow_wall_banner[facing=south]');
// benches facing the altar + offering tables
for (px = 40; px <= 60; px += 2) {
chairStair(px, walkY, 34, 'dark_oak_stairs', 'north');
chairStair(px, walkY, 36, 'dark_oak_stairs', 'north');
}
for (px = 42; px <= 58; px += 8) {
pb(px, walkY, 32, 'dark_oak_fence'); ps(px, walkY + 1, 32, 'oak_pressure_plate');
pb(px + 1, walkY, 32, 'decorated_pot');
}
// hanging butter lamps
for (px = 38; px <= 62; px += 6) {
pb(px, f2Y - 1, 33, 'chain[axis=y]'); ps(px, f2Y - 2, 33, 'lantern[hanging=true]');
}
pb(34, walkY, 31, 'bookshelf'); pb(34, walkY + 1, 31, 'bookshelf');
pb(66, walkY, 31, 'bookshelf'); pb(66, walkY + 1, 31, 'bookshelf');
// ============ CHECKPOINT: INTERIOR — REFECTORY (west) ============
fill(33, walkY, 38, 37, walkY, 58, 'air');
// kitchen counter run along the west wall
pb(33, walkY, 39, 'stripped_spruce_log'); ps(33, walkY + 1, 39, 'spruce_stairs[facing=east,half=top]');
ps(33, walkY, 40, 'furnace[facing=east,lit=true]'); ps(33, walkY + 1, 40, 'iron_trapdoor[facing=east,half=bottom]');
pb(33, walkY, 41, 'stripped_spruce_log'); ps(33, walkY + 1, 41, 'spruce_stairs[facing=east,half=top]');
ps(33, walkY, 42, 'water_cauldron[level=3]');
pb(33, walkY, 43, 'barrel'); pb(33, walkY, 44, 'smoker[facing=east]');
// long refectory tables + benches
for (pz = 47; pz <= 55; pz++) {
pb(35, walkY, pz, 'dark_oak_fence'); ps(35, walkY + 1, pz, 'dark_oak_pressure_plate');
chairStair(34, walkY, pz, 'spruce_stairs', 'east');
chairStair(36, walkY, pz, 'spruce_stairs', 'west');
}
rug(33, walkY, 46, 5, 11, 'orange', 'red');
for (pz = 40; pz <= 56; pz += 6) { pb(37, f2Y - 1, pz, 'chain[axis=y]'); ps(37, f2Y - 2, pz, 'lantern[hanging=true]'); }
pb(33, walkY, 57, 'barrel'); pb(34, walkY, 57, 'barrel'); pb(33, walkY + 1, 57, 'barrel');
pb(36, walkY, 39, 'cartography_table'); pb(37, walkY, 39, 'composter');
// ============ CHECKPOINT: INTERIOR — LIBRARY (east) ============
fill(63, walkY, 38, 67, walkY, 58, 'air');
shelfWall(68, walkY, 39, 68, walkY + 2, 57, 'bookshelf');
for (pz = 42; pz <= 54; pz += 4) {
ps(65, walkY, pz, 'lectern[facing=west]');
chairStair(64, walkY, pz, 'dark_oak_stairs', 'east');
pb(65, f2Y - 1, pz, 'chain[axis=y]'); ps(65, f2Y - 2, pz, 'lantern[hanging=true]');
}
rug(63, walkY, 40, 4, 16, 'yellow', 'red');
pb(63, walkY, 39, 'enchanting_table'); pb(67, walkY, 57, 'barrel');
for (pz = 40; pz <= 56; pz += 8) { pb(63, walkY, pz, 'decorated_pot'); }
// ============ CHECKPOINT: INTERIOR — GUARD ROOMS (south) ============
fill(33, walkY, 61, 46, walkY, 67, 'air');
fill(54, walkY, 61, 67, walkY, 67, 'air');
pb(35, walkY, 62, 'smithing_table'); pb(36, walkY, 62, 'anvil[facing=north]');
pb(37, walkY, 62, 'grindstone[face=floor,facing=north]');
placeBed(34, walkY, 65, 'red', 'west'); placeBed(34, walkY, 63, 'red', 'west');
for (px = 40; px <= 45; px++) { pb(px, walkY, 61, 'barrel'); }
pb(43, walkY, 64, 'dark_oak_fence'); ps(43, walkY + 1, 64, 'oak_pressure_plate');
chairStair(42, walkY, 64, 'spruce_stairs', 'east'); chairStair(44, walkY, 64, 'spruce_stairs', 'west');
pb(43, f2Y - 1, 64, 'chain[axis=y]'); ps(43, f2Y - 2, 64, 'lantern[hanging=true]');
placeBed(66, walkY, 65, 'red', 'east'); placeBed(66, walkY, 63, 'red', 'east');
pb(60, walkY, 62, 'fletching_table'); pb(59, walkY, 62, 'barrel'); pb(58, walkY, 62, 'cauldron');
pb(57, f2Y - 1, 64, 'chain[axis=y]'); ps(57, f2Y - 2, 64, 'lantern[hanging=true]');
rug(56, walkY, 63, 5, 4, 'red', 'yellow');
// ============ CHECKPOINT: INTERIOR — UPPER FLOOR (monk cells + corridor) ============
for (ri = 0; ri < 4; ri++) {
rr = ranges[ri];
fill(rr[0] + 1, walkY2, rr[1] + 1, rr[2] - 1, walkY2 + 4, rr[3] - 1, 'air');
}
var cellZ;
for (cellZ = 40; cellZ <= 55; cellZ += 5) { // west cells
placeBed(34, walkY2, cellZ, 'red', 'west');
pb(36, walkY2, cellZ, 'dark_oak_fence'); ps(36, walkY2 + 1, cellZ, 'oak_pressure_plate');
pb(36, walkY2 + 2, cellZ, 'lantern');
rug(33, walkY2, cellZ + 1, 4, 2, 'orange', 'yellow');
fill(37, walkY2, cellZ + 2, 37, walkY2 + 3, cellZ + 2, 'spruce_planks'); // cell partition
}
for (cellZ = 41; cellZ <= 55; cellZ += 5) { // east cells
placeBed(66, walkY2, cellZ, 'red', 'east');
pb(64, walkY2, cellZ, 'dark_oak_fence'); ps(64, walkY2 + 1, cellZ, 'oak_pressure_plate');
pb(64, walkY2 + 2, cellZ, 'lantern');
rug(64, walkY2, cellZ + 1, 4, 2, 'orange', 'yellow');
}
// upper assembly room over the north range
rug(38, walkY2, 31, 24, 5, 'red', 'yellow');
for (px = 40; px <= 60; px += 4) {
pb(px, walkY2, 32, 'dark_oak_fence'); ps(px, walkY2 + 1, 32, 'dark_oak_pressure_plate');
chairStair(px, walkY2, 33, 'dark_oak_stairs', 'north');
pb(px, wallTopY - 1, 33, 'chain[axis=y]'); ps(px, wallTopY - 2, 33, 'lantern[hanging=true]');
}
shelfWall(36, walkY2, 30, 44, walkY2 + 1, 30, 'bookshelf');
for (px = 46; px <= 58; px += 6) { pb(px, walkY2, 30, 'decorated_pot'); pb(px + 1, walkY2, 30, 'barrel'); }
// upper south hall
for (px = 36; px <= 64; px += 6) {
pb(px, walkY2, 67, 'barrel');
pb(px, wallTopY - 1, 64, 'chain[axis=y]'); ps(px, wallTopY - 2, 64, 'lantern[hanging=true]');
}
// ============ CHECKPOINT: UTSE SHRINE INTERIOR ============
fill(45, walkY, 43, 55, walkY + 6, 53, 'air');
fill(45, walkY, 43, 55, walkY, 53, 'polished_blackstone');
rug(46, walkY, 44, 9, 9, 'red', 'yellow');
fill(48, walkY, 43, 52, walkY + 1, 43, goldPal);
pb(50, walkY + 2, 43, 'gold_block'); pb(50, walkY + 3, 43, 'shroomlight');
ps(49, walkY, 44, 'candle[candles=4,lit=true]'); ps(51, walkY, 44, 'candle[candles=4,lit=true]');
for (uz2 = 45; uz2 <= 51; uz2 += 3) {
pb(45, walkY, uz2, 'barrel'); pb(55, walkY, uz2, 'barrel'); // prayer wheels
pb(45, walkY + 1, uz2, 'gold_block'); pb(55, walkY + 1, uz2, 'gold_block');
}
pb(50, walkY + 6, 48, 'chain[axis=y]'); ps(50, walkY + 5, 48, 'lantern[hanging=true]');
// utse upper storeys
fill(46, walkY2 + 1, 44, 54, walkY2 + 6, 52, 'air');
rug(47, walkY2 + 1, 45, 7, 7, 'yellow', 'red');
fill(48, walkY2 + 1, 44, 52, walkY2 + 2, 44, goldPal);
pb(50, walkY2 + 3, 44, 'shroomlight');
ps(48, walkY2 + 1, 45, 'lantern'); ps(52, walkY2 + 1, 45, 'lantern');
shelfWall(47, walkY2 + 1, 52, 53, walkY2 + 2, 52, 'bookshelf');
fill(47, 36, 45, 53, 42, 51, 'air');
rug(48, 36, 46, 5, 5, 'red', 'yellow');
pb(50, 36, 46, 'gold_block'); pb(50, 37, 46, 'shroomlight');
ps(48, 36, 47, 'lantern'); ps(52, 36, 47, 'lantern');
ps(49, 36, 50, 'lectern[facing=north]');
// ============ CHECKPOINT: COURTYARD + PRAYER FLAGS ============
var fx, colors = ['blue_wool', 'white_wool', 'red_wool', 'green_wool', 'yellow_wool'];
for (fx = 41; fx <= 59; fx += 6) {
fill(fx, walkY, 39, fx, walkY + 5, 39, 'dark_oak_fence');
pb(fx, walkY + 6, 39, colors[(fx / 3) % 5 | 0]);
fill(fx, walkY, 57, fx, walkY + 5, 57, 'dark_oak_fence');
pb(fx, walkY + 6, 57, colors[(fx / 2) % 5 | 0]);
}
var flagI = 0;
for (fx = 41; fx <= 59; fx++) { // strung flag lines on the railings
pb(fx, walkY2 + 1, 38, colors[flagI % 5]);
pb(fx, walkY2 + 1, 58, colors[(flagI + 2) % 5]);
flagI++;
}
for (fx = 42; fx <= 58; fx += 4) { lampPost(fx, walkY, 41, 'dark_oak_fence'); lampPost(fx, walkY, 55, 'dark_oak_fence'); }
pb(43, walkY, 45, 'decorated_pot'); pb(57, walkY, 51, 'decorated_pot');
// ============ CHECKPOINT: MONUMENTAL STAIR + LANDSCAPE ============
var approachY = Math.round(pad(50, 82));
staircase(48, 82, approachY + 1, walkY, 'north', { width: 5, material: 'stone_brick_stairs', rail: false });
fill(46, approachY - 4, 71, 47, walkY - 1, 84, basePal); // stair cheek walls
fill(53, approachY - 4, 71, 54, walkY - 1, 84, basePal);
fill(46, walkY, 71, 47, walkY + 1, 84, 'stone_brick_wall');
fill(53, walkY, 71, 54, walkY + 1, 84, 'stone_brick_wall');
fill(48, floorY - 1, 71, 52, floorY - 1, 74, paveP);
lampPost(45, walkY, 74, 'dark_oak_fence'); lampPost(55, walkY, 74, 'dark_oak_fence');
lampPost(45, walkY, 80, 'dark_oak_fence'); lampPost(55, walkY, 80, 'dark_oak_fence');
// boulders + conifers on the spur
var tI, tx, tz, th;
for (tI = 0; tI < 26; tI++) {
tx = 8 + ((tI * 37) % 84); tz = 6 + ((tI * 53) % 88);
if (tx > 24 && tx < 78 && tz > 20 && tz < 76) continue;
th = Math.round(pad(tx, tz));
if (th < 4) continue;
if (tI % 4 === 0) makeSphere(tx, th, tz, noisePalette([{ block: 'stone', weight: 55 }, { block: 'andesite', weight: 25 }, { block: 'mossy_cobblestone', weight: 20 }], { seed: tI }), 2 + (tI % 2), true);
else placeTree(tx, th + 1, tz, 'spruce', 5 + (tI % 4));
}
noisyScatter(10, 90, 10, 90, pad, ['grass', 'fern', 'dandelion', 'poppy'], 0.05, 61);