// === BUILD PLAN ===
// Subject: 1960s split-screen camper van (VW-bus type) parked at a lakeside campsite
// Scale (vehicles-machines Scale Guide says "vehicle 5-10" — scaled UP to 14 so it can be
// WALKED INTO): length 14 along X (x14 nose .. x28 tail), width 7 along Z (z20..z26),
// height 7 from tyre contact (Y13) to roof (Y19). Ratio 14/7 = 2.0 ~= real T1 (4.3m/2.0m).
// Y LEVELS: ground pad Y12 -> tyres Y13..14 -> chassis floor Y15 -> walkY 16 (ALL furniture)
// -> body rows 16,17,18 -> roof Y19 -> pop-top canvas Y20, lid Y21.
//
// SIDE ELEVATION (x ->, cream over teal, waist at Y18):
// ####pop-top canvas + lid####
// CCCCCCCCCCCCCCCCCCCCCCCC Y19 roof (cream)
// CGGGCC.GGG.CC.GGG.CCCCCC Y18 cream + glazing band
// TTTTTT DOOR TTTTTTTTTTT Y17 teal, sliding-door opening
// =TTTTTTTTTTTTTTTTTTTTTT= Y15-16 teal + chrome bumper
// OO OO Y13-14 tyres
//
// NOSE (x=14, split-screen + V panel): PLAN (top-down):
// .GG#GG. Y18 two windscreens z20 ###############
// .C#V#C. Y17 cream V arms z23 # bench kit #
// OT#V#TO Y16 round headlights z26 ####DOOR#######
// ======= Y15 chrome bumper ^ awning + campfire south
//
// MATERIALS PLAN
// lower body : noisePalette cyan_concrete(55)+cyan_terracotta(25)+warped_planks(20)
// — WHY: teal with a fired/painted variation, warped adds a green-teal note
// upper body : white_concrete(50)+bone_block(30)+smooth_quartz(20) — WHY: cream, brighter up top
// so the two-tone waistline reads at a glance (the ID feature of this van)
// curves : warped_stairs (teal) + quartz_stairs (cream) on every roof/nose/tail edge
// — vehicles-machines: "never leave staircase-stepped hulls"
// tyres : black_concrete(40)+gray_concrete(25)+deepslate(20)+coal_block(15) (doc palette)
// chrome : iron_block + light_gray_concrete; glass: light_blue_stained_glass
// awning : white_wool / orange_wool STRIPES on spruce_fence poles
// ground : hills + lake pad + patches(grass/podzol/coarse_dirt), gravel track
// Interior: bench seat (3 stairs), tiny kitchen unit (barrel + counter stair + cauldron sink),
// folding table, rear cushion bed, hanging lantern, carpet runner.
// Campsite: stone-ringed campfire + 2 folding chairs + cooler + firewood + reeds/lilies/trees.
// === END PLAN ===
var padY = 12;
var groundWalk = padY + 1; // 13 tyres sit here
var floorY = 15; // chassis floor
var walkY = floorY + 1; // 16
var bodyTop = 18; // top body row
var roofY = 19;
var X1 = 14, X2 = 28; // nose .. tail
var Z1 = 20, Z2 = 26; // width
// ---------- PALETTES ----------
var tealPal = noisePalette([{block:'cyan_concrete',weight:55},{block:'cyan_terracotta',weight:25},{block:'warped_planks',weight:20}], {seed:17, freq:0.2});
var creamPal = noisePalette([{block:'white_concrete',weight:50},{block:'bone_block',weight:30},{block:'smooth_quartz',weight:20}], {seed:29, freq:0.18});
var tyrePal = noisePalette([{block:'black_concrete',weight:40},{block:'gray_concrete',weight:25},{block:'deepslate',weight:20},{block:'coal_block',weight:15}], {seed:3, freq:0.3});
// ---------- 1. SITE: lake + camp pad ----------
var land = blob(32, 32, 34, {irregularity:0.45, seed:77});
var h = hills({base:14, amp:3.5, scale:0.05, seed:5});
var lake = blob(46, 14, 15, {irregularity:0.5, seed:41});
h = flatten(h, lake, 8, 8); // lake basin
h = flatten(h, {x0:10, z0:22, x1:40, z1:48}, padY, 8); // flat camp pad
var soil = patches([{block:'grass_block',weight:60},{block:'podzol',weight:18},{block:'coarse_dirt',weight:14},{block:'moss_block',weight:8}], 0.05, 9);
var waterY = 11;
var siteMat = function (x, z) {
if (h(x, z) <= waterY) return 'sand';
if (h(x, z) <= waterY + 1) return 'gravel';
return soil(x, z);
};
surface(land, h, siteMat, {sub:'dirt', deep:'stone', depth:5});
// fill the lake
var lx, lz, ly;
for (lx = 26; lx <= 63; lx++) {
for (lz = 0; lz <= 34; lz++) {
if (lake(lx, lz) && h(lx, lz) < waterY) {
fill(lx, Math.floor(h(lx, lz)) + 1, lz, lx, waterY, lz, 'water');
}
}
}
checkpoint('SITE');
// gravel track arriving from the south
var tx, tz;
for (tz = 42; tz <= 60; tz++) {
for (tx = 18; tx <= 21; tx++) pb(tx, Math.floor(h(tx, tz)), tz, (tx === 19 || tx === 20) ? 'gravel' : 'coarse_dirt');
}
// ---------- 2. RUNNING GEAR ----------
var wheels = [[16, Z1],[16, Z2],[25, Z1],[25, Z2]];
var i, wx, wz;
for (i = 0; i < wheels.length; i++) {
wx = wheels[i][0]; wz = wheels[i][1];
fill(wx - 1, groundWalk, wz, wx + 1, groundWalk + 1, wz, tyrePal);
pb(wx, groundWalk + 1, wz, 'light_gray_concrete'); // hubcap
}
// chassis + underbody shadow
fill(15, groundWalk + 1, Z1 + 1, X2, groundWalk + 1, Z2 - 1, 'gray_concrete');
fill(15, floorY, Z1, X2, floorY, Z2, 'light_gray_concrete');
// chrome bumpers, front and rear, protruding one block
fill(13, floorY, Z1 + 1, 13, floorY, Z2 - 1, 'iron_block');
fill(X2 + 1, floorY, Z1 + 1, X2 + 1, floorY, Z2 - 1, 'iron_block');
ps(13, floorY, Z1, 'quartz_stairs[facing=north,half=bottom]');
ps(13, floorY, Z2, 'quartz_stairs[facing=south,half=bottom]');
checkpoint('CHASSIS');
// ---------- 3. BODY SHELL (two-tone, rounded edges) ----------
// teal lower rows
fill(15, floorY, Z1, X2, walkY + 1, Z1, tealPal);
fill(15, floorY, Z2, X2, walkY + 1, Z2, tealPal);
fill(X2, floorY, Z1, X2, walkY + 1, Z2, tealPal);
// cream upper row + roof
fill(15, bodyTop, Z1, X2, bodyTop, Z1, creamPal);
fill(15, bodyTop, Z2, X2, bodyTop, Z2, creamPal);
fill(X2, bodyTop, Z1, X2, bodyTop, Z2, creamPal);
fill(15, roofY, Z1, X2, roofY, Z2, creamPal);
// hollow the cabin
fill(16, walkY, Z1 + 1, X2 - 1, bodyTop, Z2 - 1, 'air');
// NOSE: narrower front face + chamfered corners = rounded snout
fill(X1, floorY, Z1 + 1, X1, bodyTop, Z2 - 1, tealPal);
fill(X1, bodyTop, Z1 + 1, X1, bodyTop, Z2 - 1, creamPal);
ps(X1, floorY, Z1, 'warped_stairs[facing=north,half=bottom]');
ps(X1, floorY, Z2, 'warped_stairs[facing=south,half=bottom]');
ps(X1, walkY, Z1, 'warped_stairs[facing=north,half=bottom]');
ps(X1, walkY, Z2, 'warped_stairs[facing=south,half=bottom]');
ps(X1, walkY + 1, Z1, 'warped_stairs[facing=north,half=bottom]');
ps(X1, walkY + 1, Z2, 'warped_stairs[facing=south,half=bottom]');
ps(X1, bodyTop, Z1, 'quartz_stairs[facing=north,half=bottom]');
ps(X1, bodyTop, Z2, 'quartz_stairs[facing=south,half=bottom]');
// roof edge rounding all the way round (no stepped box)
var rx, rz;
for (rx = 15; rx <= X2; rx++) {
ps(rx, roofY, Z1 - 1, 'quartz_stairs[facing=north,half=top]');
ps(rx, roofY, Z2 + 1, 'quartz_stairs[facing=south,half=top]');
}
for (rz = Z1; rz <= Z2; rz++) {
ps(X1, roofY, rz, 'quartz_stairs[facing=west,half=top]');
ps(X2 + 1, roofY, rz, 'quartz_stairs[facing=east,half=top]');
}
checkpoint('BODY');
// ---------- 4. SPLIT-SCREEN NOSE, GLAZING, DOOR ----------
// two windscreens split by a centre pillar, V panel + round headlights below
ps(X1, bodyTop, 22, 'light_blue_stained_glass');
ps(X1, bodyTop, 24, 'light_blue_stained_glass');
pb(X1, bodyTop, 23, 'white_concrete'); // split pillar
pb(X1, walkY + 1, 22, 'white_concrete'); // V arms
pb(X1, walkY + 1, 24, 'white_concrete');
pb(X1, walkY + 1, 23, 'white_concrete');
pb(X1, walkY, 21, 'sea_lantern'); // round headlights
pb(X1, walkY, 25, 'sea_lantern');
ps(X1 - 1, walkY, 21, 'quartz_stairs[facing=west,half=bottom]');
ps(X1 - 1, walkY, 25, 'quartz_stairs[facing=west,half=bottom]');
// side glazing band (cabin + rear quarter lights)
var glassX = [17, 18, 22, 23, 26, 27];
for (i = 0; i < glassX.length; i++) {
pb(glassX[i], bodyTop, Z1, 'light_blue_stained_glass');
pb(glassX[i], bodyTop, Z2, 'light_blue_stained_glass');
}
// rear window + tail lights
pb(X2, bodyTop, 22, 'light_blue_stained_glass');
pb(X2, bodyTop, 24, 'light_blue_stained_glass');
pb(X2, walkY, 21, 'red_concrete');
pb(X2, walkY, 25, 'red_concrete');
// sliding side door OPEN on the awning side (z=Z2), 2 wide x 2 tall
fill(20, walkY, Z2, 21, walkY + 1, Z2, 'air');
ps(19, walkY, Z2, 'warped_stairs[facing=east,half=bottom]');
ps(22, walkY, Z2, 'warped_stairs[facing=west,half=bottom]');
// running board under the door
ps(20, floorY, Z2 + 1, 'iron_trapdoor[facing=south,half=bottom,open=false]');
ps(21, floorY, Z2 + 1, 'iron_trapdoor[facing=south,half=bottom,open=false]');
checkpoint('GLAZING');
// ---------- 5. POP-TOP ----------
var popX1 = 21, popX2 = X2 - 1;
var stripe;
for (rx = popX1; rx <= popX2; rx++) {
stripe = ((rx % 2) === 0) ? 'white_wool' : 'light_gray_wool';
pb(rx, roofY + 1, Z1, stripe);
pb(rx, roofY + 1, Z2, stripe);
}
for (rz = Z1; rz <= Z2; rz++) {
pb(popX2, roofY + 1, rz, ((rz % 2) === 0) ? 'white_wool' : 'light_gray_wool');
pb(popX1, roofY + 1, rz, ((rz % 2) === 0) ? 'white_wool' : 'light_gray_wool');
}
fill(popX1, roofY + 2, Z1, popX2, roofY + 2, Z2, creamPal);
// lid tilts UP toward the front, blended with stairs
for (rz = Z1; rz <= Z2; rz++) {
ps(popX1 - 1, roofY + 2, rz, 'quartz_stairs[facing=west,half=bottom]');
ps(popX1 - 1, roofY + 1, rz, 'quartz_stairs[facing=west,half=bottom]');
}
for (rx = popX1; rx <= popX2; rx++) {
ps(rx, roofY + 2, Z1 - 1, 'quartz_stairs[facing=north,half=top]');
ps(rx, roofY + 2, Z2 + 1, 'quartz_stairs[facing=south,half=top]');
}
// roof rack over the front half + surfboard
fill(16, roofY + 1, Z1 + 1, 19, roofY + 1, Z1 + 1, 'oak_fence');
fill(16, roofY + 1, Z2 - 1, 19, roofY + 1, Z2 - 1, 'oak_fence');
fill(17, roofY + 2, 22, 19, roofY + 2, 22, 'yellow_terracotta');
checkpoint('POPTOP');
// ---------- 6. INTERIOR ----------
pb(17, walkY, 22, 'red_carpet'); pb(17, walkY, 23, 'red_carpet'); pb(17, walkY, 24, 'red_carpet');
pb(19, walkY, 23, 'brown_carpet'); pb(20, walkY, 23, 'brown_carpet'); pb(21, walkY, 23, 'brown_carpet');
// front cab: two seats facing the windscreen + steering wheel
chairStair(16, walkY, 22, 'spruce_stairs', 'west');
chairStair(16, walkY, 24, 'spruce_stairs', 'west');
ps(15, walkY + 1, 22, 'oak_trapdoor[facing=west,half=top,open=false]'); // dash
ps(15, walkY + 1, 24, 'oak_trapdoor[facing=west,half=top,open=false]');
// bench seat down the north side
chairStair(23, walkY, Z1 + 1, 'spruce_stairs', 'north');
chairStair(24, walkY, Z1 + 1, 'spruce_stairs', 'north');
chairStair(25, walkY, Z1 + 1, 'spruce_stairs', 'north');
ps(22, walkY, Z1 + 1, 'spruce_wall_sign[facing=east]');
ps(26, walkY, Z1 + 1, 'spruce_wall_sign[facing=west]');
// tiny kitchen unit on the south side by the door
pb(24, walkY, Z2 - 1, 'stripped_spruce_log');
ps(24, walkY + 1, Z2 - 1, 'spruce_stairs[facing=north,half=top]'); // countertop
ps(25, walkY, Z2 - 1, 'water_cauldron[level=3]'); // sink
ps(25, walkY + 1, Z2 - 1, 'tripwire_hook[facing=north]'); // tap
ps(23, walkY, Z2 - 1, 'barrel[facing=up]');
ps(26, walkY, Z2 - 1, 'smoker[facing=north]'); // little stove
// folding table between bench and kitchen
pb(24, walkY, 23, 'oak_fence');
pb(24, walkY + 1, 23, 'oak_pressure_plate');
// rear cushion bed under the pop-top
pb(27, walkY, 22, 'white_carpet'); pb(27, walkY, 23, 'white_carpet'); pb(27, walkY, 24, 'white_carpet');
pb(26, walkY, 23, 'light_blue_carpet');
// hanging lantern from the roof
ps(22, bodyTop, 23, 'chain[axis=y]');
ps(21, bodyTop, 23, 'lantern[hanging=true]');
checkpoint('INTERIOR');
// ---------- 7. STRIPED AWNING ----------
var aw;
for (rx = 16; rx <= 25; rx++) {
aw = ((rx % 2) === 0) ? 'white_wool' : 'orange_wool';
pb(rx, roofY, Z2 + 1, aw);
pb(rx, roofY - 1, Z2 + 2, aw);
pb(rx, roofY - 1, Z2 + 3, aw);
pb(rx, roofY - 2, Z2 + 4, aw);
}
fill(16, groundWalk, Z2 + 4, 16, roofY - 3, Z2 + 4, 'spruce_fence');
fill(25, groundWalk, Z2 + 4, 25, roofY - 3, Z2 + 4, 'spruce_fence');
ps(16, roofY - 3, Z2 + 4, 'lantern');
ps(25, roofY - 3, Z2 + 4, 'lantern');
checkpoint('AWNING');
// ---------- 8. CAMPSITE ----------
// stone-ringed campfire
var ring = [[19,34],[20,34],[21,34],[19,36],[20,36],[21,36],[18,35],[22,35]];
for (i = 0; i < ring.length; i++) pb(ring[i][0], groundWalk, ring[i][1], 'cobblestone');
pb(20, groundWalk, 35, 'campfire[lit=true,facing=north]');
// folding chairs round the fire
chairStair(17, groundWalk, 35, 'spruce_stairs', 'east');
chairStair(24, groundWalk, 35, 'spruce_stairs', 'west');
chairStair(20, groundWalk, 38, 'spruce_stairs', 'north');
// cooler, firewood, washing line
ps(26, groundWalk, 33, 'barrel[facing=up]');
fill(26, groundWalk, 37, 27, groundWalk + 1, 38, 'oak_log[axis=x]');
pb(14, groundWalk, 33, 'spruce_fence'); pb(14, groundWalk + 1, 33, 'spruce_fence');
pb(14, groundWalk + 2, 33, 'spruce_fence');
// picnic table under the awning
pb(19, groundWalk, 31, 'oak_fence'); pb(21, groundWalk, 31, 'oak_fence');
ps(19, groundWalk + 1, 31, 'oak_slab[type=bottom]');
ps(20, groundWalk + 1, 31, 'oak_slab[type=bottom]');
ps(21, groundWalk + 1, 31, 'oak_slab[type=bottom]');
checkpoint('CAMPSITE');
// ---------- 9. SHORE PLANTING ----------
var sx, sz, gy;
for (sx = 24; sx <= 62; sx++) {
for (sz = 0; sz <= 34; sz++) {
gy = Math.floor(h(sx, sz));
if (gy === waterY + 1 && (sx * 5 + sz * 7) % 8 === 0) {
fill(sx, gy + 1, sz, sx, gy + 1 + ((sx + sz) % 3), sz, 'sugar_cane');
}
if (gy < waterY && (sx * 3 + sz * 11) % 27 === 0) pb(sx, waterY + 1, sz, 'lily_pad');
}
}
var flora = [[12,26],[13,40],[30,44],[36,40],[8,34],[34,52],[16,52],[42,30]];
for (i = 0; i < flora.length; i++) {
sx = flora[i][0]; sz = flora[i][1]; gy = Math.floor(h(sx, sz));
if ((i % 3) === 0) placeTree(sx, gy + 1, sz, 'birch');
else if ((i % 3) === 1) placeTree(sx, gy + 1, sz, 'oak');
else fill(sx, gy + 1, sz, sx, gy + 2, sz, 'short_grass');
}
for (sx = 8; sx <= 44; sx += 3) {
for (sz = 44; sz <= 58; sz += 5) {
gy = Math.floor(h(sx, sz));
pb(sx, gy + 1, sz, ((sx + sz) % 2 === 0) ? 'short_grass' : 'dandelion');
}
}
checkpoint('PLANTING');