← Back to Gallery

Loading 3D viewer…

Ottoman Hammam (guided, fixed)

by Jorge Barbero

Dimensions
84×48×84
Blocks
75,041
Compute Time
8.7s
Generation Time
9m 50s
Edits
1
Model
claude-opus-5
Created
September 21, 2026
autoevalguidedhammamottomanlarge_structures
Prompt

User Prompt

an Ottoman hammam bathhouse: a low massing of thick warm-limestone walls topped by three lead-grey ribbed domes of different sizes pierced with small star-shaped glass oculi; an arched portico entrance with alternating red-and-cream voussoirs, a marble-floored octagonal hot room with a raised central navel-stone platform and water basins along the walls, and a cool changing room with a fountain and a wooden upper gallery reached by a stair

Enhanced Prompt

autoeval condition=guided; prepare_build + search_docs(build-rules/Essential Build Rules, shape-techniques/Dome Layer Tables, worldedit-api/Furniture&Stairs, worldedit-api/Position Palettes, worldedit-api/Natural Terrain Superpowers, worldedit-api/Shape Wrappers)

Photos

Exterior
Exteriorexterior
Camekan + fountain
Camekan + fountaininterior
Hararet + gobektasi
Hararet + gobektasiinterior
Gallery stair
Gallery stairinterior
CraftScript Source
// === BUILD PLAN ===
// Style: Ottoman hammam (classical, 16th c. Sinan idiom)
// Footprint: linear 3-cell sequence on N-S axis, 25 wide x 62 deep + portico
//   HARARET (hot room, OCTAGON) z15..37, center (40,26), R=11, big ribbed dome R=9
//   SOGUKLUK (cool passage)     z37..47, 13x11, small ribbed dome R=4
//   CAMEKAN (changing hall)     z47..71, 25x25, LARGEST ribbed dome R=10 + wooden gallery
//   PORTICO                     z72..77, 3 arches, alternating red/cream voussoirs
//
// GROUND PLAN (top-down, z increases downward = toward the entrance):
//        ....#######....      <- hararet octagon, 8 wall niches w/ basins
//        ..##  .....  ##..       central gobektasi (navel stone) platform
//        .#   [GOBEK]   #.
//        ..##  .....  ##..
//        ....###DDD###....      D = doorway
//          ##       ##
//          # sogukluk #        basins + benches, small dome
//          ###   DDD###
//        #####################
//        #G                 G#  G = wooden gallery strip (upper level y13)
//        #G     ~~~~~       G#  ~ = octagonal fountain pool
//        #G     ~~~~~       G#
//        #G   S             G#  S = staircase to gallery
//        ##########DDD########
//             | | |             portico piers
//             A A A             A = arch (red/cream voussoirs)
//
// SECTION (front elevation):
//            (.)  <- ribbed lead dome, star oculi
//         ___/ \___
//        |  drum   |
//        |#|#|#|#|#|   <- pilastered limestone wall w/ string course
//        |  /^\    |   <- portico arches
//        =============
//
// MATERIALS PLAN (what goes where + WHY):
//   walls    : gradientPalette sandstone -> smooth_sandstone -> smooth_quartz (y8..y20)
//              WHY: warm limestone that lightens with height = fake sun/AO, gives volume
//   pilaster : cut_sandstone proud by 1 + cut_sandstone_stairs cornice
//              WHY: kills flat_walls - vertical rhythm every 6 blocks, real shadow
//   domes    : gradientPalette deepslate_tiles -> gray_concrete -> light_gray_concrete
//              WHY: lead sheeting reads darker at the springing, brighter at the crown
//   ribs     : polished_deepslate radial lines  WHY: the "ribbed" signature, dark on grey
//   oculi    : light_blue/white stained glass rings  WHY: star-lights, never a solid fire block
//   voussoir : red_terracotta / smooth_quartz ALTERNATING  WHY: the ablaq stripe is the look
//   interior : quartz family marble noisePalette + spruce gallery  WHY: cold marble vs warm wood
// Rooms: camekan(fountain, benches, rugs, upper gallery), sogukluk(basins, benches),
//        hararet(gobektasi platform, 4 basin alcoves, oculi light)
// STAIR PLAN: camekan floor walkY=8 -> gallery walk 14, D=6 -> staircase() single run north
//             along the west gallery strip at x=31, from z=68. Helper cuts the floor hole.
// === END PLAN ===

var padY = 6, floorY = 7, walkY = 8;

// ---------- palettes ----------
var LIME = gradientPalette(8, 20, [
  { block: 'sandstone', from: 0 },
  { block: 'smooth_sandstone', from: 0.35 },
  { block: 'smooth_quartz', from: 0.88 }
], { noise: 0.25, seed: 3 });
var LIMEFLAT = noisePalette([
  { block: 'smooth_sandstone', weight: 50 },
  { block: 'sandstone', weight: 25 },
  { block: 'cut_sandstone', weight: 25 }
], { seed: 7, freq: 0.1 });
var LEAD = gradientPalette(16, 32, [
  { block: 'gray_concrete', from: 0 },
  { block: 'light_gray_concrete', from: 0.3 },
  { block: 'light_gray_terracotta', from: 0.62 },
  { block: 'smooth_stone', from: 0.85 }
], { noise: 0.22, seed: 11 });
var MARBLE = noisePalette([
  { block: 'quartz_block', weight: 46 },
  { block: 'smooth_quartz', weight: 30 },
  { block: 'quartz_bricks', weight: 14 },
  { block: 'chiseled_quartz_block', weight: 10 }
], { seed: 9, freq: 0.16 });
var RIB = 'deepslate_tiles';

// ---------- 1. TERRAIN (superpowers, flat pad under the whole hammam) ----------
var land = blob(40, 42, 40, { irregularity: 0.35, seed: 12 });
var h = hills({ base: padY, amp: 3, scale: 0.035, seed: 5 });
var pad = flatten(h, { x0: 21, z0: 7, x1: 59, z1: 81 }, padY, 9);
var groundMat = patches(['grass_block', 'moss_block', 'coarse_dirt', 'sand'], 0.06, 4);
surface(land, pad, groundMat, { sub: 'dirt', deep: 'stone', depth: 4 });

// ---------- helpers ----------
function inOct(x, z, cx, cz, R, cut) {
  var dx = x - cx, dz = z - cz;
  if (dx < 0) dx = -dx;
  if (dz < 0) dz = -dz;
  return (dx <= R && dz <= R && (dx + dz) <= cut);
}
function dist2(x, z, cx, cz) {
  var dx = x - cx, dz = z - cz;
  return Math.sqrt(dx * dx + dz * dz);
}
// ribbed dome: stacked shrinking rings (watertight), radial ribs, oculi rings
function ribbedDome(cx, cz, baseY, R, shellPat, ribId, ribCount) {
  for (var dy = 0; dy <= R; dy++) {
    var r = Math.round(Math.sqrt(R * R - dy * dy));
    var rn = (dy >= R) ? -1 : Math.round(Math.sqrt(R * R - (dy + 1) * (dy + 1)));
    if (r <= 0) { pb(cx, baseY + dy, cz, ribId); continue; }
    var start = rn + 1;
    if (start > r) start = r;
    if (start < 1) start = 1;
    for (var rr = start; rr <= r; rr++) {
      makeCylinder(cx, baseY + dy, cz, shellPat, rr, 1, true);
    }
    for (var k = 0; k < ribCount; k++) {
      var a = (Math.PI * 2 * k) / ribCount;
      pb(cx + Math.round(r * Math.cos(a)), baseY + dy, cz + Math.round(r * Math.sin(a)), ribId);
    }
  }
  pb(cx, baseY + R + 1, cz, 'polished_deepslate');
  pb(cx, baseY + R + 2, cz, 'lightning_rod');
}
// star oculi: single glass blocks ON the shell ring (computed from the ring radius -> never floating)
function domeOculi(cx, cz, baseY, R, count, level, glassA, glassB) {
  var dy = Math.round(R * level);
  var r = Math.round(Math.sqrt(R * R - dy * dy));
  for (var k = 0; k < count; k++) {
    var a = (Math.PI * 2 * (k + 0.5)) / count;
    var gx = cx + Math.round(r * Math.cos(a));
    var gz = cz + Math.round(r * Math.sin(a));
    pb(gx, baseY + dy, gz, (k % 2 === 0) ? glassA : glassB);
    pb(gx, baseY + dy - 1, gz, glassB);
  }
}
// roof deck that turns a square/octagon room into a circular dome opening
function domeDeck(x0, z0, x1, z1, y0, y1, cx, cz, openR, pat, octR, octCut) {
  for (var x = x0; x <= x1; x++) {
    for (var z = z0; z <= z1; z++) {
      if (octR > 0 && !inOct(x, z, cx, cz, octR, octCut)) continue;
      if (dist2(x, z, cx, cz) <= openR - 1) continue;
      fill(x, y0, z, x, y1, z, pat);
    }
  }
}

// ---------- 2. HARARET (hot room, octagon) ----------
var hcx = 40, hcz = 26, hR = 11, hCut = 15;
var hTop = walkY + 7;   // y15
for (var x = hcx - hR; x <= hcx + hR; x++) {
  for (var z = hcz - hR; z <= hcz + hR; z++) {
    if (!inOct(x, z, hcx, hcz, hR, hCut)) continue;
    fill(x, floorY, z, x, floorY, z, MARBLE);                       // marble floor
    if (!inOct(x, z, hcx, hcz, hR - 2, hCut - 2)) {
      fill(x, walkY, z, x, hTop, z, LIME);                          // 2-thick wall
    } else {
      fill(x, walkY, z, x, hTop + 6, z, 'air');                     // clear interior
    }
  }
}
domeDeck(hcx - hR, hcz - hR, hcx + hR, hcz + hR, hTop + 1, hTop + 2, hcx, hcz, 9, LIMEFLAT, hR, hCut);
makeCylinder(hcx, hTop + 1, hcz, LIMEFLAT, 10, 2, true);            // drum
ribbedDome(hcx, hcz, hTop + 3, 9, LEAD, RIB, 8);
domeOculi(hcx, hcz, hTop + 3, 9, 8, 0.45, 'light_blue_stained_glass', 'white_stained_glass');

// ---------- 3. SOGUKLUK (cool passage) ----------
var sx0 = 34, sx1 = 46, sz0 = 37, sz1 = 47, scx = 40, scz = 42;
var sTop = walkY + 5;   // y13
fill(sx0, floorY, sz0, sx1, floorY, sz1, MARBLE);
makeWalls(sx0, walkY, sz0, sx1, sTop, sz1, LIME);
makeWalls(sx0 + 1, walkY, sz0 + 1, sx1 - 1, sTop, sz1 - 1, LIME);
fill(sx0 + 2, walkY, sz0 + 2, sx1 - 2, sTop + 5, sz1 - 2, 'air');
domeDeck(sx0, sz0, sx1, sz1, sTop + 1, sTop + 2, scx, scz, 4, LIMEFLAT, 0, 0);
makeCylinder(scx, sTop + 1, scz, LIMEFLAT, 5, 2, true);
ribbedDome(scx, scz, sTop + 3, 4, LEAD, RIB, 8);
domeOculi(scx, scz, sTop + 3, 4, 6, 0.4, 'light_blue_stained_glass', 'white_stained_glass');

// ---------- 4. CAMEKAN (changing hall) ----------
var cx0 = 28, cx1 = 52, cz0 = 47, cz1 = 71, ccx = 40, ccz = 59;
var cTop = walkY + 10;  // y18
fill(cx0, floorY, cz0, cx1, floorY, cz1, MARBLE);
makeWalls(cx0, walkY, cz0, cx1, cTop, cz1, LIME);
makeWalls(cx0 + 1, walkY, cz0 + 1, cx1 - 1, cTop, cz1 - 1, LIME);
fill(cx0 + 2, walkY, cz0 + 2, cx1 - 2, cTop + 6, cz1 - 2, 'air');
domeDeck(cx0, cz0, cx1, cz1, cTop + 1, cTop + 2, ccx, ccz, 10, LIMEFLAT, 0, 0);
makeCylinder(ccx, cTop + 1, ccz, LIMEFLAT, 11, 2, true);
ribbedDome(ccx, ccz, cTop + 3, 10, LEAD, RIB, 12);
domeOculi(ccx, ccz, cTop + 3, 10, 10, 0.42, 'light_blue_stained_glass', 'white_stained_glass');

// ---------- 5. FACADE RELIEF: pilasters + string course + cornice (anti flat_walls) ----------
function pilaster(x, z, yTop, dir) {
  fill(x, walkY, z, x, yTop - 1, z, 'cut_sandstone');
  ps(x, yTop, z, 'cut_sandstone_stairs[facing=' + dir + ',half=top]');
  pb(x, walkY - 1, z, 'chiseled_sandstone');
}
var pz;
for (pz = cz0 + 2; pz <= cz1 - 2; pz += 5) {
  pilaster(cx0 - 1, pz, cTop, 'east');
  pilaster(cx1 + 1, pz, cTop, 'west');
}
for (var px = cx0 + 3; px <= cx1 - 3; px += 5) {
  pilaster(px, cz1 + 1, cTop, 'north');
}
for (pz = hcz - 8; pz <= hcz + 8; pz += 5) {
  pilaster(hcx - hR - 1, pz, hTop, 'east');
  pilaster(hcx + hR + 1, pz, hTop, 'west');
}
// string course band + top cornice around the camekan block
function bandRect(x0, z0, x1, z1, y, id) {
  for (var x = x0; x <= x1; x++) { ps(x, y, z0, id); ps(x, y, z1, id); }
  for (var z = z0; z <= z1; z++) { ps(x0, y, z, id); ps(x1, y, z, id); }
}
bandRect(cx0 - 1, cz0 - 1, cx1 + 1, cz1 + 1, walkY + 6, 'cut_sandstone_slab');
bandRect(cx0 - 1, cz0 - 1, cx1 + 1, cz1 + 1, cTop, 'cut_sandstone_slab');
bandRect(sx0 - 1, sz0, sx1 + 1, sz1, sTop, 'cut_sandstone_slab');

// ---------- 6. DOORWAYS + WINDOWS ----------
fill(39, walkY, 70, 41, walkY + 2, 71, 'air');    // portico -> camekan
fill(39, walkY, 46, 41, walkY + 2, 48, 'air');    // camekan -> sogukluk
fill(39, walkY, 36, 41, walkY + 2, 38, 'air');    // sogukluk -> hararet
// arched window with alternating red/cream voussoirs
function archWindow(x, z, y, axis) {
  var i;
  for (i = -1; i <= 1; i++) {
    if (axis === 'x') {
      fill(x, y, z + i, x + 1, y + 2, z + i, 'air');
      fill(x, y, z + i, x + 1, y + 2, z + i, 'light_blue_stained_glass');
    } else {
      fill(x + i, y, z, x + i, y + 2, z + 1, 'air');
      fill(x + i, y, z, x + i, y + 2, z + 1, 'light_blue_stained_glass');
    }
  }
  for (i = -2; i <= 2; i++) {
    var vy = y + 3 + (i === 0 ? 1 : (Math.abs(i) === 1 ? 1 : 0));
    var vid = (Math.abs(i) % 2 === 0) ? 'smooth_quartz' : 'red_terracotta';
    if (axis === 'x') { pb(x, vy, z + i, vid); pb(x + 1, vy, z + i, vid); }
    else { pb(x + i, vy, z, vid); pb(x + i, vy, z + 1, vid); }
  }
}
var wz;
for (wz = cz0 + 5; wz <= cz1 - 5; wz += 7) {
  archWindow(cx0, wz, walkY + 2, 'x');
  archWindow(cx1 - 1, wz, walkY + 2, 'x');
}
archWindow(36, cz1 - 1, walkY + 2, 'z');
archWindow(44, cz1 - 1, walkY + 2, 'z');

// ---------- 7. PORTICO with alternating red/cream voussoir arches ----------
var poZ = 75, piers = [31, 37, 43, 49];
var pi;
for (pi = 0; pi < piers.length; pi++) {
  fill(piers[pi], walkY, poZ, piers[pi] + 1, walkY + 9, poZ + 1, LIMEFLAT);
  pb(piers[pi], walkY - 1, poZ, 'chiseled_sandstone');
}
// three semicircular arches, r=3, springing y = walkY+7
function voussoirArch(cxA, yS, zA, r) {
  for (var k = 0; k <= 24; k++) {
    var a = Math.PI * k / 24;
    var ax = cxA - Math.round(r * Math.cos(a));
    var ay = yS + Math.round(r * Math.sin(a));
    var id = ((ax + ay) % 2 === 0) ? 'red_terracotta' : 'smooth_quartz';
    pb(ax, ay, zA, id);
    pb(ax, ay, zA + 1, id);
  }
}
for (pi = 0; pi < piers.length - 1; pi++) {
  voussoirArch(piers[pi] + 4, walkY + 7, poZ, 3);
}
// portico roof: flat lead deck + cornice + small half domes
fill(31, walkY + 11, poZ - 1, 50, walkY + 11, poZ + 2, LIMEFLAT);
bandRect(30, poZ - 2, 51, poZ + 3, walkY + 12, 'cut_sandstone_slab');
for (pi = 0; pi < piers.length - 1; pi++) {
  ribbedDome(piers[pi] + 4, poZ + 1, walkY + 12, 3, LEAD, RIB, 6);
}
// entrance steps
fill(37, walkY - 1, poZ + 2, 43, walkY - 1, poZ + 3, 'smooth_sandstone');
ps(37, walkY - 1, poZ + 4, 'sandstone_stairs[facing=south]');
fill(37, walkY - 2, poZ + 4, 43, walkY - 2, poZ + 4, 'smooth_sandstone');

// ---------- 8. INTERIOR: CAMEKAN (fountain, benches, gallery, light) ----------
// octagonal fountain pool
makeCylinder(ccx, walkY, ccz, 'quartz_bricks', 4, 1, true);
for (var fx = ccx - 3; fx <= ccx + 3; fx++) {
  for (var fz = ccz - 3; fz <= ccz + 3; fz++) {
    if (dist2(fx, fz, ccx, ccz) <= 3.2) { pb(fx, floorY, fz, 'water'); pb(fx, walkY, fz, 'water'); }
  }
}
fill(ccx, floorY, ccz, ccx, walkY + 2, ccz, 'quartz_pillar');
pb(ccx, walkY + 3, ccz, 'chiseled_quartz_block');
pb(ccx, walkY + 4, ccz, 'sea_lantern');
// benches along the side walls (chairStair -> auto facing toward the room centre)
var bz;
for (bz = cz0 + 4; bz <= cz1 - 4; bz++) {
  if (bz % 2 === 0) continue;
  chairStair(cx0 + 2, walkY, bz, 'spruce_stairs', 'east');
  chairStair(cx1 - 2, walkY, bz, 'spruce_stairs', 'west');
}
rug(34, walkY, 52, 5, 5, 'red', 'orange');
rug(44, walkY, 64, 5, 5, 'red', 'orange');
// ---- wooden upper gallery (y13 floor, walk 14) on 3 sides ----
var gFloor = 13;
fill(cx0 + 2, gFloor, cz0 + 2, cx0 + 4, gFloor, cz1 - 2, 'spruce_planks');   // west strip
fill(cx1 - 4, gFloor, cz0 + 2, cx1 - 2, gFloor, cz1 - 2, 'spruce_planks');   // east strip
fill(cx0 + 2, gFloor, cz0 + 2, cx1 - 2, gFloor, cz0 + 4, 'spruce_planks');   // north strip
// support posts + brackets so nothing floats
var gz;
for (gz = cz0 + 3; gz <= cz1 - 3; gz += 4) {
  fill(cx0 + 4, walkY, gz, cx0 + 4, gFloor - 1, gz, 'stripped_spruce_log[axis=y]');
  fill(cx1 - 4, walkY, gz, cx1 - 4, gFloor - 1, gz, 'stripped_spruce_log[axis=y]');
  pb(cx0 + 4, gFloor, gz, 'spruce_planks');
  pb(cx1 - 4, gFloor, gz, 'spruce_planks');
}
for (var gx = cx0 + 6; gx <= cx1 - 6; gx += 4) {
  fill(gx, walkY, cz0 + 4, gx, gFloor - 1, cz0 + 4, 'stripped_spruce_log[axis=y]');
}
// railing
for (gz = cz0 + 2; gz <= cz1 - 2; gz++) {
  pb(cx0 + 5, gFloor + 1, gz, 'spruce_fence');
  pb(cx1 - 5, gFloor + 1, gz, 'spruce_fence');
}
for (gx = cx0 + 5; gx <= cx1 - 5; gx++) {
  pb(gx, gFloor + 1, cz0 + 5, 'spruce_fence');
}
// gallery furnishing
rug(cx0 + 2, gFloor + 1, cz0 + 8, 3, 6, 'light_blue', 'blue');
rug(cx1 - 4, gFloor + 1, cz0 + 8, 3, 6, 'light_blue', 'blue');
chairStair(cx0 + 2, gFloor + 1, cz0 + 16, 'spruce_stairs', 'east');
chairStair(cx1 - 2, gFloor + 1, cz0 + 16, 'spruce_stairs', 'west');
// STAIR to the gallery (helper guarantees navigable run + floor hole)
staircase(cx0 + 3, cz1 - 3, walkY, gFloor + 1, 'north', { width: 2, material: 'spruce_stairs', rail: 'spruce_fence' });
// lighting
var lz;
for (lz = cz0 + 4; lz <= cz1 - 4; lz += 5) {
  pb(cx0 + 2, walkY + 4, lz, 'lantern[hanging=false]');
  pb(cx1 - 2, walkY + 4, lz, 'lantern[hanging=false]');
  pb(cx0 + 5, gFloor + 2, lz, 'lantern[hanging=false]');
  pb(cx1 - 5, gFloor + 2, lz, 'lantern[hanging=false]');
}

// ---------- 9. INTERIOR: SOGUKLUK ----------
chairStair(sx0 + 2, walkY, scz - 2, 'spruce_stairs', 'east');
chairStair(sx1 - 2, walkY, scz - 2, 'spruce_stairs', 'west');
chairStair(sx0 + 2, walkY, scz + 2, 'spruce_stairs', 'east');
chairStair(sx1 - 2, walkY, scz + 2, 'spruce_stairs', 'west');
function basin(bx, by, bz2, facingA, facingB) {
  pb(bx, by - 1, bz2, 'quartz_bricks');
  pb(bx, by, bz2, 'water');
  ps(bx - 1, by, bz2, 'quartz_stairs[facing=' + facingA + ']');
  ps(bx + 1, by, bz2, 'quartz_stairs[facing=' + facingB + ']');
  pb(bx, by + 2, bz2, 'lantern[hanging=false]');
}
basin(scx - 3, walkY, sz0 + 2, 'east', 'west');
basin(scx + 3, walkY, sz0 + 2, 'east', 'west');
pb(scx, walkY + 4, scz, 'lantern[hanging=true]');

// ---------- 10. INTERIOR: HARARET (gobektasi + alcove basins) ----------
for (var gx2 = hcx - 3; gx2 <= hcx + 3; gx2++) {
  for (var gz2 = hcz - 3; gz2 <= hcz + 3; gz2++) {
    if (Math.abs(gx2 - hcx) + Math.abs(gz2 - hcz) > 4) continue;
    fill(gx2, walkY, gz2, gx2, walkY + 1, gz2, 'smooth_quartz');
  }
}
pb(hcx, walkY + 2, hcz, 'chiseled_quartz_block');
ps(hcx - 4, walkY, hcz, 'quartz_stairs[facing=west]');
ps(hcx + 4, walkY, hcz, 'quartz_stairs[facing=east]');
ps(hcx, walkY, hcz - 4, 'quartz_stairs[facing=north]');
ps(hcx, walkY, hcz + 4, 'quartz_stairs[facing=south]');
// 4 corner alcoves carved into the inner wall face, each with a basin
function alcove(ax, az, dirA, dirB) {
  fill(ax - 1, walkY, az, ax + 1, walkY + 2, az, 'air');
  basin(ax, walkY, az, dirA, dirB);
}
alcove(hcx - 7, hcz - 5, 'east', 'west');
alcove(hcx + 7, hcz - 5, 'east', 'west');
alcove(hcx - 7, hcz + 5, 'east', 'west');
alcove(hcx + 7, hcz + 5, 'east', 'west');
var hz;
for (hz = hcz - 6; hz <= hcz + 6; hz += 6) {
  pb(hcx - 8, walkY + 3, hz, 'lantern[hanging=false]');
  pb(hcx + 8, walkY + 3, hz, 'lantern[hanging=false]');
}
rug(hcx - 8, walkY, hcz - 2, 3, 5, 'red', 'orange');
rug(hcx + 6, walkY, hcz - 2, 3, 5, 'red', 'orange');

// ---------- 11. EXTERIOR: courtyard, cypresses, lamps, garden wall ----------
var court = noisePalette([
  { block: 'smooth_stone', weight: 40 },
  { block: 'polished_andesite', weight: 30 },
  { block: 'stone_bricks', weight: 20 },
  { block: 'cracked_stone_bricks', weight: 10 }
], { seed: 21, freq: 0.12 });
for (var qx = 25; qx <= 55; qx++) {
  for (var qz = 72; qz <= 80; qz++) {
    if (dist2(qx, qz, 40, 76) > 17) continue;
    pb(qx, padY, qz, court);
  }
}
function cypress(tx, tz) {
  fill(tx, padY + 1, tz, tx, padY + 9, tz, 'spruce_log[axis=y]');
  makeCone(tx, padY + 2, tz, noisePalette([{ block: 'spruce_leaves[persistent=true]', weight: 70 }, { block: 'azalea_leaves[persistent=true]', weight: 30 }], { seed: 4 }), 2, 9, false);
}
cypress(27, 74); cypress(53, 74); cypress(24, 66); cypress(56, 66);
cypress(24, 30); cypress(56, 30);
lampPost(33, padY + 1, 79, 4, 'cobblestone_wall');
lampPost(47, padY + 1, 79, 4, 'cobblestone_wall');
lampPost(26, padY + 1, 58, 4, 'cobblestone_wall');
lampPost(54, padY + 1, 58, 4, 'cobblestone_wall');
// low garden wall with planted beds
var wx;
for (wx = 22; wx <= 58; wx += 1) {
  pb(wx, padY + 1, 82, 'sandstone_wall');
}
for (wx = 24; wx <= 56; wx += 8) {
  pb(wx, padY + 2, 82, 'lantern[hanging=false]');
  pb(wx, padY + 1, 81, 'flowering_azalea');
}

Static Renders

Ottoman Hammam (guided, fixed) isometric viewisometric
Ottoman Hammam (guided, fixed) front viewfront
Ottoman Hammam (guided, fixed) side viewside
Ottoman Hammam (guided, fixed) back viewback
Ottoman Hammam (guided, fixed) top viewtop