← Back to Gallery

Loading 3D viewer…

Ottoman Hammam (indexed)

by Jorge Barbero

Dimensions
88×44×76
Blocks
61,259
Compute Time
7.7s
Generation Time
26.7s
Model
claude-opus-5
Created
August 24, 2026
ottomanhammamdomeinteriorindexedautoeval
Prompt

User Prompt

an Ottoman stone hammam (bathhouse): squat sandstone block with a large ribbed central dome over the hot room flanked by two smaller domes, arched entrance portal with a stepped muqarnas hood, star-shaped skylight holes, interior with a raised octagonal marble navel-stone, water basins in wall niches, a stair up to a raised gallery, warm lantern light

Enhanced Prompt

indexed condition: prepare_build + search_docs({action:"related"}) routing then read of the returned sections (Roof intrusion into rooms, Wizard Tower Interior, Natural Terrain Superpowers). Independent design: cross-plan hammam, camekan with gallery ring, ribbed dome hot room, two halvet corner cells.

Photos

Exterior
Exteriorexterior
Camekan
Camekaninterior
Hot room
Hot roominterior
Gallery stair
Gallery stairinterior
CraftScript Source
// === BUILD PLAN ===
// Style: Ottoman hammam, cross-plan: camekan (domed hall + gallery ring) -> passage -> sicaklik (ribbed dome)
//        with two halvet (private cell) domes budding off the far side
// Footprint: camekan X20..34 Z30..44 (dome R6, top y20) | passage X34..38 Z35..39 | sicaklik X38..54 Z28..44
//            (RIBBED dome R7, top y19) | halvets X54..60 Z29..35 & Z37..43 (domes R3) | portico X22..32 Z26..30
// Height: floorY=9 walkY=10; gallery walk 16; dome apexes ~27
// GROUND FLOOR: [portico p] -> D door -> camekan (pool + gallery ring) == passage == sicaklik (O navel, basins) == halvets
// MATERIALS: walls gradientPalette sandstone->cut->smooth (fake AO); chiseled pilasters + terracotta band + stair cornice
//            domes deepslate->andesite lead ramp, cut_sandstone ribs; interior quartz marble + prismarine; dark_oak gallery
// STAIR PLAN: camekan walk 10 -> gallery walk 16 (D=6) -> staircase(32,41,10,16,"north"), width 2
// === END PLAN ===

var floorY = 9, walkY = 10, padY = 8;

terrain({ cx:40, cz:36, radius:36, baseY:padY, amp:3, scale:0.05, seed:77,
          surface:[{block:'sand',weight:50},{block:'coarse_dirt',weight:25},{block:'grass_block',weight:15},{block:'sandstone',weight:10}],
          sub:'sandstone', deep:'sandstone', depth:4,
          pads:[{cx:40, cz:36, r:30, y:padY, falloff:7}] });

var stonePal = gradientPalette(floorY, 20, [
  {block:'sandstone', from:0},
  {block:'cut_sandstone', from:0.4},
  {block:'smooth_sandstone', from:0.8}], {noise:0.2, seed:31});
var marble = noisePalette([{block:'quartz_block',weight:50},{block:'smooth_quartz',weight:35},{block:'quartz_bricks',weight:15}], {seed:5, freq:0.13});

function room(x1, z1, x2, z2, topY, floorBlock){
  makeWalls(x1, floorY, z1, x2, topY, z2, stonePal);
  fill(x1, floorY, z1, x2, floorY, z2, floorBlock);
  fill(x1+1, walkY, z1+1, x2-1, topY, z2-1, 'air');
  fill(x1, topY+1, z1, x2, topY+1, z2, 'smooth_sandstone');
}
function domeOn(cx, cz, deckY, R, ribbed){
  var dy, dx, dz, outerR, innerR, d2, ang, k, isRib, frac, jit, shell;
  for (dy = 0; dy < 2; dy++)
    for (dx = -R; dx <= R; dx++)
      for (dz = -R; dz <= R; dz++){
        d2 = dx*dx + dz*dz;
        if (d2 <= R*R + R && d2 >= (R-1)*(R-1)) pb(cx+dx, deckY+1+dy, cz+dz, 'cut_sandstone');
      }
  var baseY = deckY + 3;
  for (dy = 0; dy <= R; dy++){
    outerR = Math.round(Math.sqrt(R*R - dy*dy));
    innerR = Math.round(Math.sqrt(Math.max(0, (R-1)*(R-1) - dy*dy)));
    for (dx = -outerR; dx <= outerR; dx++)
      for (dz = -outerR; dz <= outerR; dz++){
        d2 = dx*dx + dz*dz;
        if (d2 <= outerR*outerR + outerR && !(d2 <= innerR*innerR)){
          isRib = false;
          if (ribbed && dy < R - 1){
            ang = Math.atan2(dz, dx);
            k = Math.abs(((ang + Math.PI) / (Math.PI/4)) % 1);
            if (k < 0.15 || k > 0.85) isRib = true;
          }
          frac = dy / R;
          jit = ((cx+dx)*5 + (cz+dz)*11 + dy) % 4;
          shell = (frac + jit*0.04 < 0.4) ? 'deepslate' : ((frac + jit*0.04 < 0.8) ? 'andesite' : 'polished_andesite');
          pb(cx+dx, baseY+dy, cz+dz, isRib ? 'cut_sandstone' : shell);
        }
      }
  }
  var hr = R - 2;
  for (dy = 0; dy < R; dy++){
    innerR = Math.round(Math.sqrt(Math.max(0, (R-1)*(R-1) - dy*dy)));
    for (dx = -innerR; dx <= innerR; dx++)
      for (dz = -innerR; dz <= innerR; dz++)
        if (dx*dx + dz*dz <= innerR*innerR) pb(cx+dx, baseY+dy, cz+dz, 'air');
  }
  for (dy = deckY; dy <= deckY + 2; dy++)
    for (dx = -hr; dx <= hr; dx++)
      for (dz = -hr; dz <= hr; dz++)
        if (dx*dx + dz*dz <= hr*hr + 1) pb(cx+dx, dy, cz+dz, 'air');
  var pts = [[0,0],[1,0],[-1,0],[0,1],[0,-1],[1,1],[-1,-1],[2,0],[0,2],[-2,0],[0,-2]];
  var i, r2, yy;
  for (i = 0; i < pts.length; i++){
    r2 = Math.sqrt(pts[i][0]*pts[i][0] + pts[i][1]*pts[i][1]);
    yy = baseY + Math.round(Math.sqrt(Math.max(0, R*R - r2*r2)));
    pb(cx+pts[i][0], yy, cz+pts[i][1], (i % 3 === 0) ? 'orange_stained_glass' : 'yellow_stained_glass');
  }
  pb(cx, baseY + R + 1, cz, 'glowstone');
}
function pilasters(x1, z1, x2, z2, topY, step){
  var x, z;
  for (x = x1; x <= x2; x += step){
    fill(x, floorY, z1, x, topY-1, z1, 'chiseled_sandstone');
    fill(x, floorY, z2, x, topY-1, z2, 'chiseled_sandstone');
    ps(x, topY, z1, 'cut_sandstone_slab[type=top]');
    ps(x, topY, z2, 'cut_sandstone_slab[type=top]');
  }
  for (z = z1; z <= z2; z += step){
    fill(x1, floorY, z, x1, topY-1, z, 'chiseled_sandstone');
    fill(x2, floorY, z, x2, topY-1, z, 'chiseled_sandstone');
    ps(x1, topY, z, 'cut_sandstone_slab[type=top]');
    ps(x2, topY, z, 'cut_sandstone_slab[type=top]');
  }
}
function bandRing(x1, z1, x2, z2, y, blockId){
  var x, z;
  for (x = x1; x <= x2; x++){ pb(x, y, z1, blockId); pb(x, y, z2, blockId); }
  for (z = z1; z <= z2; z++){ pb(x1, y, z, blockId); pb(x2, y, z, blockId); }
}
function corniceRing(x1, z1, x2, z2, y){
  var x, z;
  for (x = x1; x <= x2; x++){ roofStair(x, y, z1-1, 'sandstone_stairs', 'south'); roofStair(x, y, z2+1, 'sandstone_stairs', 'north'); }
  for (z = z1-1; z <= z2+1; z++){ roofStair(x1-1, y, z, 'sandstone_stairs', 'east'); roofStair(x2+1, y, z, 'sandstone_stairs', 'west'); }
}

var topCam = 20, topSic = 19, topHal = 15, topPas = 14;
room(20, 30, 34, 44, topCam, 'smooth_sandstone');
room(38, 28, 54, 44, topSic, 'smooth_sandstone');
room(54, 29, 60, 35, topHal, 'polished_andesite');
room(54, 37, 60, 43, topHal, 'polished_andesite');
room(34, 35, 38, 39, topPas, 'polished_diorite');

fill(34, walkY, 36, 34, walkY+2, 38, 'air');
fill(38, walkY, 36, 38, walkY+2, 38, 'air');
fill(54, walkY, 31, 54, walkY+2, 33, 'air');
fill(54, walkY, 39, 54, walkY+2, 41, 'air');

pilasters(20, 30, 34, 44, topCam, 3);
pilasters(38, 28, 54, 44, topSic, 4);
bandRing(20, 30, 34, 44, 15, 'terracotta');
bandRing(38, 28, 54, 44, 15, 'terracotta');
corniceRing(20, 30, 34, 44, topCam + 1);
corniceRing(38, 28, 54, 44, topSic + 1);
corniceRing(54, 29, 60, 35, topHal + 1);
corniceRing(54, 37, 60, 43, topHal + 1);
var wz;
for (wz = 31; wz <= 41; wz += 5){
  ps(38, 16, wz, 'orange_stained_glass');
  ps(54, 16, wz, 'orange_stained_glass');
  pb(38, 17, wz, 'sandstone_slab[type=bottom]');
  pb(54, 17, wz, 'sandstone_slab[type=bottom]');
}

domeOn(27, 37, topCam + 1, 6, false);
domeOn(46, 36, topSic + 1, 7, true);
domeOn(57, 32, topHal + 1, 3, false);
domeOn(57, 40, topHal + 1, 3, false);
var pv;
for (pv = 35; pv <= 37; pv++){
  roofStair(35, topPas, pv, 'cut_sandstone_stairs', 'west');
  roofStair(37, topPas, pv, 'cut_sandstone_stairs', 'east');
}

var col;
for (col = 22; col <= 32; col += 4){
  fill(col, floorY, 27, col, 15, 27, 'quartz_pillar[axis=y]');
  pb(col, 16, 27, 'chiseled_quartz_block');
}
fill(21, 16, 26, 33, 16, 28, 'smooth_sandstone');
fill(21, 17, 26, 33, 17, 28, 'cut_sandstone');
corniceRing(22, 27, 32, 28, 17);
fill(21, padY+1, 27, 33, padY+1, 29, 'polished_diorite');
fill(26, walkY, 30, 28, walkY+2, 30, 'air');
ps(27, walkY, 30, 'dark_oak_door[facing=north,half=lower,hinge=left]');
ps(27, walkY+1, 30, 'dark_oak_door[facing=north,half=upper,hinge=left]');
var h, hy, half, hx;
for (h = 0; h < 4; h++){
  hy = walkY + 3 + h;
  half = 3 - h;
  for (hx = 27 - half; hx <= 27 + half; hx++) pb(hx, hy, 29, 'chiseled_sandstone');
  roofStair(27 - half - 1, hy, 29, 'cut_sandstone_stairs', 'west');
  roofStair(27 + half + 1, hy, 29, 'cut_sandstone_stairs', 'east');
}
pb(27, walkY + 7, 29, 'sandstone_wall');
pb(27, walkY + 8, 29, 'lantern[hanging=false]');

fill(21, floorY, 31, 33, floorY, 43, marble);
fill(21, walkY, 31, 33, walkY+3, 31, 'smooth_quartz');
fill(21, walkY, 43, 33, walkY+3, 43, 'smooth_quartz');
fill(21, walkY, 31, 21, walkY+3, 43, 'smooth_quartz');
fill(33, walkY, 31, 33, walkY+3, 43, 'smooth_quartz');
var px, pz, dman;
for (px = 24; px <= 30; px++)
  for (pz = 34; pz <= 40; pz++){
    dman = Math.abs(px-27) + Math.abs(pz-37);
    if (dman <= 3) pb(px, floorY, pz, 'water');
    else if (dman === 4) pb(px, floorY, pz, 'polished_diorite');
  }
pb(27, floorY+1, 37, 'water');
var bz2;
for (bz2 = 33; bz2 <= 41; bz2 += 2){
  chairStair(22, walkY, bz2, 'dark_oak_stairs', 'east');
  chairStair(32, walkY, bz2, 'dark_oak_stairs', 'west');
}
var cxx;
for (cxx = 24; cxx <= 30; cxx++) { ps(cxx, walkY, 32, 'red_carpet'); ps(cxx, walkY, 42, 'orange_carpet'); }
pb(23, walkY, 32, 'flower_pot'); pb(31, walkY, 32, 'flower_pot');
pb(23, walkY, 42, 'barrel[facing=up]'); pb(24, walkY, 42, 'barrel[facing=up]');
fill(21, 15, 31, 33, 15, 33, 'dark_oak_planks');
fill(30, 15, 34, 33, 15, 41, 'dark_oak_planks');
var gp;
for (gp = 21; gp <= 33; gp += 3) fill(gp, walkY, 33, gp, 14, 33, 'dark_oak_fence');
for (gp = 35; gp <= 41; gp += 3) fill(30, walkY, gp, 30, 14, gp, 'dark_oak_fence');
for (gp = 21; gp <= 29; gp++) pb(gp, 16, 33, 'dark_oak_fence');
for (gp = 34; gp <= 40; gp++) pb(30, 16, gp, 'dark_oak_fence');
staircase(32, 41, walkY, 16, 'north', {width:2, material:'dark_oak_stairs', rail:true, support:'cut_sandstone'});
placeBed(23, 16, 32, 'red', 'east');
pb(26, 16, 32, 'dark_oak_fence'); ps(26, 17, 32, 'white_carpet');
chairStair(27, 16, 32, 'dark_oak_stairs', 'west');
pb(22, 16, 32, 'lantern[hanging=false]');
pb(32, 16, 36, 'lectern[facing=west]');
var lz;
for (lz = 33; lz <= 41; lz += 4){ pb(21, 18, lz, 'lantern[hanging=true]'); pb(33, 18, lz, 'lantern[hanging=true]'); }

fill(39, floorY, 29, 53, floorY, 43, marble);
fill(39, walkY, 29, 53, walkY+4, 29, 'smooth_quartz');
fill(39, walkY, 43, 53, walkY+4, 43, 'smooth_quartz');
fill(39, walkY, 29, 39, walkY+4, 43, 'smooth_quartz');
fill(53, walkY, 29, 53, walkY+4, 43, 'smooth_quartz');
var nx, nz, dm;
for (nx = 41; nx <= 51; nx++)
  for (nz = 31; nz <= 41; nz++){
    dm = Math.abs(nx-46) + Math.abs(nz-36);
    if (dm <= 7 && Math.abs(nx-46) <= 5 && Math.abs(nz-36) <= 5) pb(nx, floorY+1, nz, (dm <= 4) ? 'quartz_block' : 'smooth_quartz');
  }
for (nx = 44; nx <= 48; nx++)
  for (nz = 34; nz <= 38; nz++)
    pb(nx, floorY+2, nz, (((nx+nz) % 2) === 0) ? 'quartz_bricks' : 'calcite');
pb(46, floorY+2, 36, 'sea_lantern');
function nicheBasin(x, z, dx, dz){
  var i;
  for (i = 0; i < 3; i++) pb(x + dx, walkY + i, z + dz, 'air');
  pb(x + dx, walkY + 3, z + dz, 'chiseled_sandstone');
  ps(x + dx, walkY, z + dz, 'cauldron');
  pb(x + dx, floorY, z + dz, 'prismarine_bricks');
  pb(x + dx, walkY + 2, z + dz, 'lantern[hanging=true]');
}
nicheBasin(39, 32, -1, 0);
nicheBasin(39, 40, -1, 0);
nicheBasin(53, 32,  1, 0);
nicheBasin(53, 40,  1, 0);
var cor = [[40,30],[52,30],[40,42],[52,42]];
var ci2;
for (ci2 = 0; ci2 < cor.length; ci2++){
  fill(cor[ci2][0], walkY, cor[ci2][1], cor[ci2][0], 17, cor[ci2][1], 'quartz_pillar[axis=y]');
  pb(cor[ci2][0], 18, cor[ci2][1], 'chiseled_quartz_block');
}
var mb2;
for (mb2 = 32; mb2 <= 40; mb2 += 2){ chairStair(40, walkY, mb2, 'quartz_stairs', 'east'); chairStair(52, walkY, mb2, 'quartz_stairs', 'west'); }
var wcx;
for (wcx = 41; wcx <= 51; wcx++){ pb(wcx, floorY, 30, 'water'); pb(wcx, floorY, 42, 'water'); }
var lp = [[42,32],[50,32],[42,40],[50,40]];
var lpi;
for (lpi = 0; lpi < lp.length; lpi++){
  pb(lp[lpi][0], 18, lp[lpi][1], 'chain');
  pb(lp[lpi][0], 17, lp[lpi][1], 'lantern[hanging=true]');
}

function halvet(x1, z1, x2, z2){
  var cx = Math.floor((x1+x2)/2), cz = Math.floor((z1+z2)/2);
  fill(x1+1, floorY, z1+1, x2-1, floorY, z2-1, 'polished_andesite');
  ps(cx, walkY, cz+1, 'cauldron');
  pb(cx, floorY, cz+1, 'prismarine_bricks');
  chairStair(cx-1, walkY, cz-1, 'quartz_stairs', 'east');
  pb(cx+1, walkY, cz-1, 'quartz_slab[type=bottom]');
  pb(cx, 13, cz, 'chain');
  pb(cx, 12, cz, 'lantern[hanging=true]');
}
halvet(54, 29, 60, 35);
halvet(54, 37, 60, 43);

var fx, fz, dxx, dzz;
for (fx = 16; fx <= 40; fx++)
  for (fz = 18; fz <= 28; fz++){
    dxx = fx - 27; dzz = fz - 24;
    if (dxx*dxx*0.45 + dzz*dzz < 70) pb(fx, padY, fz, (((fx + fz) % 5) === 0) ? 'polished_diorite' : 'smooth_sandstone');
  }
for (fz = 18; fz <= 60; fz++){ pb(16, padY, fz, 'smooth_sandstone'); pb(17, padY, fz, 'sandstone'); }
makeCylinder(24, padY, 20, 'cut_sandstone', 3, 1, false);
makeCylinder(24, padY+1, 20, 'sandstone_wall', 3, 1, true);
makeCylinder(24, padY+1, 20, 'water', 2, 1, false);
pb(24, padY+1, 20, 'quartz_pillar[axis=y]');
pb(24, padY+2, 20, 'water');
function post(x, z){
  var i;
  for (i = 0; i < 3; i++) pb(x, padY+1+i, z, 'cut_sandstone_wall');
  pb(x, padY+4, z, 'chiseled_sandstone');
  pb(x, padY+5, z, 'lantern[hanging=true]');
}
post(20, 25); post(34, 25); post(18, 46); post(62, 30);
var trees = [[18,32],[18,42],[36,22],[64,36],[62,46],[30,50]];
var ti, tx, tz;
for (ti = 0; ti < trees.length; ti++){
  tx = trees[ti][0]; tz = trees[ti][1];
  fill(tx, padY+1, tz, tx, padY+6, tz, 'spruce_log[axis=y]');
  makeSphere(tx, padY+7, tz, 'spruce_leaves[persistent=true]', 2, 3, 2, true);
  makeSphere(tx, padY+5, tz, 'spruce_leaves[persistent=true]', 2, 2, 2, true);
}
var sx, sz, nv;
for (sx = 12; sx <= 72; sx++)
  for (sz = 14; sz <= 60; sz++){
    if (sx >= 16 && sx <= 62 && sz >= 24 && sz <= 46) continue;
    nv = noise2d('perlin', sx, sz, {freq:0.3, seed:19});
    if (nv > 0.85) pb(sx, padY+1, sz, 'dead_bush');
  }
var ex;
for (ex = 24; ex <= 30; ex++) roofStair(ex, padY+1, 26, 'sandstone_stairs', 'north');

Static Renders

Ottoman Hammam (indexed) isometric viewisometric
Ottoman Hammam (indexed) front viewfront
Ottoman Hammam (indexed) side viewside
Ottoman Hammam (indexed) back viewback
Ottoman Hammam (indexed) top viewtop