← Back to Gallery

Loading 3D viewer…

Stave church on a rocky knoll (guided)

by Jorge Barbero

Dimensions
96×48×96
Blocks
84,478
Compute Time
8.0s
Generation Time
5m 31s
Model
claude-opus-5
Created
August 28, 2026
autoevalguidedstave_churchlarge_structures
Prompt

User Prompt

a Norwegian stave church on a rocky knoll: dark tarred vertical timber walls, steeply stacked tiered shingle roofs with dragon-head finials, a shingled tower over the nave, an arcaded covered walkway (svalgang) wrapping the base, small round windows; inside a dark nave with wooden benches, a raised chancel, lanterns and a stair up to the gallery

Enhanced Prompt

GUIDED condition: prepare_build plan + docs read (build-rules Essential Build Rules, shape-techniques Roof Types, interior-design Room-by-Room, worldedit-api position palettes + terrain superpowers). Composite plan (nave + chancel + porch + tower + svalgang), tiered roofs via placeGableRoof, staircase() to the gallery, terrain() pad, gradient/noise palettes.

Photos

Exterior
Exteriorexterior
Nave
Naveinterior
Gallery stair
Gallery stairinterior
Chancel
Chancelinterior
CraftScript Source
// === BUILD PLAN ===
// Style: Norwegian stave church (rustic dark tarred timber)
// Footprint: composite cross — nave 13x17 (x-6..6, z-8..8) + chancel 9x6 (z8..13)
//            + porch 7x6 (z-13..-8) + svalgang deck ring (x-9..9) + lantern tower over nave
// Height: floorY3 / walls to Y11 / nave gable base Y12 -> ridge Y18 / tower Y12-20,
//         tower gable base Y21 -> ridge Y24 / mast to Y27
//
// GROUND FLOOR (top-down, 1 char = 1 block, Z increases downward):
//   ....#####PPP#####....      P porch (entrance z=-13)
//   ..oo#############oo..      o svalgang posts (x=+-9)
//   ..o #  gallery over # o..  G gallery over the north bay (Y8, stair at x=-4)
//   ..o #  B B | B B    # o..  B benches, | red carpet aisle x=0
//   ..o #  B B | B B    # o..
//   ..oo#####  A  #####oo..    A chancel arch (z=8)
//   .......##  D  ##.......    D raised chancel dais + altar
//
// FRONT ELEVATION (north):
//            /^\            dragon-head finial + mast
//           /TTT\           shingled lantern tower (Y21-24)
//        /=========\        nave gable, dark_oak shingles (Y12-18)
//      /=============\
//      |staves+window|      clerestory round windows Y9
//    __|             |__    svalgang lean-to (Y8->Y6), posts + rail
//   |o o o o o o o o o o|
//   =====rocky knoll=====
//
// MATERIALS PLAN:
//   base   : gradientPalette cobble->mossy->andesite Y4..Y6   — WHY: wet stone sill grounds the timber
//   walls  : noisePalette dark_oak_planks55/spruce30/dark_oak_log15 — WHY: tarred stave board variation
//   staves : dark_oak_log[axis=y] pilasters PROTRUDING at x=+-7 every 3 — WHY: real facade relief
//   roofs  : dark_oak_stairs (nave, big dark mass) vs spruce_stairs (porch/chancel/tower/svalgang)
//            — WHY: tier CONTRAST reads the stacked silhouette
//   accents: brown_stained_glass round windows, lanterns, red carpet, banners
// Rooms: Nave (pews, aisle, chandelier, wall lanterns), Chancel (dais, altar, lectern, banners),
//        Gallery Y8 (benches, lantern, rail), Porch (bench, lanterns)
// STAIR PLAN: nave walk Y4 -> gallery walk Y9 (D=5) -> staircase(-4,-2,4,9,"north"), 6 cells z-2..-7
// === END PLAN ===

var padY = 2;
var floorY = 3;
var walkY = floorY + 1;      // 4
var wallTopY = 11;
var naveRoofY = 12;
var towerBaseY = 12;
var towerTopY = 20;

var wallMat = noisePalette([
  { block: 'dark_oak_planks', weight: 55 },
  { block: 'spruce_planks', weight: 30 },
  { block: 'dark_oak_log', weight: 15 }
], { seed: 7, freq: 0.16 });

var deckMat = noisePalette([
  { block: 'spruce_planks', weight: 60 },
  { block: 'dark_oak_planks', weight: 25 },
  { block: 'stripped_spruce_log', weight: 15 }
], { seed: 13, freq: 0.2 });

var stoneMat = gradientPalette(floorY, floorY + 3, [
  { block: 'mossy_cobblestone', from: 0 },
  { block: 'cobblestone', from: 0.45 },
  { block: 'andesite', from: 0.8 }
], { noise: 0.25, seed: 3 });

function ringWalls(x1, z1, x2, z2, y1, y2, mat) {
  fill(x1, y1, z1, x2, y2, z1, mat);
  fill(x1, y1, z2, x2, y2, z2, mat);
  fill(x1, y1, z1, x1, y2, z2, mat);
  fill(x2, y1, z1, x2, y2, z2, mat);
}

// === TERRAIN ===
var ground = null;
try {
  ground = terrain({
    cx: 0, cz: 0, radius: 34, baseY: -2, amp: 5, scale: 0.05, seed: 29, irregularity: 0.38,
    surface: [
      { block: 'grass_block', w: 5 },
      { block: 'coarse_dirt', w: 2 },
      { block: 'stone', w: 2 },
      { block: 'moss_block', w: 1 }
    ],
    sub: 'dirt', deep: 'stone', depth: 4,
    pads: [{ cx: 0, cz: 0, r: 19, y: padY, falloff: 10 }]
  });
} catch (terrErr) {
  fill(-20, padY - 3, -20, 20, padY, 20, 'stone');
  fill(-20, padY, -20, 20, padY, 20, 'grass_block');
}
// clear the building envelope so no ground intrudes
fill(-12, floorY, -18, 12, 30, 18, 'air');

// === STRUCTURE ===
// deck / svalgang platform + church floor slab
fill(-9, floorY, -8, 9, floorY, 8, deckMat);
fill(-5, floorY, -14, 5, floorY, 14, deckMat);
fill(-5, floorY, -7, 5, floorY, 7, 'dark_oak_planks');

// nave walls
ringWalls(-6, -8, 6, 8, floorY + 1, wallTopY, wallMat);
// stone sill band
ringWalls(-6, -8, 6, 8, floorY + 1, floorY + 3, stoneMat);
// chancel
ringWalls(-4, 8, 4, 13, floorY + 1, 9, wallMat);
ringWalls(-4, 8, 4, 13, floorY + 1, floorY + 3, stoneMat);
fill(-3, floorY, 9, 3, floorY, 12, 'dark_oak_planks');
// porch
ringWalls(-3, -13, 3, -8, floorY + 1, 8, wallMat);
ringWalls(-3, -13, 3, -8, floorY + 1, floorY + 3, stoneMat);
fill(-2, floorY, -12, 2, floorY, -9, 'dark_oak_planks');

// openings: outer door, porch->nave, nave->chancel arch
fill(-1, walkY, -13, 1, walkY + 2, -13, 'air');
fill(-1, walkY, -8, 1, walkY + 2, -8, 'air');
fill(-2, walkY, 8, 2, walkY + 3, 8, 'air');
ps(0, walkY, -13, 'dark_oak_door[facing=north,half=lower,hinge=left]');
ps(0, walkY + 1, -13, 'dark_oak_door[facing=north,half=upper,hinge=left]');

// protruding stave pilasters + corner posts (facade depth)
var pz;
for (pz = -8; pz <= 8; pz += 3) {
  fill(-7, floorY + 1, pz, -7, wallTopY, pz, 'dark_oak_log[axis=y]');
  fill(7, floorY + 1, pz, 7, wallTopY, pz, 'dark_oak_log[axis=y]');
}
fill(-6, floorY + 1, -8, -6, wallTopY, -8, 'dark_oak_log[axis=y]');
fill(6, floorY + 1, -8, 6, wallTopY, -8, 'dark_oak_log[axis=y]');
fill(-6, floorY + 1, 8, -6, wallTopY, 8, 'dark_oak_log[axis=y]');
fill(6, floorY + 1, 8, 6, wallTopY, 8, 'dark_oak_log[axis=y]');

// cornice ring (upside-down stairs) at wall top
var cx2, cz2;
for (cx2 = -6; cx2 <= 6; cx2++) {
  roofStair(cx2, wallTopY, -9, 'dark_oak_stairs', 'north', 'top');
  roofStair(cx2, wallTopY, 9, 'dark_oak_stairs', 'south', 'top');
}
for (cz2 = -8; cz2 <= 8; cz2++) {
  roofStair(-7, wallTopY, cz2, 'dark_oak_stairs', 'west', 'top');
  roofStair(7, wallTopY, cz2, 'dark_oak_stairs', 'east', 'top');
}

// === ROOF ===
placeGableRoof(-6, 6, -8, 8, naveRoofY, 'dark_oak_stairs', 'dark_oak_slab', wallMat);
placeGableRoof(-4, 4, 8, 13, 10, 'spruce_stairs', 'spruce_slab', wallMat);
placeGableRoof(-3, 3, -13, -8, 9, 'spruce_stairs', 'spruce_slab', wallMat);

// lantern tower over the nave (built AFTER the nave roof so it overwrites it)
ringWalls(-3, -3, 3, 3, towerBaseY, towerTopY, wallMat);
fill(-2, towerBaseY, -2, 2, towerTopY, 2, 'air');
// belfry louvers on all four faces
var lv;
for (lv = -1; lv <= 1; lv++) {
  fill(lv, towerTopY - 4, -3, lv, towerTopY - 1, -3, 'dark_oak_fence');
  fill(lv, towerTopY - 4, 3, lv, towerTopY - 1, 3, 'dark_oak_fence');
  fill(-3, towerTopY - 4, lv, -3, towerTopY - 1, lv, 'dark_oak_fence');
  fill(3, towerTopY - 4, lv, 3, towerTopY - 1, lv, 'dark_oak_fence');
}
placeGableRoof(-3, 3, -3, 3, towerTopY + 1, 'spruce_stairs', 'spruce_slab', wallMat);
// mast + weather finial
fill(0, towerTopY + 5, 0, 0, towerTopY + 7, 0, 'dark_oak_fence');
pb(0, towerTopY + 8, 0, 'lantern');

// dragon-head finials at the four ridge ends
function finial(fx, fy, fz, face) {
  pb(fx, fy, fz, 'dark_oak_fence');
  ps(fx, fy + 1, fz, 'dark_oak_stairs[facing=' + face + ',half=top]');
  ps(fx, fy + 1, fz + (face === 'north' ? -1 : (face === 'south' ? 1 : 0)), 'dark_oak_trapdoor[facing=' + face + ',half=top,open=false]');
}
finial(0, 19, -9, 'north');
finial(0, 19, 9, 'south');
finial(0, 15, 14, 'south');
finial(0, 13, -14, 'north');

// === SVALGANG (arcaded covered walkway) ===
var sz;
for (sz = -8; sz <= 8; sz++) {
  // lean-to shingles west & east
  roofStair(-7, 8, sz, 'spruce_stairs', 'west');
  roofStair(-8, 7, sz, 'spruce_stairs', 'west');
  roofStair(-9, 6, sz, 'spruce_stairs', 'west');
  roofStair(7, 8, sz, 'spruce_stairs', 'east');
  roofStair(8, 7, sz, 'spruce_stairs', 'east');
  roofStair(9, 6, sz, 'spruce_stairs', 'east');
  if (sz % 2 === 0) {
    fill(-9, walkY, sz, -9, 5, sz, 'dark_oak_log[axis=y]');
    fill(9, walkY, sz, 9, 5, sz, 'dark_oak_log[axis=y]');
  } else {
    pb(-9, walkY + 1, sz, 'dark_oak_fence');
    pb(9, walkY + 1, sz, 'dark_oak_fence');
  }
}
// re-place the pilasters that the lean-to overwrote at Y8
for (pz = -8; pz <= 8; pz += 3) {
  fill(-7, floorY + 1, pz, -7, wallTopY, pz, 'dark_oak_log[axis=y]');
  fill(7, floorY + 1, pz, 7, wallTopY, pz, 'dark_oak_log[axis=y]');
}

// === WINDOWS === small round clerestory windows above the svalgang roof
var wz;
for (wz = -6; wz <= 6; wz += 3) {
  ps(-6, 9, wz, 'brown_stained_glass');
  ps(6, 9, wz, 'brown_stained_glass');
  ps(-6, 10, wz, 'dark_oak_trapdoor[facing=west,half=top,open=false]');
  ps(6, 10, wz, 'dark_oak_trapdoor[facing=east,half=top,open=false]');
}
ps(-3, 7, 13, 'brown_stained_glass');
ps(3, 7, 13, 'brown_stained_glass');
ps(0, 8, 13, 'brown_stained_glass');

// === INTERIOR: GALLERY + STAIR ===
fill(-5, 8, -7, 5, 8, -5, 'spruce_planks');
var gx;
for (gx = -5; gx <= 5; gx++) {
  pb(gx, 9, -4, 'dark_oak_fence');
}
staircase(-4, -2, walkY, 9, 'north', { width: 1, material: 'dark_oak_stairs', rail: true, support: 'dark_oak_planks' });
var gb;
for (gb = -2; gb <= 2; gb++) {
  chairStair(gb, 9, -6, 'spruce_stairs', 'south');
}
pb(4, 9, -6, 'dark_oak_fence');
pb(4, 10, -6, 'lantern');

// === INTERIOR: NAVE ===
var rz, bx;
for (rz = -7; rz <= 7; rz++) {
  pb(0, walkY, rz, 'red_carpet');
}
for (rz = -5; rz <= 5; rz += 2) {
  for (bx = 2; bx <= 3; bx++) {
    chairStair(-bx, walkY, rz, 'spruce_stairs', 'south');
    chairStair(bx, walkY, rz, 'spruce_stairs', 'south');
  }
}
// wall lanterns on fence brackets
var lz;
for (lz = -5; lz <= 5; lz += 4) {
  pb(-5, walkY + 3, lz, 'dark_oak_fence');
  pb(-5, walkY + 4, lz, 'lantern');
  pb(5, walkY + 3, lz, 'dark_oak_fence');
  pb(5, walkY + 4, lz, 'lantern');
}
// chandelier hanging from the tower ridge into the nave
var chY;
for (chY = towerBaseY; chY <= towerTopY + 3; chY++) {
  pb(0, chY, 0, 'chain[axis=y]');
}
ps(0, wallTopY, 0, 'lantern[hanging=true]');

// === INTERIOR: CHANCEL ===
fill(-3, walkY, 10, 3, walkY, 12, 'polished_andesite');
var stx;
for (stx = -2; stx <= 2; stx++) {
  climbStair(stx, walkY, 9, 'dark_oak_stairs', 'south');
}
fill(-1, walkY + 1, 12, 1, walkY + 1, 12, 'chiseled_stone_bricks');
pb(0, walkY + 2, 12, 'lantern');
ps(-2, walkY + 1, 11, 'lectern[facing=east]');
ps(-4, walkY + 4, 11, 'red_wall_banner[facing=east]');
ps(4, walkY + 4, 11, 'red_wall_banner[facing=west]');
pb(-3, walkY + 1, 10, 'dark_oak_fence');
pb(-3, walkY + 2, 10, 'lantern');
pb(3, walkY + 1, 10, 'dark_oak_fence');
pb(3, walkY + 2, 10, 'lantern');

// === INTERIOR: PORCH ===
chairStair(-2, walkY, -11, 'spruce_stairs', 'east');
chairStair(2, walkY, -11, 'spruce_stairs', 'west');
pb(-2, walkY + 3, -9, 'dark_oak_fence');
pb(-2, walkY + 4, -9, 'lantern');
pb(2, walkY + 3, -9, 'dark_oak_fence');
pb(2, walkY + 4, -9, 'lantern');

// === DETAIL: LANDSCAPING ===
// path from the porch down the knoll
var pathZ, gy, pxx;
for (pathZ = -15; pathZ >= -26; pathZ--) {
  gy = padY;
  if (ground) { gy = Math.round(ground(0, pathZ)); }
  for (pxx = -1; pxx <= 1; pxx++) {
    pb(pxx, gy, pathZ, (pathZ % 3 === 0) ? 'cobblestone' : 'gravel');
  }
}
// churchyard: stone grave markers + low wall posts
var graves = [[-13, -4], [-14, 2], [-13, 7], [13, -3], [14, 3], [12, 8]];
var gi, gxx, gzz, ggy;
for (gi = 0; gi < graves.length; gi++) {
  gxx = graves[gi][0]; gzz = graves[gi][1];
  ggy = padY;
  if (ground) { ggy = Math.round(ground(gxx, gzz)); }
  pb(gxx, ggy + 1, gzz, 'cobblestone_wall');
  ps(gxx, ggy + 2, gzz, 'stone_brick_slab[type=bottom]');
  pb(gxx + 1, ggy + 1, gzz, 'moss_block');
}
// trees + shrubs on the knoll
var trees = [[-19, -12], [17, -14], [-21, 9], [18, 12], [-16, 17]];
var ti, txx, tzz, tyy;
for (ti = 0; ti < trees.length; ti++) {
  txx = trees[ti][0]; tzz = trees[ti][1];
  tyy = padY;
  if (ground) { tyy = Math.round(ground(txx, tzz)); }
  try {
    placeTree(txx, tyy + 1, tzz, 'spruce');
  } catch (treeErr) {
    fill(txx, tyy + 1, tzz, txx, tyy + 6, tzz, 'spruce_log[axis=y]');
    makeSphere(txx, tyy + 6, tzz, 'spruce_leaves[persistent=true]', 3, true);
  }
}
// outdoor lamps flanking the path
try {
  lampPost(-3, padY + 1, -15, 'dark_oak_fence');
  lampPost(3, padY + 1, -15, 'dark_oak_fence');
} catch (lampErr) {
  fill(-3, padY + 1, -15, -3, padY + 3, -15, 'dark_oak_fence');
  pb(-3, padY + 4, -15, 'lantern');
  fill(3, padY + 1, -15, 3, padY + 3, -15, 'dark_oak_fence');
  pb(3, padY + 4, -15, 'lantern');
}
// scattered flowers / grass on the pad edge
var fi2, fx2, fz2, fy2;
for (fi2 = 0; fi2 < 60; fi2++) {
  fx2 = -24 + Math.floor(noise2d('perlin', fi2 * 7.3, 11.1) * 48);
  fz2 = -24 + Math.floor(noise2d('perlin', 3.7, fi2 * 5.9) * 48);
  if (Math.abs(fx2) < 11 && Math.abs(fz2) < 16) { continue; }
  fy2 = padY;
  if (ground) { fy2 = Math.round(ground(fx2, fz2)); }
  pb(fx2, fy2 + 1, fz2, (fi2 % 4 === 0) ? 'poppy' : ((fi2 % 4 === 1) ? 'oxeye_daisy' : 'short_grass'));
}

Static Renders

Stave church on a rocky knoll (guided) isometric viewisometric
Stave church on a rocky knoll (guided) front viewfront
Stave church on a rocky knoll (guided) side viewside
Stave church on a rocky knoll (guided) back viewback
Stave church on a rocky knoll (guided) top viewtop