// === BUILD PLAN ===
// Style: planetary exploration rover (Curiosity/Perseverance family), scale ~1 block = 20cm
// Footprint: 25 long (X) x 19 wide (Z) incl. solar deck; centre (32,32); pad top Y=10, wheels rest Y=11
// Height: wheels Y11-17 | chassis Y17-20 | solar deck Y21 | mast head Y29-31
//
// SIDE SILHOUETTE (X horizontal, front = -X):
// ___________________ mast + camera head
// ____|########## ####|___ deck Y21
// | arm |##CHASSIS##| RTG | chassis Y17-20
// \ (O) (O) (O) wheels r=3, x = cx-8, cx, cx+8
// v ~~~~~~~~~~~~~~~~~~~~~~ ground Y10
//
// FRONT SILHOUETTE (Z horizontal):
// ==========DECK==========
// | white chassis |
// (O) (O) wheels at z = cz-6 / cz+6
//
// MATERIALS PLAN:
// chassis : noisePalette white_concrete(52)+light_gray_concrete(30)+iron_block(18)
// — WHY: pale body reads bright against red ground, subtle panel noise
// foil : gold_block + yellow_terracotta band, PROTRUDING 1 block on both flanks
// — WHY: thermal-blanket accent + real facade relief on a small volume
// wheels : black_concrete/polished_blackstone alternating tread (cleats) + iron hub
// — WHY: dark value anchors the silhouette, checker = grousers
// deck : blue_concrete field + light_blue cell lines + gray_concrete frame
// mast/arm: light_gray_concrete + iron_block, drawLine struts (rocker-bogie)
// ground : patches red_sand(40)+terracotta(24)+red_terracotta(21)+granite(15), boulders + wheel tracks
// Rooms: N/A (vehicle — no interior)
// === END PLAN ===
function ck(s){ try { print(s); } catch(e) {} }
var cx = 32, cz = 32;
var PADY = 10; // top solid ground under the rover
var GRD = PADY + 1; // first air block
var body = noisePalette([
{block:"white_concrete", weight:52},
{block:"light_gray_concrete", weight:30},
{block:"iron_block", weight:18}
], {seed:41, freq:0.16});
var i, k, t, x, y, z, dx, dy, dz;
// === 1. MARS TERRAIN ===
ck("TERRAIN");
var land = blob(cx, cz, 30, {irregularity:0.32, seed:57});
var h = hills({base: PADY - 2, amp: 4, scale: 0.045, seed: 19});
var pad = flatten(h, {x0: cx-16, z0: cz-12, x1: cx+16, z1: cz+12}, PADY, 7);
var gmat = patches([
{block:"red_sand", w:40},
{block:"terracotta", w:24},
{block:"red_terracotta", w:21},
{block:"granite", w:15}
], 0.05, 33);
surface(land, pad, gmat, {sub:"terracotta", deep:"stone", depth:4});
// scattered boulders + a small outcrop
var rocks = [[-22,-14,3],[19,-18,2],[-17,17,2],[24,9,3],[-25,4,2],[12,22,2],[-8,-24,2],[22,-3,2]];
for (i = 0; i < rocks.length; i++) {
makeSphere(cx+rocks[i][0], PADY + rocks[i][2] - 1, cz+rocks[i][1],
noisePalette([{block:"granite",weight:45},{block:"stone",weight:30},{block:"cobblestone",weight:25}], {seed:7}),
rocks[i][2], true);
}
for (i = 0; i < 6; i++) {
makeSphere(cx - 26 + i, PADY + 2 + (i % 3), cz - 26 + (i % 2) * 2, "granite", 3, true);
}
// wheel tracks trailing behind (+X)
for (t = 12; t < 30; t++) {
for (k = -1; k <= 1; k += 2) {
pb(cx + t, PADY, cz + k*6, "brown_terracotta");
if (t % 2 === 0) {
pb(cx + t, PADY, cz + k*6 - 1, "coarse_dirt");
pb(cx + t, PADY, cz + k*6 + 1, "coarse_dirt");
}
}
}
// === 2. WHEELS (6, rocker-bogie layout) ===
ck("WHEELS");
function wheel(wx, wy, wz, r, halfW) {
var a, bq, d2, id, c;
for (a = -r; a <= r; a++) {
for (bq = -r; bq <= r; bq++) {
d2 = a*a + bq*bq;
if (d2 <= r*r + r) {
if (d2 >= (r-1)*(r-1)) {
id = (Math.abs(a + bq) % 2 === 0) ? "black_concrete" : "polished_blackstone";
} else if (d2 <= 2) {
id = "iron_block";
} else {
id = "gray_concrete";
}
for (c = -halfW; c <= halfW; c++) {
pb(wx + a, wy + bq, wz + c, id);
}
}
}
}
}
var wxs = [cx-8, cx, cx+8];
var wy = GRD + 3; // centre of a r=3 wheel resting on the pad
for (i = 0; i < 3; i++) {
wheel(wxs[i], wy, cz-6, 3, 1);
wheel(wxs[i], wy, cz+6, 3, 1);
}
// === 3. ROCKER-BOGIE SUSPENSION STRUTS ===
ck("SUSPENSION");
for (k = -1; k <= 1; k += 2) {
z = cz + k*6;
drawLine(cx-8, wy, z, cx-3, GRD+7, z, "light_gray_concrete", 1); // front rocker
drawLine(cx-3, GRD+7, z, cx+2, GRD+6, z, "light_gray_concrete", 1);
drawLine(cx, wy, z, cx+2, GRD+6, z, "polished_andesite", 1); // bogie
drawLine(cx+8, wy, z, cx+4, GRD+7, z, "polished_andesite", 1); // rear rocker
drawLine(cx+4, GRD+7, z, cx+2, GRD+6, z, "light_gray_concrete", 1);
drawLine(cx+2, GRD+6, z, cx+2, GRD+7, cz + k*4, "iron_block", 1); // pivot into the chassis
drawLine(cx-3, GRD+7, z, cx-3, GRD+7, cz + k*4, "iron_block", 1);
}
// === 4. CHASSIS (warm electronics box) ===
ck("CHASSIS");
var bTop = GRD + 9; // 20
var bBot = GRD + 6; // 17
fill(cx-7, bBot, cz-4, cx+7, bTop, cz+4, body);
// chamfered upper edges
for (t = cx-7; t <= cx+7; t++) {
roofStair(t, bTop, cz-5, "smooth_quartz_stairs", "north");
roofStair(t, bTop, cz+5, "smooth_quartz_stairs", "south");
}
// protruding gold thermal-foil band on both flanks + nose plate
fill(cx-6, bBot+1, cz-5, cx+3, bBot+2, cz-5, "gold_block");
fill(cx-6, bBot+1, cz+5, cx+3, bBot+2, cz+5, "gold_block");
fill(cx-6, bBot, cz-5, cx+3, bBot, cz-5, "yellow_terracotta");
fill(cx-6, bBot, cz+5, cx+3, bBot, cz+5, "yellow_terracotta");
fill(cx-8, bBot+1, cz-3, cx-8, bBot+2, cz+3, "light_gray_concrete");
// greebles / instrument boxes
pb(cx-8, bBot+3, cz-2, "iron_trapdoor[facing=west,half=top]");
pb(cx-8, bBot+3, cz+2, "iron_trapdoor[facing=west,half=top]");
pb(cx-5, bTop+1, cz-3, "light_gray_concrete");
pb(cx-5, bTop+1, cz+3, "light_gray_concrete");
pb(cx-9, bBot+2, cz, "observer[facing=west]");
for (t = -3; t <= 3; t += 3) {
pb(cx+t, bBot+1, cz-6, "stone_button[face=wall,facing=north]");
pb(cx+t, bBot+1, cz+6, "stone_button[face=wall,facing=south]");
}
// RTG power unit at the rear with cooling fins
fill(cx+8, bBot+1, cz-2, cx+10, bBot+3, cz+2, "gray_concrete");
for (t = -2; t <= 2; t++) {
pb(cx+11, bBot+2, cz+t, "iron_bars");
pb(cx+8, bBot+4, cz+t, "iron_bars");
}
pb(cx+11, bBot+3, cz, "redstone_lamp");
// === 5. SOLAR / EQUIPMENT DECK ===
ck("DECK");
var deckY = bTop + 1; // 21
for (x = cx-12; x <= cx+12; x++) {
for (z = cz-9; z <= cz+9; z++) {
dx = Math.abs(x - cx); dz = Math.abs(z - cz);
if (dx + dz <= 19 && !(dx > 7 && dz > 6)) {
if (dx === 12 || dz === 9 || dx === 0) {
pb(x, deckY, z, "gray_concrete");
} else if ((dx % 3) === 0) {
pb(x, deckY, z, "light_blue_concrete");
} else {
pb(x, deckY, z, ((x + z) % 7 === 0) ? "blue_stained_glass" : "blue_concrete");
}
}
}
}
// deck supports — clean solid pylons + diagonal braces (no dangling bars)
for (k = -1; k <= 1; k += 2) {
fill(cx-10, bBot+2, cz + k*7, cx-10, deckY-1, cz + k*7, "light_gray_concrete");
fill(cx+10, bBot+2, cz + k*7, cx+10, deckY-1, cz + k*7, "light_gray_concrete");
drawLine(cx-10, bBot+2, cz + k*7, cx-6, bBot+1, cz + k*4, "polished_andesite", 1);
drawLine(cx+10, bBot+2, cz + k*7, cx+6, bBot+1, cz + k*4, "polished_andesite", 1);
fill(cx, bTop+1, cz + k*8, cx, deckY-1, cz + k*8, "light_gray_concrete");
}
// === 6. CAMERA MAST + ANTENNAE ===
ck("MAST");
fill(cx+4, deckY, cz, cx+4, deckY+6, cz, "iron_block");
fill(cx+3, deckY+7, cz-1, cx+5, deckY+8, cz+1, "gray_concrete");
pb(cx+2, deckY+8, cz-1, "black_concrete");
pb(cx+2, deckY+8, cz+1, "black_concrete");
pb(cx+2, deckY+8, cz, "light_gray_concrete");
for (t = -1; t <= 1; t++) {
roofStair(cx+3+t+1, deckY+9, cz, "smooth_quartz_stairs", "west");
}
pb(cx+4, deckY+9, cz-1, "smooth_quartz_slab");
pb(cx+4, deckY+9, cz+1, "smooth_quartz_slab");
// whip antenna
fill(cx+9, deckY, cz-4, cx+9, deckY+4, cz-4, "iron_bars");
pb(cx+9, deckY+5, cz-4, "lightning_rod");
// high-gain dish
fill(cx+8, deckY, cz+4, cx+8, deckY+2, cz+4, "iron_block");
makeCylinder(cx+8, deckY+3, cz+4, "white_concrete", 2, 1, true);
pb(cx+8, deckY+4, cz+4, "light_gray_concrete");
// === 7. ROBOTIC ARM (deployed to the ground) ===
ck("ARM");
drawLine(cx-8, bBot+2, cz+2, cx-13, GRD+4, cz+3, "light_gray_concrete", 2);
drawLine(cx-13, GRD+4, cz+3, cx-16, GRD+1, cz+3, "iron_block", 2);
pb(cx-16, GRD, cz+3, "iron_block");
pb(cx-17, GRD, cz+3, "polished_andesite");
pb(cx-16, GRD-1, cz+3, "lightning_rod[facing=down]");
pb(cx-13, GRD+5, cz+3, "iron_block");
pb(cx-15, GRD+2, cz+4, "stone_button[face=wall,facing=south]");
// scuffed patch of soil where the drill sits
for (t = -2; t <= 2; t++) {
pb(cx-16+t, PADY, cz+3, "coarse_dirt");
pb(cx-16+t, PADY, cz+4, "brown_terracotta");
}
ck("DONE");