// === BUILD PLAN ===
// Subject: colossal chameleon straddling a thick jungle branch. Long axis along Z so the
// READABLE side profile faces +X (the render camera). Head at high Z (+Z), spiral tail at low Z.
// Scale: body z34..z76 (42 long), belly Y21 (branch top Y20), arched back peaks Y37, casque Y41.
// Laterally flattened: half-width max 5 in X vs 8 half-height in Y (the defining chameleon trait).
//
// SIDE SILHOUETTE (Z horizontal ->, Y vertical):
// ____
// ..#. ..###/casq\.. crest = serrated single blocks
// .####. ...####... .####(eye)##~~~~* ~ = tongue, * = dragonfly
// (spiral) ..#############.. ############
// ..##.. ################### ## ## feet clamp the branch
// ============================================== branch (tapering log along Z)
//
// CROSS-SECTION (X horizontal, Y vertical, mid-body): rx=5, ry=8 ellipse, tall+narrow
// .#.
// ##### <- crest ridge
// #######
// #######
// #####
// ### <- belly, sits 1 above the branch
//
// MATERIALS PLAN (the gradient IS the brief: "deep teal-green -> yellow-green -> ochre"):
// skin : gradientPalette belly->back yellow_terracotta/orange_terracotta (ochre, low)
// -> moss_block/green_concrete/lime_terracotta (yellow-green, mid)
// -> warped_planks/dark_prismarine/cyan_terracotta (deep teal, back) {noise:0.25}
// WHY: the value ramp fakes the roundness of a laterally flattened body AND is the species colour.
// bands : every 6 z a darker warped_hyphae/green_concrete flank stripe — chameleon lateral banding
// crest : dark_prismarine + prismarine_wall serration along the spine
// branch: noisePalette jungle_log/stripped_jungle_log/brown_mushroom_block (bark variation)
// ground: jungle floor via surface()/patches() — grass_block/moss_block/podzol, ferns, vines
// eyes : cone turret of green/lime concrete + black_concrete pupil + gold ring
// === END PLAN ===
var CX = 32;
var PI = Math.PI;
// ---------------------------------------------------------------- JUNGLE FLOOR (superpowers)
var hn = hills({ base: 5, amp: 3, scale: 0.06, seed: 19 });
var gh = function (x, z) { var v = hn(x, z); if (v < 2) v = 2; return Math.round(v); };
var land = blob(32, 48, 40, { irregularity: 0.45, seed: 9 });
var soil = patches(['grass_block', 'moss_block', 'podzol', 'coarse_dirt'], 0.06, 4);
surface(land, gh, soil, { sub: 'dirt', deep: 'stone', depth: 4 });
checkpoint('JUNGLE_FLOOR');
// ---------------------------------------------------------------- THE BRANCH + ITS TRUNK
var bark = noisePalette([
{ block: 'jungle_log[axis=z]', weight: 45 },
{ block: 'stripped_jungle_log[axis=z]', weight: 25 },
{ block: 'brown_mushroom_block', weight: 18 },
{ block: 'mossy_cobblestone', weight: 12 }
], { seed: 3, freq: 0.16 });
function disc(cx, cy, z, rx, ry, pat) {
var dx, dy;
for (dx = -rx; dx <= rx; dx++) {
for (dy = -ry; dy <= ry; dy++) {
if ((dx * dx) / (rx * rx) + (dy * dy) / (ry * ry) <= 1.05) pb(cx + dx, cy + dy, z, pat);
}
}
}
var z, r, cy;
for (z = 2; z <= 93; z++) {
r = 5 - Math.floor(z / 26); // tapers toward the tip
cy = 16 - Math.floor(z / 40); // droops slightly
disc(CX, cy, z, r, r, bark);
}
// the trunk that carries the branch, rising out of the jungle floor
var ty;
for (ty = 2; ty <= 20; ty++) {
var tr = 7 - Math.floor((ty - 2) / 6);
var dx2, dz2;
for (dx2 = -tr; dx2 <= tr; dx2++) {
for (dz2 = -tr; dz2 <= tr; dz2++) {
if (dx2 * dx2 + dz2 * dz2 <= tr * tr) pb(CX + dx2, ty, 8 + dz2, noisePalette([{ block: 'jungle_log[axis=y]', weight: 55 }, { block: 'stripped_jungle_log[axis=y]', weight: 25 }, { block: 'mossy_cobblestone', weight: 20 }], { seed: 11, freq: 0.14 })(CX + dx2, ty, 8 + dz2));
}
}
}
// side twigs + foliage + hanging vines
// FIX: the foliage was swallowing the animal. Twigs+leaves now live only at the two ENDS of the
// branch (z<30 and z>84), sit LOWER than the belly line and are smaller, so the silhouette is clean.
var k, fz;
var FZ = [16, 22, 86, 91];
for (k = 0; k < 4; k++) {
fz = FZ[k];
drawLine(CX + 4, 15, fz, CX + 13 - k, 17 + (k % 2), fz + 4, 'jungle_log[axis=x]');
drawLine(CX - 4, 15, fz + 2, CX - 13 + k, 16 + (k % 2), fz + 5, 'jungle_log[axis=x]');
makeSphere(CX + 13 - k, 17 + (k % 2), fz + 4, noisePalette([{ block: 'jungle_leaves[persistent=true]', weight: 70 }, { block: 'oak_leaves[persistent=true]', weight: 30 }], { seed: k, freq: 0.3 }), 3, false);
makeSphere(CX - 13 + k, 16 + (k % 2), fz + 5, noisePalette([{ block: 'jungle_leaves[persistent=true]', weight: 70 }, { block: 'azalea_leaves[persistent=true]', weight: 30 }], { seed: k + 5, freq: 0.3 }), 3, false);
var vy;
for (vy = 1; vy <= 6 + (k % 3) * 2; vy++) {
ps(CX + 5, 11 - vy + 1, fz + 2, 'vine[east=true]');
ps(CX - 5, 11 - vy + 1, fz + 5, 'vine[west=true]');
}
}
// a few hanging vines under the mid branch too (they read as depth without hiding the body)
var mv, mz;
for (mz = 40; mz <= 80; mz += 13) {
for (mv = 1; mv <= 5; mv++) {
ps(CX + 5, 12 - mv, mz, 'vine[east=true]');
ps(CX - 5, 12 - mv, mz + 5, 'vine[west=true]');
}
}
checkpoint('BRANCH');
// ---------------------------------------------------------------- BODY (laterally flattened, arched back)
var skin = gradientPalette(21, 38, [
{ block: 'yellow_terracotta', from: 0 },
{ block: 'orange_terracotta', from: 0.14 },
{ block: 'lime_terracotta', from: 0.3 },
{ block: 'moss_block', from: 0.46 },
{ block: 'green_concrete', from: 0.62 },
{ block: 'warped_planks', from: 0.76 },
{ block: 'dark_prismarine', from: 0.88 }
], { noise: 0.25, seed: 21 });
var bandSkin = noisePalette([
{ block: 'warped_hyphae[axis=y]', weight: 40 },
{ block: 'green_concrete', weight: 35 },
{ block: 'dark_prismarine', weight: 25 }
], { seed: 33, freq: 0.25 });
var bz1 = 34, bz2 = 76;
var t, yTop, yBot, rx, ycen, ryy, isBand;
for (z = bz1; z <= bz2; z++) {
t = (z - bz1) / (bz2 - bz1);
yBot = 21 + Math.round(1.5 * Math.sin(PI * t)); // belly curves a touch above the branch
yTop = 28 + Math.round(9 * Math.sin(PI * Math.pow(t, 0.85))); // high arched back
rx = 2 + Math.round(3.2 * Math.pow(Math.sin(PI * t), 0.55));
ycen = Math.round((yTop + yBot) / 2);
ryy = Math.round((yTop - yBot) / 2);
isBand = ((z - bz1) % 7 === 0 || (z - bz1) % 7 === 1);
disc(CX, ycen, z, rx, ryy, isBand ? bandSkin : skin);
// serrated dorsal crest
if ((z - bz1) % 2 === 0) {
pb(CX, yTop + 1, z, 'dark_prismarine');
if (t > 0.2 && t < 0.85) ps(CX, yTop + 2, z, 'prismarine_wall');
} else {
pb(CX, yTop + 1, z, 'prismarine_slab[type=bottom]');
}
}
checkpoint('BODY');
// ---------------------------------------------------------------- LEGS + ZYGODACTYL FEET
function leg(zA, side, kneeOut) {
var sx = CX + side * 4;
drawLine(sx, 26, zA, CX + side * (4 + kneeOut), 22, zA + 2, 'green_concrete');
drawLine(CX + side * (4 + kneeOut), 22, zA + 2, CX + side * 6, 19, zA - 1, 'moss_block');
// pincer foot: two opposed toe groups clamping the branch
var f;
for (f = 0; f < 3; f++) {
pb(CX + side * (6 - f), 19 - f, zA - 2, 'lime_terracotta');
pb(CX + side * (6 - f), 19 - f, zA, 'lime_terracotta');
pb(CX + side * (5 - f), 17 - f, zA - 1, 'green_concrete');
}
pb(CX + side * 6, 20, zA - 1, 'moss_block');
}
leg(41, 1, 2); leg(41, -1, 2); // hind legs
leg(69, 1, 3); leg(69, -1, 2); // front legs (slight asymmetry on purpose)
checkpoint('LEGS');
// ---------------------------------------------------------------- HEAD + CASQUE + TURRET EYES
var hz;
for (hz = 76; hz <= 88; hz++) {
t = (hz - 76) / 12;
yBot = 23 + Math.round(2 * t);
yTop = 37 - Math.round(9 * t * t) + (hz < 80 ? 2 : 0); // casque sweeps back high, snout low
rx = 4 - Math.round(2.6 * t);
ycen = Math.round((yTop + yBot) / 2);
ryy = Math.round((yTop - yBot) / 2);
disc(CX, ycen, hz, rx < 1 ? 1 : rx, ryy < 1 ? 1 : ryy, skin);
if (hz < 82 && (hz % 2 === 0)) pb(CX, yTop + 1, hz, 'dark_prismarine');
}
// casque back plate (helmet crown) + jaw line
disc(CX, 36, 77, 3, 5, 'dark_prismarine');
disc(CX, 35, 78, 3, 4, 'warped_planks');
var jz;
for (jz = 80; jz <= 88; jz++) {
pb(CX + 2, 24 + Math.floor((jz - 80) / 3), jz, 'orange_terracotta');
pb(CX - 2, 24 + Math.floor((jz - 80) / 3), jz, 'orange_terracotta');
pb(CX, 23 + Math.floor((jz - 80) / 3), jz, 'yellow_terracotta');
}
// turret eyes: cone-shaped swivelling turrets with a gold ring and a black pupil
function turret(side) {
makeSphere(CX + side * 4, 31, 80, 'lime_terracotta', 3, false);
makeSphere(CX + side * 5, 31, 80, 'green_concrete', 2, false);
pb(CX + side * 6, 31, 80, 'gold_block');
pb(CX + side * 7, 31, 80, 'black_concrete');
pb(CX + side * 6, 32, 80, 'yellow_terracotta');
pb(CX + side * 6, 30, 80, 'yellow_terracotta');
pb(CX + side * 6, 31, 79, 'yellow_terracotta');
pb(CX + side * 6, 31, 81, 'yellow_terracotta');
}
turret(1); turret(-1);
checkpoint('HEAD');
// ---------------------------------------------------------------- TONGUE + DRAGONFLY
var a, tx, tz, tr2;
for (a = 0; a <= 100; a++) {
tz = 88 + Math.round(a * 0.062);
tx = CX;
var tyv = 25 + Math.round(2 * Math.sin(a * 0.03));
pb(tx, tyv, tz, a > 88 ? 'pink_concrete' : 'red_concrete');
if (a > 92) { pb(tx + 1, tyv, tz, 'pink_concrete'); pb(tx - 1, tyv, tz, 'pink_concrete'); pb(tx, tyv + 1, tz, 'pink_concrete'); }
}
// dragonfly at the end of the tongue
var dz = 94, dy = 27;
fill(CX, dy, dz - 1, CX, dy, dz + 1, 'cyan_concrete');
pb(CX, dy + 1, dz, 'lime_concrete');
pb(CX + 1, dy + 1, dz, 'light_blue_stained_glass'); pb(CX + 2, dy + 1, dz - 1, 'light_blue_stained_glass');
pb(CX - 1, dy + 1, dz, 'light_blue_stained_glass'); pb(CX - 2, dy + 1, dz - 1, 'light_blue_stained_glass');
pb(CX + 1, dy, dz + 1, 'light_blue_stained_glass'); pb(CX - 1, dy, dz + 1, 'light_blue_stained_glass');
checkpoint('TONGUE');
// ---------------------------------------------------------------- PREHENSILE SPIRAL TAIL
var ang, rad, sy, sz, th, i, j;
for (ang = 0; ang <= 940; ang += 4) {
rad = 9.0 - ang * 0.0088;
if (rad < 0.8) rad = 0.8;
sy = 25 + rad * Math.sin(ang * PI / 180);
sz = 26 - rad * Math.cos(ang * PI / 180);
th = rad > 6 ? 2 : (rad > 3 ? 1 : 0);
for (i = -th; i <= th; i++) {
for (j = -th; j <= th; j++) {
pb(CX + i, Math.round(sy + j), Math.round(sz), skin(CX + i, Math.round(sy + j), Math.round(sz)));
}
}
}
// blend the tail root into the body
for (z = 30; z <= 35; z++) {
t = (z - 30) / 5;
disc(CX, 26 + Math.round(2 * t), z, 1 + Math.round(2 * t), 2 + Math.round(4 * t), skin);
}
checkpoint('TAIL');
// ---------------------------------------------------------------- SCENERY / GROUND DETAIL
var gx, gz;
for (gx = 6; gx <= 58; gx += 6) {
for (gz = 14; gz <= 90; gz += 11) {
if (gx > 22 && gx < 44 && gz < 20) continue;
var gy = gh(gx, gz) + 1;
if ((gx + gz) % 3 === 0) pb(gx, gy, gz, 'fern');
else if ((gx + gz) % 3 === 1) { pb(gx, gy, gz, 'large_fern[half=lower]'); pb(gx, gy + 1, gz, 'large_fern[half=upper]'); }
else pb(gx, gy, gz, 'jungle_sapling');
}
}
placeTree(9, gh(9, 22) + 1, 22, 'jungle');
placeTree(55, gh(55, 70) + 1, 70, 'jungle');
placeTree(12, gh(12, 78) + 1, 78, 'jungle');
noisyScatter(4, 2, 10, 60, 8, 92, 'moss_block', 0.16, 61);
checkpoint('SCENERY');