← Back to Gallery

Loading 3D viewer…

Victorian Palm House (indexed)

by Jorge Barbero

Dimensions
72×60×96
Blocks
148,394
Compute Time
5.6s
Generation Time
3m 10s
Model
claude-opus-5
Created
September 7, 2026
victorianglasshouseautoevalindexed
Prompt

User Prompt

a Victorian cast-iron and glass palm house (botanical glasshouse) in a park: a long barrel-vaulted glazed nave with a taller domed octagonal centre, dark green painted iron ribs and glazing bars, a low red-brick plinth, arched entrance doors, and inside a warm humid planting hall with tall palms, raised gallery walkway reached by a staircase, and lantern lighting

Enhanced Prompt

indexed condition: prepare_build + search_docs({action:"related"}) graph retrieval -> read Clean Dome/Cupola (stacked shrinking cylinders, drum+cap+crown), Block ID Changes 1.21.11 (iron_chain), Victorian. DIRECT process, stepped-ring dome, L-shaped gallery stair via staircase()+landing.

Photos

Exterior
Exteriorexterior
Nave acristalada
Nave acristaladainterior
Rotonda
Rotondainterior
Escalera y galeria
Escalera y galeriainterior
CraftScript Source
// === BUILD PLAN ===
// Style: Victorian cast-iron & glass palm house + brick boiler-house annexe, set in a park
// Footprint: cruciform/T — glazed nave 17 wide running N-S (z12..84) + octagonal drum r=12 at centre
//            + brick boiler house 12x11 bolted to the WEST face (chimney) => never a plain box
// Height: plinth Y12-13, glazing to Y20, barrel vault crown Y29; drum to Y26, stepped dome Y28..Y40, finial Y44
//
// PLAN (top-down, x right, z down):
//        z12   #####D#####          north arched door
//              #  nave   #          17 wide glazed nave, vault ridge along Z
//        z36   ##       ##
//   BOILER ####(   DRUM   )####     octagon r=12, gallery ring at walk Y21
//        z60   ##       ##
//              #  nave   #
//        z84   #####D#####          south arched door + gravel path
//
// SECTION through the nave:  .-~~~-.  vault crown Y29 (glass + green iron ribs every 4)
//                            |     |  glazing Y14..20
//                            |#####|  red-brick plinth Y12..13 + cornice slab
//
// MATERIALS PLAN:
//   plinth   : gradientPalette deepslate_bricks -> bricks -> granite up Y12..14 — WHY: heavy base, fakes AO
//   ironwork : green_concrete(55)+green_terracotta(25)+dried_kelp_block(20) — WHY: dark painted iron vs pale glass = the whole look
//   glazing  : noisePalette glass(72)+white_stained_glass(16)+light_blue_stained_glass(12) — WHY: old uneven panes
//   boiler   : bricks(65)+granite(20)+mossy_stone_bricks(15), deepslate_tile_stairs roof
//   dome     : DRUM + stacked shrinking cylinders (build-rules "Clean Dome") + crown finial, ribs by ring parity
// Rooms: N nave (palm beds, benches), drum (pond, giant palms, gallery ring), S nave (ferns, potting benches),
//        boiler house (furnaces, barrels, workbench, lantern)
// STAIR PLAN: Δ walk12 -> walk21 = 9 -> L-shape: staircase south 12->16, landing, staircase east 16->21 into ring
// PROCESS: DIRECT (final materials as placed) — masks not needed, avoids placeholder leftovers
// NOTE (from related-retrieval): chain -> iron_chain in 1.21.11+; glass panes only connect to solid blocks
// === END PLAN ===

var CX = 36, CZ = 48, DR = 12;
var NX1 = 28, NX2 = 44;            // nave X span
var NZ1 = 12, NZ2 = 36;            // north nave Z span
var SZ1 = 60, SZ2 = 84;            // south nave Z span
var groundY = 10, floorY = 11, walkY = 12;
var plinthTop = 13;
var wallTopY = 20, SPRING = 21, VR = 8;
var drumTop = 26, domeBaseY = 28;
var galFloorY = 20, galWalkY = 21;
var BX1 = 12, BX2 = 23, BZ1 = 42, BZ2 = 53;   // boiler house

var brickPal = palette([{block:"bricks",weight:65},{block:"granite",weight:20},{block:"mossy_stone_bricks",weight:15}]);
var plinthPal = gradientPalette(walkY, plinthTop + 1, [{block:"deepslate_bricks",from:0},{block:"bricks",from:0.45},{block:"granite",from:0.85}], {noise:0.25});
var ironPal = palette([{block:"green_concrete",weight:55},{block:"green_terracotta",weight:25},{block:"dried_kelp_block",weight:20}]);
var glassPal = noisePalette([{block:"glass",weight:72},{block:"white_stained_glass",weight:16},{block:"light_blue_stained_glass",weight:12}], {freq:0.15, seed:21});
var floorPal = palette([{block:"smooth_stone",weight:40},{block:"polished_diorite",weight:30},{block:"stone_bricks",weight:30}]);

function inOctR(x, z, R) {
    var dx = Math.abs(x - CX), dz = Math.abs(z - CZ);
    return dx <= R && dz <= R && (dx + dz) <= Math.floor(R * 1.42);
}
function onOctEdge(x, z) {
    if (!inOctR(x, z, DR)) return false;
    return !(inOctR(x + 1, z, DR) && inOctR(x - 1, z, DR) && inOctR(x, z + 1, DR) && inOctR(x, z - 1, DR));
}
function inNave(x, z) {
    return x >= NX1 && x <= NX2 && ((z >= NZ1 && z <= NZ2) || (z >= SZ1 && z <= SZ2));
}
function inBoiler(x, z) { return x >= BX1 && x <= BX2 && z >= BZ1 && z <= BZ2; }
function inFoot(x, z) { return inNave(x, z) || inOctR(x, z, DR) || inBoiler(x, z); }

var x, y, z, i, k, dx, dz, dy, dd;

// === TERRAIN (superpowers, flat pad UNDER the build) ===
var park = blob(CX, CZ, 46, {irregularity: 0.32, seed: 17});
var hf = hills({base: 9, amp: 3, seed: 31});
var pad = flatten(hf, {x0: BX1 - 4, z0: NZ1 - 5, x1: NX2 + 6, z1: SZ2 + 5}, groundY, 10);
var gmat = patches(["grass_block", "grass_block", "podzol", "coarse_dirt"], 0.055, 8);
surface(park, pad, gmat, {sub: "dirt", deep: "stone", depth: 4});

// === CLEAR FOOTPRINT + FLOOR ===
for (x = BX1 - 1; x <= NX2 + 1; x++) {
    for (z = NZ1 - 1; z <= SZ2 + 1; z++) {
        if (!inFoot(x, z)) continue;
        fill(x, floorY, z, x, 46, z, "air");
        pb(x, floorY - 1, z, "stone_bricks");
        pb(x, floorY, z, inBoiler(x, z) ? "polished_blackstone" : floorPal);
    }
}

// === NAVE WALLS (glazing between iron mullions on a brick plinth) ===
function naveWall(wx, z1, z2) {
    var zz, yy;
    for (zz = z1; zz <= z2; zz++) {
        for (yy = walkY; yy <= wallTopY; yy++) {
            if (yy <= plinthTop) pb(wx, yy, zz, plinthPal);
            else if (zz % 4 === 0) pb(wx, yy, zz, ironPal);
            else pb(wx, yy, zz, glassPal);
        }
        pb(wx, wallTopY, zz, ironPal);                        // cornice band
    }
}
naveWall(NX1, NZ1, NZ2); naveWall(NX2, NZ1, NZ2);
naveWall(NX1, SZ1, SZ2); naveWall(NX2, SZ1, SZ2);
function endWall(wz) {
    var xx, yy;
    for (xx = NX1; xx <= NX2; xx++) {
        for (yy = walkY; yy <= wallTopY; yy++) {
            if (yy <= plinthTop) pb(xx, yy, wz, plinthPal);
            else if (xx % 4 === 0) pb(xx, yy, wz, ironPal);
            else pb(xx, yy, wz, glassPal);
        }
    }
    // semicircular tympanum closing the vault end
    for (dx = -VR; dx <= VR; dx++) {
        for (dy = 0; dy <= VR; dy++) {
            dd = Math.sqrt(dx * dx + dy * dy);
            if (dd < VR - 0.4) pb(CX + dx, SPRING + dy, wz, (dx % 4 === 0 || dy === 0) ? ironPal : glassPal);
        }
    }
}
endWall(NZ1); endWall(SZ2);

// === BARREL VAULTS (ribs every 4th bay) ===
function vault(z1, z2) {
    var zz, ddx, ddy, d2, rib;
    for (zz = z1; zz <= z2; zz++) {
        rib = (zz % 4 === 0);
        for (ddx = -VR - 1; ddx <= VR + 1; ddx++) {
            for (ddy = 0; ddy <= VR + 1; ddy++) {
                d2 = Math.sqrt(ddx * ddx + ddy * ddy);
                if (d2 >= VR - 0.5 && d2 < VR + 0.5) {
                    pb(CX + ddx, SPRING + ddy, zz, rib ? ironPal : glassPal);
                }
            }
        }
    }
}
vault(NZ1, NZ2); vault(SZ1, SZ2);

// === OCTAGONAL DRUM ===
function isDrumOpening(x, z, y) {
    return Math.abs(x - CX) <= VR && (z <= CZ - 9 || z >= CZ + 9) && y >= walkY && y <= 24;
}
for (x = CX - DR; x <= CX + DR; x++) {
    for (z = CZ - DR; z <= CZ + DR; z++) {
        if (!onOctEdge(x, z)) continue;
        for (y = walkY; y <= drumTop; y++) {
            if (isDrumOpening(x, z, y)) continue;
            if (x === BX2 + 1 && z >= CZ - 1 && z <= CZ + 1 && y <= walkY + 2) continue;   // door to boiler house
            if (y <= plinthTop) pb(x, y, z, plinthPal);
            else if (y === drumTop || (x + z) % 4 === 0) pb(x, y, z, ironPal);
            else pb(x, y, z, glassPal);
        }
        // buttress piers with a stone cap — facade depth
        if ((x + z) % 6 === 0 && !isDrumOpening(x, z, walkY)) {
            for (y = walkY; y <= plinthTop + 3; y++) {
                pb(x + (x > CX ? 1 : (x < CX ? -1 : 0)), y, z + (z > CZ ? 1 : (z < CZ ? -1 : 0)), brickPal);
            }
        }
    }
}
// close the drum face above the nave openings (no sky gap at the junction)
for (z = CZ - DR; z <= CZ + DR; z++) {
    for (x = CX - DR; x <= CX + DR; x++) {
        if (!onOctEdge(x, z)) continue;
        for (y = 25; y <= drumTop; y++) if (!inNave(x, z)) pb(x, y, z, (x + z) % 4 === 0 ? ironPal : glassPal);
    }
}

// === DOME: drum cornice + stacked shrinking rings + crown (build-rules "Clean Dome") ===
makeCylinder(CX, drumTop + 1, CZ, brickPal, DR + 1, 1, false);       // 1-block cornice overhang ring
makeCylinder(CX, drumTop + 1, CZ, ironPal, DR, 1, true);
var ringR = [12, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2];
for (i = 0; i < ringR.length; i++) {
    makeCylinder(CX, domeBaseY + i, CZ, (i % 3 === 0) ? ironPal : glassPal, ringR[i], 1, true);
}
makeCylinder(CX, domeBaseY + ringR.length, CZ, ironPal, 2, 1, false);
// lantern cupola + finial
makeCylinder(CX, domeBaseY + ringR.length + 1, CZ, glassPal, 2, 3, true);
makeCylinder(CX, domeBaseY + ringR.length + 4, CZ, ironPal, 3, 1, false);
makeCone(CX, domeBaseY + ringR.length + 5, CZ, ironPal, 3, 4, false);
pb(CX, domeBaseY + ringR.length + 10, CZ, "lightning_rod");

// === BOILER HOUSE ANNEXE (brick, gable roof, chimney) ===
for (x = BX1; x <= BX2; x++) {
    for (z = BZ1; z <= BZ2; z++) {
        var edge = (x === BX1 || x === BX2 || z === BZ1 || z === BZ2);
        if (!edge) continue;
        for (y = walkY; y <= walkY + 6; y++) {
            if (x === BX1 && z >= CZ - 1 && z <= CZ + 1 && y <= walkY + 2) continue;  // west service door
            if ((x === BX1 || x === BX2) && (z === BZ1 + 3 || z === BZ2 - 3) && y >= walkY + 2 && y <= walkY + 4) { pb(x, y, z, "glass_pane"); continue; }
            if ((z === BZ1 || z === BZ2) && (x === BX1 + 3 || x === BX2 - 3) && y >= walkY + 2 && y <= walkY + 4) { pb(x, y, z, "glass_pane"); continue; }
            pb(x, y, z, brickPal);
        }
        // pilaster relief every 4
        if ((x + z) % 4 === 0) for (y = walkY; y <= walkY + 6; y++) pb(x + (x === BX1 ? -1 : (x === BX2 ? 1 : 0)), y, z + (z === BZ1 ? -1 : (z === BZ2 ? 1 : 0)), brickPal);
    }
}
placeGableRoof(BX1, BX2, BZ1, BZ2, walkY + 7, "deepslate_tile_stairs", "deepslate_tile_slab", "bricks");
fill(BX1 + 1, walkY, BZ1 + 1, BX2 - 1, walkY + 8, BZ2 - 1, "air");
fill(BX1 + 1, floorY, BZ1 + 1, BX2 - 1, floorY, BZ2 - 1, "polished_blackstone");
// chimney
for (y = walkY; y <= 34; y++) makeCylinder(BX1 + 2, y, BZ1 + 2, brickPal, 2, 1, y > walkY + 8);
makeCylinder(BX1 + 2, 35, BZ1 + 2, "deepslate_tiles", 2, 1, true);
ps(BX1 + 2, 36, BZ1 + 2, "campfire[lit=true]");
// service doors
ps(BX1, walkY, CZ, "spruce_door[facing=west,half=lower,hinge=left]");
ps(BX1, walkY + 1, CZ, "spruce_door[facing=west,half=upper,hinge=left]");
ps(BX2 + 1, walkY, CZ, "spruce_door[facing=east,half=lower,hinge=right]");
ps(BX2 + 1, walkY + 1, CZ, "spruce_door[facing=east,half=upper,hinge=right]");
// boiler house interior
ps(BX1 + 2, walkY, BZ2 - 2, "blast_furnace[facing=north,lit=true]");
ps(BX1 + 3, walkY, BZ2 - 2, "furnace[facing=north,lit=true]");
ps(BX1 + 4, walkY, BZ2 - 2, "furnace[facing=north,lit=false]");
pb(BX1 + 6, walkY, BZ2 - 2, "barrel");
pb(BX1 + 7, walkY, BZ2 - 2, "chest");
pb(BX1 + 8, walkY, BZ1 + 2, "crafting_table");
ps(BX1 + 9, walkY, BZ1 + 2, "anvil[facing=south]");
pb(BX1 + 5, walkY, BZ1 + 1, "cauldron");
rug(BX1 + 5, walkY, CZ - 1, 3, 3, "brown", "gray");
pb(BX1 + 5, walkY + 6, CZ, "bricks");
ps(BX1 + 5, walkY + 5, CZ, "lantern[hanging=true]");
for (i = 0; i < 2; i++) { pb(BX1 + 2 + i * 6, walkY + 6, BZ2 - 3, "bricks"); ps(BX1 + 2 + i * 6, walkY + 5, BZ2 - 3, "lantern[hanging=true]"); }

// === ARCHED ENTRANCE DOORS (north + south ends of the nave) ===
function grandDoor(dz, facing, inward) {
    var xx, yy;
    fill(CX - 1, walkY, dz, CX, walkY + 3, dz, "air");
    ps(CX - 1, walkY, dz, "dark_oak_door[facing=" + facing + ",half=lower,hinge=left]");
    ps(CX - 1, walkY + 1, dz, "dark_oak_door[facing=" + facing + ",half=upper,hinge=left]");
    ps(CX, walkY, dz, "dark_oak_door[facing=" + facing + ",half=lower,hinge=right]");
    ps(CX, walkY + 1, dz, "dark_oak_door[facing=" + facing + ",half=upper,hinge=right]");
    pb(CX - 1, walkY + 2, dz, "green_concrete"); pb(CX, walkY + 2, dz, "green_concrete");
    pb(CX - 1, walkY + 3, dz, glassPal); pb(CX, walkY + 3, dz, glassPal);
    for (yy = walkY; yy <= walkY + 5; yy++) { pb(CX - 2, yy, dz, brickPal); pb(CX + 1, yy, dz, brickPal); }
    for (xx = CX - 2; xx <= CX + 1; xx++) ps(xx, walkY + 5, dz + inward * -1, "brick_slab[type=top]");
    // porch canopy on iron posts
    for (xx = CX - 2; xx <= CX + 1; xx++) pb(xx, walkY + 5, dz + inward * -2, "green_concrete");
    pb(CX - 2, walkY, dz + inward * -2, "green_concrete"); pb(CX + 1, walkY, dz + inward * -2, "green_concrete");
    pb(CX - 2, walkY + 1, dz + inward * -2, "green_concrete"); pb(CX + 1, walkY + 1, dz + inward * -2, "green_concrete");
    pb(CX - 2, walkY + 2, dz + inward * -2, "green_concrete"); pb(CX + 1, walkY + 2, dz + inward * -2, "green_concrete");
    pb(CX - 2, walkY + 3, dz + inward * -2, "green_concrete"); pb(CX + 1, walkY + 3, dz + inward * -2, "green_concrete");
    pb(CX - 2, walkY + 4, dz + inward * -2, "green_concrete"); pb(CX + 1, walkY + 4, dz + inward * -2, "green_concrete");
}
grandDoor(NZ1, "north", 1);
grandDoor(SZ2, "south", -1);

// === GALLERY RING + L-SHAPED STAIR ===
for (x = CX - DR; x <= CX + DR; x++) {
    for (z = CZ - DR; z <= CZ + DR; z++) {
        if (inOctR(x, z, DR - 1) && !inOctR(x, z, 7)) pb(x, galFloorY, z, "spruce_planks");
    }
}
for (x = CX - DR; x <= CX + DR; x++) {
    for (z = CZ - DR; z <= CZ + DR; z++) {
        if (!inOctR(x, z, DR - 1) || inOctR(x, z, 7)) continue;
        if (inOctR(x + 1, z, 7) || inOctR(x - 1, z, 7) || inOctR(x, z + 1, 7) || inOctR(x, z - 1, 7)) {
            pb(x, galWalkY, z, "iron_bars"); pb(x, galWalkY + 1, z, "iron_bars");
        }
        if ((x + z) % 7 === 0) for (y = walkY; y < galFloorY; y++) pb(x, y, z, "green_concrete");   // slim iron columns
    }
}
var s1 = staircase(NX1 + 2, NZ2 - 12, walkY, walkY + 4, "south", {width: 2, material: "spruce_stairs"});
landing(NX1 + 2, walkY + 4, NZ2 - 6, 3, 3, "spruce_planks");
var s2 = staircase(NX1 + 3, NZ2 - 5, walkY + 4, galWalkY, "south", {width: 2, material: "spruce_stairs"});
// deck connecting the stair head to the ring
fill(NX1 + 2, galFloorY, NZ2 - 2, NX1 + 5, galFloorY, CZ - 8, "spruce_planks");
for (z = NZ2 - 2; z <= CZ - 8; z++) { pb(NX1 + 1, galWalkY, z, "iron_bars"); pb(NX1 + 6, galWalkY, z, "iron_bars"); }

// === PLANTING HALL ===
function palm(px, py, pz, hh) {
    var kk, tx, ty, dirs, ddx2, ddz2;
    for (kk = 0; kk < hh; kk++) pb(px + (kk > hh * 0.65 ? 1 : 0), py + kk, pz, kk < 2 ? "jungle_log" : "stripped_jungle_log");
    tx = px + 1; ty = py + hh - 1;
    dirs = [[1,0],[-1,0],[0,1],[0,-1],[1,1],[-1,-1],[1,-1],[-1,1]];
    for (kk = 0; kk < dirs.length; kk++) {
        ddx2 = dirs[kk][0]; ddz2 = dirs[kk][1];
        ps(tx + ddx2, ty, pz + ddz2, "jungle_leaves[persistent=true]");
        ps(tx + ddx2 * 2, ty - 1, pz + ddz2 * 2, "jungle_leaves[persistent=true]");
        ps(tx + ddx2 * 3, ty - 2, pz + ddz2 * 3, "jungle_leaves[persistent=true]");
    }
    ps(tx, ty, pz, "jungle_leaves[persistent=true]"); ps(tx, ty + 1, pz, "jungle_leaves[persistent=true]");
}
function bed(x1, z1, x2, z2) {
    var xx, zz;
    for (xx = x1; xx <= x2; xx++) for (zz = z1; zz <= z2; zz++) {
        pb(xx, floorY, zz, (xx + zz) % 4 === 0 ? "coarse_dirt" : "podzol");
        if ((xx * 3 + zz * 5) % 6 === 0) ps(xx, walkY, zz, "fern");
        else if ((xx * 7 + zz) % 8 === 0) pb(xx, walkY, zz, "azalea");
        else if ((xx + zz * 3) % 7 === 0) ps(xx, walkY, zz, "grass");
        else if ((xx * 2 + zz) % 11 === 0) pb(xx, walkY, zz, "big_dripleaf");
    }
    for (xx = x1 - 1; xx <= x2 + 1; xx++) { ps(xx, walkY, z1 - 1, "brick_slab[type=bottom]"); ps(xx, walkY, z2 + 1, "brick_slab[type=bottom]"); }
    for (zz = z1 - 1; zz <= z2 + 1; zz++) { ps(x1 - 1, walkY, zz, "brick_slab[type=bottom]"); ps(x2 + 1, walkY, zz, "brick_slab[type=bottom]"); }
}
bed(NX1 + 2, NZ1 + 3, NX1 + 6, NZ1 + 8);
bed(NX2 - 6, NZ1 + 3, NX2 - 2, NZ1 + 8);
bed(NX2 - 6, NZ1 + 12, NX2 - 2, NZ1 + 18);
bed(NX1 + 2, SZ1 + 3, NX1 + 6, SZ1 + 9);
bed(NX2 - 6, SZ1 + 3, NX2 - 6 + 4, SZ1 + 9);
bed(NX1 + 2, SZ2 - 10, NX1 + 6, SZ2 - 4);
bed(NX2 - 6, SZ2 - 10, NX2 - 2, SZ2 - 4);
palm(NX1 + 3, walkY, NZ1 + 5, 9);
palm(NX2 - 5, walkY, NZ1 + 6, 11);
palm(NX2 - 5, walkY, NZ1 + 15, 8);
palm(NX1 + 3, walkY, SZ1 + 5, 10);
palm(NX2 - 5, walkY, SZ1 + 6, 9);
palm(NX1 + 3, walkY, SZ2 - 7, 8);
palm(NX2 - 5, walkY, SZ2 - 7, 11);
// drum: octagonal pond + giant palms + tree ferns
makeCylinder(CX, floorY, CZ, "prismarine_bricks", 6, 1, false);
makeCylinder(CX, floorY, CZ, "water", 5, 1, false);
makeCylinder(CX, floorY + 1, CZ, "prismarine_brick_wall", 6, 1, true);
fill(CX, floorY + 1, CZ, CX, floorY + 3, CZ, "prismarine_bricks");
ps(CX, floorY + 4, CZ, "water");
for (i = 0; i < 6; i++) ps(CX - 3 + i, floorY + 1, CZ + (i % 2 === 0 ? 3 : -3), "lily_pad");
palm(CX - 9, walkY, CZ - 8, 14);
palm(CX + 8, walkY, CZ + 7, 15);
palm(CX - 9, walkY, CZ + 7, 13);
palm(CX + 8, walkY, CZ - 8, 14);
bed(CX - 10, CZ - 9, CX - 7, CZ - 6);
bed(CX + 7, CZ + 5, CX + 10, CZ + 8);
bed(CX - 10, CZ + 5, CX - 7, CZ + 8);
bed(CX + 7, CZ - 9, CX + 10, CZ - 6);
// benches + potting tables
for (i = 0; i < 3; i++) {
    chairStair(CX - 2, walkY, NZ1 + 6 + i * 8, "spruce_stairs", "east");
    chairStair(CX + 2, walkY, SZ1 + 6 + i * 8, "spruce_stairs", "west");
}
for (i = 0; i < 3; i++) {
    pb(NX1 + 8, walkY, SZ1 + 14 + i, "spruce_fence");
    ps(NX1 + 8, walkY + 1, SZ1 + 14 + i, "spruce_slab[type=bottom]");
    pb(NX2 - 8, walkY, NZ1 + 14 + i, "spruce_fence");
    ps(NX2 - 8, walkY + 1, NZ1 + 14 + i, "spruce_slab[type=bottom]");
}
for (i = 0; i < 4; i++) { pb(NX1 + 9, walkY, NZ1 + 4 + i * 3, "flower_pot"); pb(NX2 - 9, walkY, SZ2 - 4 - i * 3, "flower_pot"); }
// gallery planters + seats
for (i = 0; i < 6; i++) { pb(CX - 9 + i * 3, galWalkY, CZ - 9, "flower_pot"); pb(CX - 9 + i * 3, galWalkY, CZ + 9, "flower_pot"); }
chairStair(CX + 9, galWalkY, CZ, "spruce_stairs", "west");
chairStair(CX - 9, galWalkY, CZ, "spruce_stairs", "east");

// === LIGHTING (iron_chain, 1.21.11+) ===
function hangLantern(lx, ly, lz, n) {
    var kk;
    for (kk = 0; kk < n; kk++) ps(lx, ly - kk, lz, "iron_chain[axis=y]");
    ps(lx, ly - n, lz, "lantern[hanging=true]");
}
for (i = 0; i < 6; i++) { hangLantern(CX, SPRING - 1, NZ1 + 3 + i * 4, 2); hangLantern(CX, SPRING - 1, SZ1 + 3 + i * 4, 2); }
hangLantern(CX, domeBaseY - 2, CZ, 5);
hangLantern(CX - 7, domeBaseY - 3, CZ - 7, 3);
hangLantern(CX + 7, domeBaseY - 3, CZ + 7, 3);
for (i = 0; i < 4; i++) { pb(CX - 6 + i * 4, walkY, CZ - 11, "bricks"); ps(CX - 6 + i * 4, walkY + 1, CZ - 11, "lantern"); }
for (i = 0; i < 4; i++) { pb(CX - 9 + i * 6, galWalkY, CZ - 6, "green_concrete"); ps(CX - 9 + i * 6, galWalkY + 1, CZ - 6, "lantern"); }

// === PARK: paths, parterres, lamps, trees ===
for (z = SZ2 + 1; z <= SZ2 + 11; z++) for (x = CX - 2; x <= CX + 1; x++) {
    pb(x, groundY, z, (x + z) % 5 === 0 ? "cobblestone" : "gravel");
    fill(x, groundY + 1, z, x, groundY + 3, z, "air");
}
for (z = NZ1 - 11; z < NZ1; z++) for (x = CX - 2; x <= CX + 1; x++) {
    pb(x, groundY, z, (x + z) % 5 === 0 ? "cobblestone" : "gravel");
    fill(x, groundY + 1, z, x, groundY + 3, z, "air");
}
function lamp(lx, lz) {
    pb(lx, groundY + 1, lz, "cobblestone_wall"); pb(lx, groundY + 2, lz, "cobblestone_wall");
    pb(lx, groundY + 3, lz, "green_concrete"); ps(lx, groundY + 4, lz, "lantern");
}
lamp(CX - 4, SZ2 + 5); lamp(CX + 3, SZ2 + 5); lamp(CX - 4, NZ1 - 5); lamp(CX + 3, NZ1 - 5);
lamp(NX2 + 6, CZ - 10); lamp(NX2 + 6, CZ + 10);
function parterre(px, pz) {
    var xx, zz;
    for (xx = px; xx < px + 6; xx++) for (zz = pz; zz < pz + 6; zz++) {
        if (xx === px || xx === px + 5 || zz === pz || zz === pz + 5) ps(xx, groundY + 1, zz, "stone_brick_slab[type=bottom]");
        else { pb(xx, groundY, zz, "coarse_dirt"); ps(xx, groundY + 1, zz, (xx + zz) % 3 === 0 ? "red_tulip" : ((xx + zz) % 3 === 1 ? "oxeye_daisy" : "cornflower")); }
    }
}
parterre(NX2 + 4, CZ - 4); parterre(NX2 + 12, CZ - 22); parterre(NX2 + 12, CZ + 14);
parterre(CX - 12, SZ2 + 4); parterre(CX + 6, NZ1 - 10);
function parkTree(tx, tz, hh) {
    var kk;
    for (kk = 1; kk <= hh; kk++) pb(tx, groundY + kk, tz, "oak_log");
    makeSphere(tx, groundY + hh + 2, tz, "oak_leaves[persistent=true]", 3, false);
    makeSphere(tx + 1, groundY + hh, tz - 1, "oak_leaves[persistent=true]", 2, false);
}
parkTree(NX2 + 10, CZ - 12, 6); parkTree(NX2 + 14, CZ + 4, 7);
parkTree(BX1 - 6, CZ - 16, 6); parkTree(BX1 - 5, CZ + 14, 5);
parkTree(CX + 12, NZ1 - 8, 6); parkTree(CX - 14, SZ2 + 8, 7);
// hedge border along the park edge
for (z = NZ1 - 12; z <= SZ2 + 12; z += 2) { ps(NX2 + 18, groundY + 1, z, "oak_leaves[persistent=true]"); ps(BX1 - 9, groundY + 1, z, "oak_leaves[persistent=true]"); }
chairStair(NX2 + 7, groundY + 1, CZ - 14, "spruce_stairs", "west");
chairStair(NX2 + 7, groundY + 1, CZ + 14, "spruce_stairs", "west");

Static Renders

Victorian Palm House (indexed) isometric viewisometric
Victorian Palm House (indexed) front viewfront
Victorian Palm House (indexed) side viewside
Victorian Palm House (indexed) back viewback
Victorian Palm House (indexed) top viewtop