← Back to Gallery

Loading 3D viewer…

Highland Whisky Distillery (indexed)

by Jorge Barbero

Dimensions
80×52×72
Blocks
86,791
Compute Time
9.8s
Generation Time
4m 40s
Edits
1
Model
claude-opus-5
Created
August 20, 2026
autoevalindexeddistilleryscottish
Prompt

User Prompt

a Scottish Highland whisky distillery: long whitewashed stone still house with a tall pagoda-roofed malt kiln chimney, small-paned windows, slate roof, copper pot stills inside the still room, oak cask stacks and a wooden mezzanine reached by stairs, mossy riverside setting with a low stone wall

Enhanced Prompt

indexed condition: search_docs({action:'related'}) routed to landscape-environment terrain superpowers + river(), architecture-guide 6.Japanese/Pagoda (curved eaves), build-rules Construction Order + mask workflow. LAYERED process: placeholder form -> clearMasked carving -> replaceMasked texturing.

Photos

Exterior
Exteriorexterior
Still room
Still roominterior
Mezzanine gallery
Mezzanine galleryinterior
Stairs
Stairsinterior
CraftScript Source
// === BUILD PLAN ===
// Style: Scottish Highland distillery (harled stone, slate, pagoda malt kiln) — LAYERED build
// Footprint: T-plan. Still house 13x19 (x28..40, z30..48, ridge along Z) + malt kiln tower 9x9
//            (x30..38, z22..30) at the NORTH end + bonded warehouse 13x9 (x14..26, z36..44) west,
//            joined by a link corridor. Front door on the MAX-Z facade (faces the camera).
// Height: walls Y14..22 (8 air) | ridge Y29 | kiln tower Y30 + curved pagoda tiers to Y44
//
// GROUND FLOOR (top-down, 1 char = 1 block, Z down = toward camera):
//   z22   #########        <- pagoda malt kiln (fire pit + drying grate)
//   z30   ####D####
//   z31   #  MEZZANINE OVER (Y18)  #     mash tun (O)
//   z40   #   [ ]washbacks   [ ]   #
//   z45   #   (O) still   (O) still#
//   z48   ##W##DD##W##      <- ENTRANCE facade (+Z, toward camera)
//   west wing: warehouse of dunnage cask racks, linked at z39..41
//
// FRONT (+Z) ELEVATION:
//        /\        pagoda behind
//       /  \      _/\_
//      |W DD W|   |__|
//      |______|
//
// MATERIALS PLAN (LAYERED: placeholders -> masks -> texture LAST):
//   walls  : placeholder white_wool -> replaceMasked gradientPalette mossy_cobble->calcite->smooth_quartz
//            — WHY: harled whitewash that gets damp/mossy at the bottom (fake AO, describes the volume)
//   tower  : placeholder light_gray_wool -> replaceMasked noisePalette calcite/white_terracotta/diorite
//   wareh. : placeholder brown_wool -> replaceMasked noisePalette dark stone + dark_oak frame
//   roof   : deepslate_tile / cobbled_deepslate / deepslate_brick STAIRS via per-stair palette (facing kept)
//   accents: waxed copper stills, spruce gallery, iron bars, lanterns
// Rooms: Still room (mash tun, 2 washbacks, 2 pot stills, spirit safe), Mezzanine gallery (casks, desk),
//        Malt kiln (hearth, grate, malt sacks), Warehouse (dunnage racks 3 high)
// STAIR PLAN: delta walkY14 -> mezzWalkY19 = 5 -> staircase(30,44,14,19,'north'), lands flush on the gallery lip
// === END PLAN ===

var padY = 12;
var floorY = padY + 1;      // 13
var walkY = floorY + 1;     // 14
var wallTopY = 22;
var roofBaseY = wallTopY + 1;
var mezzFloorY = 18;
var mezzWalkY = mezzFloorY + 1;

// === TERRAIN (superpowers: blob + hills + flatten + river + surface) ===
var land = blob(38, 36, 38, {irregularity: 0.38, seed: 15});
var h = hills({base: 10, amp: 4, scale: 0.045, seed: 6});
h = flatten(h, {x0: 12, z0: 20, x1: 60, z1: 58}, padY, 9);
var ground = h;
var riv = null;
try {
    riv = river({from: [-4, 6], to: [78, 16], heightFn: h, halfWidth: 5, widthVar: 0.45, seed: 4, bounds: land.bounds});
    ground = riv.height;
} catch (e) { riv = null; }
var mat = function (x, z) {
    if (riv && riv.inChannel(x, z)) return 'gravel';
    var n = noise2d('perlin', x, z, {seed: 22});
    if (ground(x, z) > padY + 2) return n > 0.55 ? 'stone' : 'coarse_dirt';
    return n > 0.62 ? 'moss_block' : (n > 0.3 ? 'grass_block' : 'podzol');
};
surface(land, ground, mat, {sub: 'dirt', deep: 'stone', depth: 5});

// === LAYER 1 : FORM IN PLACEHOLDERS ===
var SHx1 = 28, SHx2 = 40, SHz1 = 30, SHz2 = 48;
var KTx1 = 30, KTx2 = 38, KTz1 = 22, KTz2 = 30, KTtop = 30;
var WHx1 = 14, WHx2 = 26, WHz1 = 36, WHz2 = 44, WHtop = 19;

function perim(x1, z1, x2, z2, y1, y2, pat) {
    fill(x1, y1, z1, x2, y2, z1, pat);
    fill(x1, y1, z2, x2, y2, z2, pat);
    fill(x1, y1, z1, x1, y2, z2, pat);
    fill(x2, y1, z1, x2, y2, z2, pat);
}

// plinths (stone platform, 1 block proud — Highland buildings sit on a plinth)
fill(SHx1 - 1, padY - 3, SHz1 - 1, SHx2 + 1, floorY, SHz2 + 1, 'stone_bricks');
fill(KTx1 - 1, padY - 3, KTz1 - 1, KTx2 + 1, floorY, KTz2 + 1, 'stone_bricks');
fill(WHx1 - 1, padY - 3, WHz1 - 1, WHx2 + 1, floorY, WHz2 + 1, 'stone_bricks');
fill(26, padY - 3, 38, 28, floorY, 42, 'stone_bricks');

// walls as placeholders
perim(SHx1, SHz1, SHx2, SHz2, floorY + 1, wallTopY, 'white_wool');
perim(KTx1, KTz1, KTx2, KTz2, floorY + 1, KTtop, 'light_gray_wool');
perim(WHx1, WHz1, WHx2, WHz2, floorY + 1, WHtop, 'brown_wool');
perim(26, 38, 28, 42, floorY + 1, 18, 'brown_wool');
// solid infill so clearMasked has something to carve
fill(SHx1, floorY + 1, SHz1, SHx2, wallTopY, SHz2, 'white_wool');
fill(KTx1, floorY + 1, KTz1, KTx2, KTtop, KTz2, 'light_gray_wool');
fill(WHx1, floorY + 1, WHz1, WHx2, WHtop, WHz2, 'brown_wool');
fill(26, floorY + 1, 38, 28, 18, 42, 'brown_wool');

// === LAYER 2 : CARVE WITH MASKS (rooms, doors, windows) ===
clearMasked(SHx1 + 1, walkY, SHz1 + 1, SHx2 - 1, wallTopY - 1, SHz2 - 1, onlyMaterial('white_wool'));
clearMasked(KTx1 + 1, walkY, KTz1 + 1, KTx2 - 1, KTtop - 1, KTz2 - 1, onlyMaterial('light_gray_wool'));
clearMasked(WHx1 + 1, walkY, WHz1 + 1, WHx2 - 1, WHtop - 1, WHz2 - 1, onlyMaterial('brown_wool'));
clearMasked(27, walkY, 39, 27, 17, 41, onlyMaterial('brown_wool'));
// link corridor doorways
clearMasked(26, walkY, 39, 26, walkY + 2, 41, onlyMaterial('brown_wool'));
clearMasked(28, walkY, 39, 28, walkY + 2, 41, onlyMaterial('white_wool'));
// still house <-> kiln doorway
clearMasked(33, walkY, SHz1, 35, walkY + 2, SHz1, onlyMaterial('white_wool'));
clearMasked(33, walkY, KTz2, 35, walkY + 2, KTz2, onlyMaterial('light_gray_wool'));
// MAIN ENTRANCE on the +Z facade
clearMasked(33, walkY, SHz2, 34, walkY + 3, SHz2, onlyMaterial('white_wool'));
// small-paned windows: front, and rows down both long walls
var wslots = [];
function carveWin(x1, y1, z1, x2, y2, z2, ph) {
    clearMasked(x1, y1, z1, x2, y2, z2, onlyMaterial(ph));
    wslots.push([x1, y1, z1, x2, y2, z2]);
}
carveWin(30, walkY + 1, SHz2, 31, walkY + 3, SHz2, 'white_wool');
carveWin(36, walkY + 1, SHz2, 37, walkY + 3, SHz2, 'white_wool');
carveWin(32, mezzWalkY + 1, SHz2, 36, mezzWalkY + 2, SHz2, 'white_wool');
var wz;
for (wz = 33; wz <= 45; wz += 4) {
    carveWin(SHx1, walkY + 1, wz, SHx1, walkY + 3, wz + 1, 'white_wool');
    carveWin(SHx2, walkY + 1, wz, SHx2, walkY + 3, wz + 1, 'white_wool');
    carveWin(SHx1, mezzWalkY + 1, wz, SHx1, mezzWalkY + 2, wz, 'white_wool');
    carveWin(SHx2, mezzWalkY + 1, wz, SHx2, mezzWalkY + 2, wz, 'white_wool');
}
// kiln slit windows
carveWin(KTx1, walkY + 4, 25, KTx1, walkY + 6, 27, 'light_gray_wool');
carveWin(KTx2, walkY + 4, 25, KTx2, walkY + 6, 27, 'light_gray_wool');
carveWin(33, walkY + 8, KTz1, 35, walkY + 10, KTz1, 'light_gray_wool');
// warehouse door (+Z) + slits
clearMasked(20, walkY, WHz2, 20, walkY + 1, WHz2, onlyMaterial('brown_wool'));
carveWin(17, walkY + 2, WHz2, 17, walkY + 3, WHz2, 'brown_wool');
carveWin(23, walkY + 2, WHz2, 23, walkY + 3, WHz2, 'brown_wool');
carveWin(WHx1, walkY + 2, 39, WHx1, walkY + 3, 41, 'brown_wool');

// === LAYER 3 : TEXTURE LAST (replaceMasked over the placeholders) ===
var shPal = gradientPalette(floorY, wallTopY, [
    {block: 'mossy_cobblestone', from: 0}, {block: 'cobblestone', from: 0.18},
    {block: 'calcite', from: 0.38}, {block: 'smooth_quartz', from: 0.68}, {block: 'white_terracotta', from: 0.85}
], {noise: 0.3, seed: 12});
var ktPal = noisePalette([
    {block: 'calcite', weight: 40}, {block: 'white_terracotta', weight: 30},
    {block: 'diorite', weight: 18}, {block: 'smooth_quartz', weight: 12}
], {seed: 3, freq: 0.11});
var whPal = noisePalette([
    {block: 'cobblestone', weight: 38}, {block: 'mossy_cobblestone', weight: 27},
    {block: 'stone_bricks', weight: 20}, {block: 'andesite', weight: 15}
], {seed: 8, freq: 0.12});
replaceMasked(SHx1 - 2, floorY, SHz1 - 2, SHx2 + 2, wallTopY + 2, SHz2 + 2, shPal, onlyMaterial('white_wool'));
replaceMasked(KTx1 - 2, floorY, KTz1 - 2, KTx2 + 2, KTtop + 2, KTz2 + 2, ktPal, onlyMaterial('light_gray_wool'));
replaceMasked(WHx1 - 2, floorY, WHz1 - 2, WHx2 + 2, WHtop + 2, WHz2 + 2, whPal, onlyMaterial('brown_wool'));
replaceMasked(25, floorY, 37, 29, 19, 43, whPal, onlyMaterial('brown_wool'));
// glaze every carved window slot with panes (only where air)
var i, s;
for (i = 0; i < wslots.length; i++) {
    s = wslots[i];
    fillMasked(s[0], s[1], s[2], s[3], s[4], s[5], 'glass_pane', onlyAir());
}
// astragals / mullions: iron bars across the middle row of the big windows
for (wz = 33; wz <= 45; wz += 4) {
    fill(SHx1, walkY + 2, wz, SHx1, walkY + 2, wz + 1, 'iron_bars');
    fill(SHx2, walkY + 2, wz, SHx2, walkY + 2, wz + 1, 'iron_bars');
}

// === WALL DEPTH : pilasters, sills, cornice ===
for (var px = SHx1; px <= SHx2; px += 4) {
    fill(px, floorY + 1, SHz1 - 1, px, wallTopY, SHz1 - 1, 'stone_bricks');
    fill(px, floorY + 1, SHz2 + 1, px, wallTopY, SHz2 + 1, 'stone_bricks');
}
for (var pz = SHz1 + 2; pz <= SHz2 - 2; pz += 4) {
    fill(SHx1 - 1, floorY + 1, pz, SHx1 - 1, wallTopY, pz, 'stone_bricks');
    fill(SHx2 + 1, floorY + 1, pz, SHx2 + 1, wallTopY, pz, 'stone_bricks');
}
perim(SHx1 - 1, SHz1 - 1, SHx2 + 1, SHz2 + 1, wallTopY, wallTopY, 'stone_brick_slab[type=top]');
perim(WHx1 - 1, WHz1 - 1, WHx2 + 1, WHz2 + 1, WHtop, WHtop, 'cobblestone_slab[type=top]');
// window sills
for (wz = 33; wz <= 45; wz += 4) {
    ps(SHx1 - 1, walkY, wz, 'stone_brick_slab[type=top]');
    ps(SHx2 + 1, walkY, wz, 'stone_brick_slab[type=top]');
}
// entrance surround + doors (+Z facade)
ps(33, walkY, SHz2, 'dark_oak_door[facing=north,half=lower,hinge=left]');
ps(33, walkY + 1, SHz2, 'dark_oak_door[facing=north,half=upper,hinge=left]');
ps(34, walkY, SHz2, 'dark_oak_door[facing=north,half=lower,hinge=right]');
ps(34, walkY + 1, SHz2, 'dark_oak_door[facing=north,half=upper,hinge=right]');
fill(32, walkY, SHz2 + 1, 32, walkY + 3, SHz2 + 1, 'stone_bricks');
fill(35, walkY, SHz2 + 1, 35, walkY + 3, SHz2 + 1, 'stone_bricks');
fill(32, walkY + 4, SHz2 + 1, 35, walkY + 4, SHz2 + 1, 'stone_brick_slab[type=top]');
ps(33, walkY + 4, SHz2 + 1, 'oak_wall_sign[facing=south]');
ps(34, walkY + 4, SHz2 + 1, 'oak_wall_sign[facing=south]');
pb(32, walkY + 3, SHz2 + 2, 'chain[axis=y]'); ps(32, walkY + 2, SHz2 + 2, 'lantern[hanging=true]');
pb(35, walkY + 3, SHz2 + 2, 'chain[axis=y]'); ps(35, walkY + 2, SHz2 + 2, 'lantern[hanging=true]');

// === ROOF : slate gable, ridge along Z (slopes E/W), per-stair palette keeps facing ===
var slate = noisePalette([
    {block: 'deepslate_tile_stairs', weight: 46}, {block: 'cobbled_deepslate_stairs', weight: 30},
    {block: 'deepslate_brick_stairs', weight: 24}
], {seed: 5, freq: 0.17});
var halfW = 7; // width 13
for (var rz = SHz1 - 1; rz <= SHz2 + 1; rz++) {
    for (var st = 0; st < halfW; st++) {
        roofStair(SHx1 - 1 + st, roofBaseY + st, rz, slate(SHx1 + st, 0, rz), 'west');
        roofStair(SHx2 + 1 - st, roofBaseY + st, rz, slate(SHx2 - st, 0, rz), 'east');
    }
    pb(34, roofBaseY + halfW - 1, rz, 'deepslate_tiles'); // solid ridge beam
}
// gable triangles at both ends
for (var gs = 0; gs < halfW; gs++) {
    for (var gx = SHx1 + gs; gx <= SHx2 - gs; gx++) {
        pb(gx, roofBaseY + gs, SHz1, shPal(gx, roofBaseY + gs, SHz1));
        pb(gx, roofBaseY + gs, SHz2, shPal(gx, roofBaseY + gs, SHz2));
    }
}
// gable vent + skylight strip on the +Z gable
fill(33, roofBaseY + 2, SHz2, 34, roofBaseY + 3, SHz2, 'glass_pane');
// eave brackets under the overhang (visual support, upside-down stairs)
for (var bz = SHz1; bz <= SHz2; bz += 3) {
    ps(SHx1 - 2, roofBaseY - 1, bz, 'spruce_stairs[facing=east,half=top]');
    ps(SHx2 + 2, roofBaseY - 1, bz, 'spruce_stairs[facing=west,half=top]');
}
// warehouse roof (ridge along X, slopes N/S)
var whHalf = 5;
for (var wx = WHx1 - 1; wx <= WHx2 + 1; wx++) {
    for (var ws = 0; ws < whHalf; ws++) {
        roofStair(wx, WHtop + 1 + ws, WHz1 - 1 + ws, slate(wx, 0, WHz1 + ws), 'north');
        roofStair(wx, WHtop + 1 + ws, WHz2 + 1 - ws, slate(wx, 0, WHz2 - ws), 'south');
    }
    pb(wx, WHtop + whHalf, 40, 'deepslate_tiles');
}
for (var ws2 = 0; ws2 < whHalf; ws2++) {
    for (var wgz = WHz1 + ws2; wgz <= WHz2 - ws2; wgz++) {
        pb(WHx1, WHtop + 1 + ws2, wgz, whPal(WHx1, WHtop + 1 + ws2, wgz));
        pb(WHx2, WHtop + 1 + ws2, wgz, whPal(WHx2, WHtop + 1 + ws2, wgz));
    }
}
// link corridor flat roof
fill(26, 19, 38, 28, 19, 42, 'spruce_slab[type=top]');

// === MALT KILN : tower body already placed; add curved pagoda tiers ===
function ringStairs(x1, z1, x2, z2, y, matFn) {
    var a;
    for (a = x1; a <= x2; a++) {
        roofStair(a, y, z1, matFn(a, 0, z1), 'north');
        roofStair(a, y, z2, matFn(a, 0, z2), 'south');
    }
    for (a = z1 + 1; a <= z2 - 1; a++) {
        roofStair(x1, y, a, matFn(x1, 0, a), 'west');
        roofStair(x2, y, a, matFn(x2, 0, a), 'east');
    }
}
function pagodaTier(x1, z1, x2, z2, baseY, matFn) {
    // thin eave lip (widest), then two stair layers stepping in and up = curved eave
    perim(x1 - 2, z1 - 2, x2 + 2, z2 + 2, baseY, baseY, 'deepslate_tile_slab[type=top]');
    ringStairs(x1 - 1, z1 - 1, x2 + 1, z2 + 1, baseY + 1, matFn);
    ringStairs(x1, z1, x2, z2, baseY + 2, matFn);
    fill(x1 + 1, baseY + 3, z1 + 1, x2 - 1, baseY + 3, z2 - 1, 'deepslate_tiles');
    // upturned corner tips (Japanese eave flick)
    ps(x1 - 2, baseY + 1, z1 - 2, 'deepslate_tile_stairs[facing=south,half=top]');
    ps(x2 + 2, baseY + 1, z1 - 2, 'deepslate_tile_stairs[facing=south,half=top]');
    ps(x1 - 2, baseY + 1, z2 + 2, 'deepslate_tile_stairs[facing=north,half=top]');
    ps(x2 + 2, baseY + 1, z2 + 2, 'deepslate_tile_stairs[facing=north,half=top]');
}
// dark timber cornice under the first tier
perim(KTx1 - 1, KTz1 - 1, KTx2 + 1, KTz2 + 1, KTtop, KTtop, 'dark_oak_log[axis=x]');
pagodaTier(KTx1, KTz1, KTx2, KTz2, KTtop + 1, slate);
// second stage (inset per pagoda rule) + its own curved roof
fill(KTx1 + 2, KTtop + 4, KTz1 + 2, KTx2 - 2, 37, KTz2 - 2, 'air');
perim(KTx1 + 2, KTz1 + 2, KTx2 - 2, KTz2 - 2, KTtop + 4, 37, ktPal);
fill(KTx1 + 2, KTtop + 4, KTz1 + 2, KTx1 + 2, 37, KTz1 + 2, 'dark_oak_log[axis=y]');
fill(KTx2 - 2, KTtop + 4, KTz1 + 2, KTx2 - 2, 37, KTz1 + 2, 'dark_oak_log[axis=y]');
fill(KTx1 + 2, KTtop + 4, KTz2 - 2, KTx1 + 2, 37, KTz2 - 2, 'dark_oak_log[axis=y]');
fill(KTx2 - 2, KTtop + 4, KTz2 - 2, KTx2 - 2, 37, KTz2 - 2, 'dark_oak_log[axis=y]');
fill(34, 36, KTz1 + 2, 34, 36, KTz2 - 2, 'spruce_trapdoor[facing=north,half=top,open=false]');
pagodaTier(KTx1 + 2, KTz1 + 2, KTx2 - 2, KTz2 - 2, 38, slate);
// copper cowl + vane on top
makeCylinder(34, 42, 26, 'waxed_exposed_copper', 1, 2, true);
pb(34, 44, 26, 'waxed_copper_block');
pb(34, 45, 26, 'lightning_rod');

// === INTERIORS ===
var stonePal = noisePalette([
    {block: 'stone_bricks', weight: 38}, {block: 'andesite', weight: 26},
    {block: 'cobblestone', weight: 20}, {block: 'mossy_stone_bricks', weight: 16}
], {seed: 27, freq: 0.14});
fill(SHx1 + 1, floorY, SHz1 + 1, SHx2 - 1, floorY, SHz2 - 1, stonePal);
fill(KTx1 + 1, floorY, KTz1 + 1, KTx2 - 1, floorY, KTz2 - 1, stonePal);
fill(WHx1 + 1, floorY, WHz1 + 1, WHx2 - 1, floorY, WHz2 - 1, 'coarse_dirt');
fill(27, floorY, 39, 27, floorY, 41, stonePal);

// ceiling tie beams
for (var tb = SHz1 + 3; tb <= SHz2 - 3; tb += 4) {
    fill(SHx1 + 1, wallTopY - 1, tb, SHx2 - 1, wallTopY - 1, tb, 'dark_oak_log[axis=x]');
}
// mash tun (spruce, copper lid)
makeCylinder(33, walkY, 34, noisePalette([{block: 'spruce_planks', weight: 60}, {block: 'stripped_spruce_log', weight: 40}], {seed: 2}), 3, 4, true);
makeCylinder(33, walkY + 4, 34, 'waxed_exposed_copper', 3, 1, true);
pb(33, walkY + 5, 34, 'waxed_copper_block');
ps(30, walkY, 34, 'lever[face=wall,facing=west]');
// two washbacks
function washback(cx, cz) {
    makeCylinder(cx, walkY, cz, 'spruce_planks', 2, 3, true);
    makeCylinder(cx, walkY + 3, cz, 'dark_oak_planks', 2, 1, false);
    pb(cx, walkY + 3, cz, 'water');
    ps(cx, walkY, cz - 2, 'spruce_trapdoor[facing=south,half=bottom,open=false]');
}
washback(31, 40); washback(37, 40);
// two copper pot stills (open to the roof, seen from the entrance)
function potStill(cx, cz) {
    fill(cx - 2, floorY, cz - 2, cx + 2, floorY, cz + 2, 'polished_andesite');
    makeCylinder(cx, walkY, cz, 'bricks', 2, 1, true);
    ps(cx, walkY, cz + 2, 'campfire[lit=true]');
    makeCylinder(cx, walkY + 1, cz, noisePalette([{block: 'waxed_copper_block', weight: 60}, {block: 'waxed_exposed_copper', weight: 25}, {block: 'waxed_cut_copper', weight: 15}], {seed: 31}), 2, 4, true);
    makeCylinder(cx, walkY + 5, cz, 'waxed_cut_copper', 1, 3, true);
    pb(cx, walkY + 8, cz, 'waxed_copper_block');
    pb(cx, walkY + 9, cz, 'waxed_copper_block');
    pb(cx, walkY + 9, cz + 1, 'waxed_exposed_copper');
    pb(cx, walkY + 8, cz + 2, 'waxed_exposed_copper');
    pb(cx, walkY + 7, cz + 2, 'copper_bulb[lit=true]');
    makeCylinder(cx, walkY + 3, cz, 'waxed_oxidized_cut_copper', 2, 1, false);
}
potStill(31, 45); potStill(37, 45);
// spirit safe + bench beside the entrance
pb(34, walkY, 46, 'stripped_dark_oak_log');
ps(34, walkY + 1, 46, 'glass');
pb(33, walkY, 46, 'stripped_dark_oak_log');
ps(33, walkY + 1, 46, 'brewing_stand');
ps(35, walkY, 46, 'barrel[facing=up]');
rug(32, walkY, 47, 4, 1, 'red', 'brown');

// mezzanine gallery + posts + railing, then the staircase (cuts its own hole)
fill(SHx1 + 1, mezzFloorY, SHz1 + 1, SHx2 - 1, mezzFloorY, 39, 'spruce_planks');
fill(33, mezzFloorY, 40, 35, mezzFloorY, 40, 'spruce_planks');
for (var mx = SHx1 + 2; mx <= SHx2 - 2; mx += 4) {
    for (var mz = SHz1 + 2; mz <= 38; mz += 4) {
        fill(mx, walkY, mz, mx, mezzFloorY - 1, mz, 'spruce_log[axis=y]');
    }
}
for (var rx = SHx1 + 1; rx <= SHx2 - 1; rx++) {
    if (rx < 33 || rx > 35) pb(rx, mezzWalkY, 39, 'spruce_fence');
}
// stair moved to the CENTRE AISLE — the old run at x30 came up inside a washback
fill(33, walkY, 39, 35, mezzFloorY - 1, 45, 'air');
fill(33, floorY, 39, 35, floorY, 45, stonePal);
staircase(34, 44, walkY, mezzWalkY, 'north', {material: 'dark_oak_stairs', rail: 'dark_oak_fence'});
// gallery contents
for (var gcx = 30; gcx <= 38; gcx += 3) {
    pb(gcx, mezzWalkY, 33, 'barrel[facing=up]');
    pb(gcx, mezzWalkY + 1, 33, 'barrel[facing=up]');
    pb(gcx + 1, mezzWalkY, 33, 'hay_block');
}
ps(31, mezzWalkY, 36, 'lectern[facing=east]');
chairStair(30, mezzWalkY, 36, 'dark_oak_stairs', 'east');
pb(35, mezzWalkY, 36, 'dark_oak_fence'); pb(35, mezzWalkY + 1, 36, 'dark_oak_pressure_plate');
pb(36, mezzWalkY, 36, 'barrel[facing=up]');
rug(33, mezzWalkY, 37, 4, 2, 'brown', 'gray');
pb(33, wallTopY - 1, 35, 'chain[axis=y]'); ps(33, wallTopY - 2, 35, 'lantern[hanging=true]');
pb(37, wallTopY - 1, 37, 'chain[axis=y]'); ps(37, wallTopY - 2, 37, 'lantern[hanging=true]');
// ground-floor lighting under the gallery
for (var glz = 33; glz <= 47; glz += 4) {
    pb(29, glz > 39 ? wallTopY - 1 : mezzFloorY - 1, glz, 'chain[axis=y]');
    ps(29, (glz > 39 ? wallTopY - 1 : mezzFloorY - 1) - 1, glz, 'lantern[hanging=true]');
    pb(39, glz > 39 ? wallTopY - 1 : mezzFloorY - 1, glz, 'chain[axis=y]');
    ps(39, (glz > 39 ? wallTopY - 1 : mezzFloorY - 1) - 1, glz, 'lantern[hanging=true]');
}

// malt kiln interior
fill(32, floorY, 24, 36, floorY, 28, 'stone_bricks');
fill(33, walkY, 25, 35, walkY, 27, 'iron_bars');
ps(34, floorY, 26, 'campfire[lit=true]');
fill(31, walkY, 23, 31, walkY + 1, 25, 'hay_block');
pb(37, walkY, 23, 'barrel[facing=up]'); pb(37, walkY, 28, 'composter');
pb(36, walkY, 29, 'cauldron[level=2]');
ps(31, walkY, 28, 'ladder[facing=east]');
ps(31, walkY + 1, 28, 'ladder[facing=east]');
ps(31, walkY + 2, 28, 'ladder[facing=east]');
pb(34, walkY + 6, 26, 'chain[axis=y]'); ps(34, walkY + 5, 26, 'lantern[hanging=true]');

// warehouse: dunnage cask racks 3 high
for (var dz = WHz1 + 2; dz <= WHz2 - 2; dz += 3) {
    for (var dx = WHx1 + 2; dx <= WHx2 - 2; dx += 3) {
        pb(dx, walkY, dz, 'oak_log[axis=x]'); pb(dx + 1, walkY, dz, 'oak_log[axis=x]');
        pb(dx, walkY + 1, dz, 'barrel[facing=up]'); pb(dx + 1, walkY + 1, dz, 'barrel[facing=up]');
        pb(dx, walkY + 2, dz, 'barrel[facing=up]'); pb(dx + 1, walkY + 2, dz, 'barrel[facing=up]');
    }
}
pb(20, WHtop - 1, 40, 'chain[axis=y]'); ps(20, WHtop - 2, 40, 'lantern[hanging=true]');
pb(16, WHtop - 1, 43, 'chain[axis=y]'); ps(16, WHtop - 2, 43, 'lantern[hanging=true]');
ps(24, walkY, WHz2 - 1, 'cartography_table');

// === EXTERIOR : yard, wall, riverside ===
var pathPal = noisePalette([{block: 'gravel', weight: 42}, {block: 'cobblestone', weight: 33}, {block: 'andesite', weight: 25}], {seed: 19});
for (var qz = 49; qz <= 60; qz++) {
    for (var qx = 31; qx <= 36; qx++) {
        pb(qx, Math.floor(ground(qx, qz)), qz, pathPal(qx, 0, qz));
    }
}
for (var yx = 16; yx <= 44; yx++) {
    pb(yx, Math.floor(ground(yx, 47)), 47, pathPal(yx, 0, 47));
    pb(yx, Math.floor(ground(yx, 48)), 48, pathPal(yx, 0, 48));
}
// low mossy stone wall around the site (follows the ground)
function wallRun(x1, z1, x2, z2) {
    var a;
    if (x1 === x2) { for (a = z1; a <= z2; a++) pb(x1, Math.floor(ground(x1, a)) + 1, a, 'mossy_cobblestone_wall'); }
    else { for (a = x1; a <= x2; a++) pb(a, Math.floor(ground(a, z1)) + 1, z1, 'mossy_cobblestone_wall'); }
}
wallRun(10, 58, 62, 58);
wallRun(10, 20, 10, 58);
wallRun(62, 20, 62, 58);
wallRun(10, 20, 62, 20);
fill(31, padY, 58, 36, padY + 3, 58, 'air');
pb(30, padY + 1, 58, 'mossy_cobblestone_wall'); pb(37, padY + 1, 58, 'mossy_cobblestone_wall');
pb(30, padY + 2, 58, 'stone_brick_slab[type=bottom]'); pb(37, padY + 2, 58, 'stone_brick_slab[type=bottom]');
lampPost(30, padY + 1, 52, 4, 'cobblestone_wall');
lampPost(37, padY + 1, 52, 4, 'cobblestone_wall');
lampPost(24, padY + 1, 47, 4, 'cobblestone_wall');
lampPost(44, padY + 1, 34, 4, 'cobblestone_wall');
// outdoor cask stack + cart by the yard
for (var oy = 0; oy < 3; oy++) {
    for (var oxx = 42 + oy; oxx <= 50 - oy; oxx += 2) {
        pb(oxx, padY + 1 + oy, 44, 'barrel[facing=up]');
        pb(oxx, padY + 1 + oy, 46, 'barrel[facing=up]');
    }
}
pb(44, padY + 1, 50, 'oak_log[axis=x]'); pb(45, padY + 1, 50, 'oak_log[axis=x]');
ps(46, padY + 1, 50, 'oak_fence');
// riverside: jetty + mossy boulders + reeds
if (riv) {
    for (var jz = 18; jz <= 24; jz++) {
        for (var jx = 33; jx <= 35; jx++) {
            pb(jx, riv.waterY + 1, jz, 'spruce_planks');
        }
        pb(32, riv.waterY + 1, jz, 'spruce_fence');
        pb(36, riv.waterY + 1, jz, 'spruce_fence');
    }
    pb(34, riv.waterY + 2, 19, 'barrel[facing=up]');
    pb(33, riv.waterY + 2, 20, 'barrel[facing=up]');
    lampPost(36, riv.waterY + 1, 22, 3, 'oak_fence');
}
for (var brx = 18; brx <= 54; brx += 6) {
    var bgy = Math.floor(ground(brx, 26 + (brx % 5)));
    makeSphere(brx, bgy, 26 + (brx % 5), noisePalette([{block: 'mossy_cobblestone', weight: 58}, {block: 'stone', weight: 27}, {block: 'andesite', weight: 15}], {seed: 14}), 2, true);
}
try {
    placeTree(20, padY + 1, 28, 'spruce');
    placeTree(48, padY + 1, 26, 'spruce');
    placeTree(52, padY + 1, 52, 'oak');
    placeTree(16, padY + 1, 52, 'spruce');
    placeTree(24, padY + 1, 24, 'spruce');
} catch (e) { }
// ground cover
for (var vx = 12; vx <= 60; vx++) {
    for (var vz = 20; vz <= 58; vz++) {
        var nn = noise2d('perlin', vx * 1.9, vz * 1.9, {seed: 41});
        if (nn > 0.87 && (vx < 26 || vx > 42 || vz < 28 || vz > 50)) {
            var gy2 = Math.floor(ground(vx, vz));
            pb(vx, gy2 + 1, vz, nn > 0.945 ? 'fern' : (nn > 0.91 ? 'grass' : 'moss_carpet'));
        }
    }
}

Static Renders

Highland Whisky Distillery (indexed) isometric viewisometric
Highland Whisky Distillery (indexed) front viewfront
Highland Whisky Distillery (indexed) side viewside
Highland Whisky Distillery (indexed) back viewback
Highland Whisky Distillery (indexed) top viewtop