← Back to Gallery

Loading 3D viewer…

Indian stepwell (baoli) — indexed

by Jorge Barbero

Dimensions
64×40×88
Blocks
160,382
Compute Time
9.4s
Generation Time
2m 7s
Edits
1
Model
claude-opus-5
Created
August 29, 2026
autoevalindexedlarge_structuresstepwell
Prompt

User Prompt

an Indian stepwell (baoli): a square sunken stone water tank descending four terraced levels underground, symmetrical flights of sandstone steps on each side going down to the green water, colonnaded pavilion galleries with carved pillars on each terrace, chhatri domed kiosks at the rim, ochre and pale sandstone with carved niches

Photos

Exterior
Exteriorexterior
Corredor escalonado
Corredor escalonadointerior
Pozo y galerias
Pozo y galeriasinterior
Pabellon y escalera
Pabellon y escalerainterior
CraftScript Source
// === BUILD PLAN ===
// Style: Gujarati stepwell (vav) — Adalaj type: LINEAR stepped corridor + octagonal well shaft
// Footprint: trench 13 wide (x26..38) x 60 long (z10..70), centre x=32; ground top Y=26 (walk 27)
// Depth: entry Y25 -> corridor descends 1 step / 2 blocks -> landing Y7 -> water Y8 -> shaft floor Y3
//
// SIDE VIEW (north -> south):
//   [torana]  ___
//    ####\__       __ pavilion  __ pavilion  __ pavilion
//         \__          |  |         |  |        |  |
//            \__ steps  \ |          \ |         \|      ___
//               \_______________________________________|~~~|  octagonal shaft
//                                              landing Y7 ~~~ water Y8, floor Y3
//
// TOP VIEW:
//   z10 torana gate | z12-48 stepped corridor (11 wide) | z49-52 landing
//   z53-68 well shaft with 3 ring galleries (Y12/Y17/Y22) | side retaining walls x26 & x38
//
// MATERIALS PLAN:
//   walls/steps upper: noisePalette sandstone(32)+cut_sandstone(28)+smooth_sandstone(24)+chiseled(9)+red_sandstone(7)
//                      — WHY: ochre ramp with carved-stone speckle
//   lower/damp       : gradientPalette moss_block -> mud? no -> moss->sandstone->smooth (Y3..Y16)
//                      — WHY: algae line at the water, fakes depth
//   pillars/lintels  : cut_sandstone + chiseled capitals — WHY: light frame contrast against speckled walls
//   domes/cornices   : red_sandstone + red_sandstone_stairs — WHY: ochre accent
//   ground           : patches sand/coarse_dirt/grass/terracotta
// Rooms: 3 covered pavilion bays over the corridor (galleries at 2 levels), shaft ring galleries
// STAIR PLAN: corridor itself is the stair — 1 block down every 2 blocks of Z (fully navigable ramp of steps)
// === END PLAN ===

function ck(s){ try { print(s); } catch(e) {} }

var cx = 32;
var GY = 26;              // top solid ground; walk 27
var WY = 8;               // water surface in the shaft

var stone = noisePalette([
  {block:"sandstone",         weight:32},
  {block:"cut_sandstone",     weight:28},
  {block:"smooth_sandstone",  weight:24},
  {block:"chiseled_sandstone",weight:9},
  {block:"red_sandstone",     weight:7}
], {seed:17, freq:0.10});

var damp = gradientPalette(3, 16, [
  {block:"moss_block",       from:0},
  {block:"sandstone",        from:0.35},
  {block:"smooth_sandstone", from:0.75}
], {noise:0.3, seed:23});

function floorAt(z) {
  if (z < 12) return GY;
  if (z <= 48) return 25 - Math.floor((z - 12) / 2);
  if (z <= 52) return 7;
  return 3;
}

var x, z, y, t, i, k;

// === 1. BASE ROCK + TERRAIN ===
ck("TERRAIN");
fill(2, 0, 2, 61, 22, 85, "stone");
var land = blob(cx, 44, 40, {irregularity:0.28, seed:31});
var h = hills({base: GY - 2, amp: 3, scale: 0.04, seed: 12});
var pad = flatten(h, {x0: 6, z0: 4, x1: 58, z1: 82}, GY, 6);
var gmat = patches([
  {block:"sand", w:34},
  {block:"coarse_dirt", w:26},
  {block:"grass_block", w:24},
  {block:"terracotta", w:16}
], 0.055, 21);
surface(land, pad, gmat, {sub:"dirt", deep:"stone", depth:4});

// === 2. CARVE THE TRENCH + SHAFT ===
ck("TRENCH");
fill(cx-6, 0, 10, cx+6, GY+9, 70, "air");

// === 3. STEPPED CORRIDOR FLOOR ===
ck("STEPS");
for (z = 10; z <= 52; z++) {
  var ft = floorAt(z);
  for (x = cx-5; x <= cx+5; x++) {
    fill(x, ft-4, z, x, ft, z, (ft <= 16) ? damp : stone);
  }
}
// shaft floor
for (z = 53; z <= 69; z++) {
  for (x = cx-5; x <= cx+5; x++) {
    fill(x, 0, z, x, 3, z, damp);
  }
}
// water in the shaft
fill(cx-5, 4, 53, cx+5, WY, 69, "water");
// submerged approach steps from the landing into the water
for (k = 0; k < 3; k++) {
  fill(cx-5, 4+k, 53+k, cx+5, 4+k, 53+k, damp);
}

// === 4. SIDE RETAINING WALLS (with pilasters + niches) ===
ck("WALLS");
for (z = 10; z <= 69; z++) {
  var fy = floorAt(z);
  fill(cx-6, fy-4, z, cx-6, GY, z, stone);
  fill(cx+6, fy-4, z, cx+6, GY, z, stone);
  if (z % 4 === 0) {                       // pilaster relief every 4 blocks
    fill(cx-5, fy+1, z, cx-5, GY, z, "cut_sandstone");
    fill(cx+5, fy+1, z, cx+5, GY, z, "cut_sandstone");
  }
  if (z % 6 === 3 && z < 53) {             // carved niche + lantern
    pb(cx-6, fy+2, z, "chiseled_sandstone");
    pb(cx+6, fy+2, z, "chiseled_sandstone");
    pb(cx-5, fy+3, z, "lantern[hanging=true]");
    pb(cx+5, fy+3, z, "lantern[hanging=true]");
  }
}
// back wall of the shaft
fill(cx-6, 0, 70, cx+6, GY, 70, stone);
for (y = 6; y <= 22; y += 5) {
  fill(cx-3, y, 70, cx+3, y, 70, "chiseled_sandstone");
}

// === 5. PAVILION BAYS OVER THE CORRIDOR (3 storeys of galleries) ===
ck("PAVILIONS");
function pavilionBay(z0, z1) {
  var fy = floorAt(z0);
  var zz, lv, ly;
  // pillars both sides, floor -> ground level
  for (zz = z0; zz <= z1; zz++) {
    if ((zz - z0) % 3 === 0) {
      fill(cx-5, fy+1, zz, cx-5, GY-1, zz, "cut_sandstone");
      fill(cx+5, fy+1, zz, cx+5, GY-1, zz, "cut_sandstone");
      pb(cx-5, GY-1, zz, "chiseled_sandstone");
      pb(cx+5, GY-1, zz, "chiseled_sandstone");
    }
  }
  // intermediate balcony galleries (2 wide each side) with railings
  for (lv = 1; lv <= 2; lv++) {
    ly = fy + lv * 6;
    if (ly >= GY - 2) break;
    fill(cx-5, ly, z0, cx-4, ly, z1, "smooth_sandstone");
    fill(cx+4, ly, z0, cx+5, ly, z1, "smooth_sandstone");
    for (zz = z0; zz <= z1; zz++) {
      pb(cx-3, ly+1, zz, "sandstone_wall");
      pb(cx+3, ly+1, zz, "sandstone_wall");
    }
    pb(cx-4, ly+1, z0+1, "lantern");
    pb(cx+4, ly+1, z1-1, "lantern");
    // navigable link: corridor floor -> gallery 1 (west side), gallery 1 -> gallery 2 (east side)
    if (lv === 1) {
      staircase(cx-4, z0, fy+1, ly+1, "south", {width:1, material:"sandstone_stairs"});
    } else {
      staircase(cx+4, z0, fy+7, ly+1, "south", {width:1, material:"sandstone_stairs"});
    }
  }
  // roof deck at ground level + cornice + parapet + chhatri
  fill(cx-6, GY, z0, cx+6, GY, z1, "cut_sandstone");
  fill(cx-6, GY+1, z0, cx+6, GY+1, z1, "smooth_sandstone");
  for (zz = z0; zz <= z1; zz++) {
    roofStair(cx-7, GY, zz, "red_sandstone_stairs", "west", "top");
    roofStair(cx+7, GY, zz, "red_sandstone_stairs", "east", "top");
    pb(cx-6, GY+2, zz, "sandstone_wall");
    pb(cx+6, GY+2, zz, "sandstone_wall");
  }
}
pavilionBay(20, 25);
pavilionBay(32, 37);
pavilionBay(44, 49);

// === 6. WELL SHAFT RING GALLERIES ===
ck("SHAFT");
for (k = 0; k < 3; k++) {
  var gy = 12 + k * 5;
  fill(cx-5, gy, 54, cx-4, gy, 68, "smooth_sandstone");
  fill(cx+4, gy, 54, cx+5, gy, 68, "smooth_sandstone");
  fill(cx-3, gy, 67, cx+3, gy, 68, "smooth_sandstone");
  for (z = 54; z <= 68; z += 3) {
    fill(cx-4, gy+1, z, cx-4, gy+4, z, "cut_sandstone");
    fill(cx+4, gy+1, z, cx+4, gy+4, z, "cut_sandstone");
  }
  for (z = 54; z <= 68; z++) {
    pb(cx-3, gy+1, z, "sandstone_wall");
    pb(cx+3, gy+1, z, "sandstone_wall");
  }
  pb(cx-4, gy+1, 56, "lantern");
  pb(cx+4, gy+1, 62, "lantern");
  pb(cx-4, gy+1, 65, "lantern");
}

// === 7. RIM PARAPET, TORANA GATE, CHHATRIS ===
ck("RIM");
for (z = 10; z <= 70; z++) {
  pb(cx-7, GY+1, z, "sandstone_wall");
  pb(cx+7, GY+1, z, "sandstone_wall");
}
fill(cx-7, GY+1, 70, cx+7, GY+1, 70, "sandstone_wall");

function chhatri(bx, by, bz, r) {
  var offs = [[-r,-r],[r,-r],[-r,r],[r,r]];
  var j;
  for (j = 0; j < 4; j++) {
    fill(bx+offs[j][0], by, bz+offs[j][1], bx+offs[j][0], by+3, bz+offs[j][1], "cut_sandstone");
  }
  fill(bx-r, by+4, bz-r, bx+r, by+4, bz-r, "cut_sandstone");
  fill(bx-r, by+4, bz+r, bx+r, by+4, bz+r, "cut_sandstone");
  fill(bx-r, by+4, bz-r, bx-r, by+4, bz+r, "cut_sandstone");
  fill(bx+r, by+4, bz-r, bx+r, by+4, bz+r, "cut_sandstone");
  makeCylinder(bx, by+5, bz, "red_sandstone", r, 1, true);
  makeCylinder(bx, by+6, bz, "red_sandstone", r-1, 1, true);
  pb(bx, by+7, bz, "red_sandstone");
  pb(bx, by+8, bz, "sandstone_wall");
  pb(bx, by+2, bz, "lantern[hanging=true]");
}
chhatri(cx-10, GY+1, 56, 2);
chhatri(cx+10, GY+1, 56, 2);
chhatri(cx-10, GY+1, 66, 2);
chhatri(cx+10, GY+1, 66, 2);

// torana entrance gate at the north end
fill(cx-5, GY+1, 9, cx-5, GY+6, 9, "cut_sandstone");
fill(cx+5, GY+1, 9, cx+5, GY+6, 9, "cut_sandstone");
fill(cx-5, GY+7, 9, cx+5, GY+7, 9, "cut_sandstone");
fill(cx-5, GY+8, 9, cx+5, GY+8, 9, "chiseled_sandstone");
pb(cx-4, GY+6, 9, "sandstone_stairs[facing=east,half=top]");
pb(cx+4, GY+6, 9, "sandstone_stairs[facing=west,half=top]");
pb(cx-3, GY+7, 9, "red_sandstone");
pb(cx+3, GY+7, 9, "red_sandstone");
pb(cx, GY+9, 9, "red_sandstone");
pb(cx-2, GY+5, 9, "lantern[hanging=true]");
pb(cx+2, GY+5, 9, "lantern[hanging=true]");

// === 8. APPROACH + VEGETATION ===
ck("DETAIL");
fill(cx-3, GY, 4, cx+3, GY, 9, "dirt_path");
fill(cx-4, GY, 10, cx+4, GY, 11, "smooth_sandstone");
for (i = 0; i < 6; i++) {
  fill(cx-6 - 1, GY+1, 12 + i*10, cx-7, GY+2, 12 + i*10, "cut_sandstone");
  pb(cx-7, GY+3, 12 + i*10, "lantern");
  fill(cx+7, GY+1, 12 + i*10, cx+7, GY+2, 12 + i*10, "cut_sandstone");
  pb(cx+7, GY+3, 12 + i*10, "lantern");
}

function acacia(bx, bz) {
  var by = GY+1;
  fill(bx, by, bz, bx, by+4, bz, "acacia_log");
  makeCylinder(bx, by+5, bz, "acacia_leaves", 3, 1, true);
  makeCylinder(bx, by+6, bz, "acacia_leaves", 2, 1, true);
}
acacia(cx-14, 20);
acacia(cx+15, 34);
acacia(cx-16, 48);
acacia(cx+13, 12);
acacia(cx-13, 74);

var bush = [[-12,15],[-15,27],[13,22],[16,41],[-11,60],[14,63],[-17,70],[11,76],[-9,78],[18,52],[-19,36],[9,8]];
for (i = 0; i < bush.length; i++) {
  pb(cx+bush[i][0], GY+1, bush[i][1], (i % 3 === 0) ? "dead_bush" : "short_grass");
}
pb(cx-20, GY+1, 44, "cactus");
pb(cx+19, GY+1, 26, "cactus");
ck("DONE");

Static Renders

Indian stepwell (baoli) — indexed isometric viewisometric
Indian stepwell (baoli) — indexed front viewfront
Indian stepwell (baoli) — indexed side viewside
Indian stepwell (baoli) — indexed back viewback
Indian stepwell (baoli) — indexed top viewtop