// === BUILD PLAN ===
// Subject: colossal deep-sea anglerfish (Melanocetus), resting on an abyssal seabed. ORGANIC build.
// Axis: body runs along +Z. Snout/jaws at z=18 (FRONT), tail fin at z=88. Centre-line x=40. Seabed pad Y=6.
// Length ~70, max body height ~26, max width ~26. Head = ~1/3 of the length (correct for an anglerfish).
//
// SIDE SILHOUETTE (X into the page; Y up, Z right):
// (o) <- glowing lure
// /
// | .-'''''-.
// ____| _.-' '-._
// \ / \ | .-' BULBOUS BODY '-._ ___
// \ / \| / '-._ / \ <- caudal fan
// V ^^^^^^^^ upper jaw + needle teeth \| |
// ^^^^^^^^ lower jaw \__/
// ~~~~~~~~~~ seabed (black rock, tube worms) ~~~~~~~~~~
//
// CROSS-SECTION at z=46 (front view, widest): ellipse rx=13 ry=12
// ....######....
// ..##############..
// .##################.
// .##################. dy>0 = BACK/spine (dark) [+Y IS UP — checked]
// ..##############.. dy<0 = BELLY (lighter)
// ....######....
//
// RADIUS PROFILE (z, rx, ry) — interpolated, adjacent slices differ by <=2 so the curve stays smooth:
// 18/6,7 · 22/8,9 · 26/10,10 · 32/12,11 · 40/13,12 · 48/13,12 · 54/11,10 · 60/8,8 · 66/5,6 · 72/3,4 · 78/2,3
// GAPE: the mouth is CARVED after the solid body — halfGape = min((36-z)*0.75, ry-2.5), so the jaws
// diverge toward the front and leave ~2.5 blocks of jaw thickness. Needle teeth on both rims.
// ILLICIUM: dorsal stalk springs from the back at z=40, arcs FORWARD over the snout, lure sphere at (40,~41,20).
//
// MATERIALS PLAN (what / where / WHY):
// body : gradientPalette Y5->Y30 gray_concrete(0) -> deepslate(.28) -> polished_blackstone(.58)
// -> black_concrete(.84), noise .26 — WHY: COUNTERSHADING (pale belly, black back) is what makes a
// fish read as a fish; it is also a value ramp, so the barrel body gains volume instead of a flat blob
// teeth: bone_block + end_rod tips — WHY: the only PALE thing on the model, so the gape reads instantly
// lure : ochre_froglight core + shroomlight shell + end_rod rays — WHY: single warm light source in a
// black-on-black subject; it carries the silhouette
// fins : gray_concrete / polished_blackstone rays — WHY: slightly lighter than the body so they separate
// floor: patches(deepslate/blackstone/tuff/gravel) on hills() relief + sea_lantern & froglight vents
// === END PLAN ===
var CX = 40, padY = 6;
// ---------- radius profile ----------
var PROF = [[18, 6, 7], [22, 8, 9], [26, 10, 10], [32, 12, 11], [40, 13, 12], [48, 13, 12],
[54, 11, 10], [60, 8, 8], [66, 5, 6], [72, 3, 4], [78, 2, 3]];
function lerpProf(z, idx) {
if (z <= PROF[0][0]) return PROF[0][idx];
if (z >= PROF[PROF.length - 1][0]) return PROF[PROF.length - 1][idx];
for (var i = 0; i < PROF.length - 1; i++) {
if (z >= PROF[i][0] && z <= PROF[i + 1][0]) {
var t = (z - PROF[i][0]) / (PROF[i + 1][0] - PROF[i][0]);
return PROF[i][idx] + t * (PROF[i + 1][idx] - PROF[i][idx]);
}
}
return 1;
}
function rxAt(z) { return lerpProf(z, 1); }
function ryAt(z) { return lerpProf(z, 2); }
// body centre-line: belly rests on the pad; the tail curls UP off the floor
function ycAt(z) {
var base = padY + ryAt(z) - 1;
if (z > 62) base += (z - 62) * 0.62;
return base;
}
function halfGape(z) {
if (z > 36 || z < 17) return -1;
var g = (36 - z) * 0.75;
var cap = ryAt(z) - 2.5;
return Math.min(g, cap);
}
var skin = gradientPalette(5, 30, [
{ block: 'gray_concrete', from: 0 },
{ block: 'deepslate', from: 0.28 },
{ block: 'polished_blackstone', from: 0.58 },
{ block: 'black_concrete', from: 0.84 }
], { noise: 0.26, seed: 13 });
// === SEABED (superpowers: blob + hills + flatten pad, flatten's return fed to surface) ===
var land = blob(42, 50, 44, { irregularity: 0.4, seed: 31 });
var relief = hills({ base: 2, amp: 5, scale: 0.035, seed: 19 });
var pad = flatten(relief, { cx: 40, cz: 48, r: 30 }, padY, 12);
var floorMat = patches(['deepslate', 'blackstone', 'tuff', 'gravel', 'deepslate'], 0.05, 23);
surface(land, pad, floorMat, { sub: 'deepslate', deep: 'stone', depth: 4 });
// === BODY (solid ellipse slices; +Y up => dy>0 is the BACK) ===
for (var z = 18; z <= 79; z++) {
var rx = rxAt(z), ry = ryAt(z), yc = ycAt(z);
for (var dx = -Math.ceil(rx); dx <= Math.ceil(rx); dx++) {
for (var dy = -Math.ceil(ry); dy <= Math.ceil(ry); dy++) {
var e = (dx * dx) / (rx * rx) + (dy * dy) / (ry * ry);
if (e > 1.0) continue;
var by = Math.round(yc + dy);
if (by < padY - 2) continue;
pb(CX + dx, by, z, skin(CX + dx, by, z));
}
}
}
// === CARVE THE GAPE ===
for (var mz = 17; mz <= 36; mz++) {
var hg = halfGape(mz);
if (hg <= 0) continue;
var mrx = rxAt(mz), myc = ycAt(mz);
for (var mx = -Math.ceil(mrx); mx <= Math.ceil(mrx); mx++) {
if (Math.abs(mx) > mrx - 1.4) continue;
for (var my = -Math.ceil(hg); my <= Math.ceil(hg); my++) {
if (Math.abs(my) > hg) continue;
pb(CX + mx, Math.round(myc + my), mz, 'air');
}
}
}
// dark red mouth lining on the palate + tongue
for (var lz = 20; lz <= 35; lz++) {
var lhg = halfGape(lz); if (lhg <= 0) continue;
var lrx = rxAt(lz), lyc = ycAt(lz);
for (var lx = -Math.floor(lrx - 1.4); lx <= Math.floor(lrx - 1.4); lx++) {
pb(CX + lx, Math.round(lyc - lhg), lz, 'netherrack');
pb(CX + lx, Math.round(lyc + lhg), lz, 'crimson_nylium');
}
}
// === NEEDLE TEETH (the pale thing that makes the gape read) ===
var toothZ = [20, 23, 26, 29, 32, 34];
for (var ti = 0; ti < toothZ.length; ti++) {
var tz = toothZ[ti];
var thg = halfGape(tz); if (thg <= 1) continue;
var trx = rxAt(tz), tyc = ycAt(tz);
var len = Math.max(2, Math.round(thg * 0.55));
for (var tx = -Math.floor(trx - 2); tx <= Math.floor(trx - 2); tx += 2) {
var upY = Math.round(tyc + thg) - 1;
var loY = Math.round(tyc - thg) + 1;
var k;
for (k = 0; k < len; k++) {
pb(CX + tx, upY - k, tz, 'bone_block[axis=y]');
pb(CX + tx, loY + k, tz, 'bone_block[axis=y]');
}
if (len >= 3) {
ps(CX + tx, upY - len, tz, 'end_rod[facing=down]');
ps(CX + tx, loY + len, tz, 'end_rod[facing=up]');
}
}
}
// === EYES (small, deep-set, on the head flanks) ===
var eyeZ = 37, eyeRx = rxAt(eyeZ), eyeYc = ycAt(eyeZ);
for (var side = -1; side <= 1; side += 2) {
var ex = CX + side * Math.round(eyeRx - 0.5);
fill(ex, Math.round(eyeYc + 4), eyeZ, ex, Math.round(eyeYc + 5), eyeZ + 1, 'black_concrete');
pb(ex, Math.round(eyeYc + 5), eyeZ, 'sea_lantern');
pb(ex, Math.round(eyeYc + 6), eyeZ, 'polished_blackstone');
}
// gill slit relief on both flanks
for (var gz = 41; gz <= 43; gz++) {
for (var gy = -5; gy <= 4; gy++) {
var grx = rxAt(gz), gyc = ycAt(gz);
var gx1 = CX - Math.round(grx - 0.4), gx2 = CX + Math.round(grx - 0.4);
if ((gz + gy) % 2 === 0) { pb(gx1, Math.round(gyc + gy), gz, 'basalt[axis=y]'); pb(gx2, Math.round(gyc + gy), gz, 'basalt[axis=y]'); }
}
}
// === ILLICIUM: dorsal stalk arcing FORWARD over the snout + bioluminescent lure ===
var stalkBaseZ = 41;
var stalkBaseY = Math.round(ycAt(stalkBaseZ) + ryAt(stalkBaseZ)) - 1;
var lureX = CX, lureY = 0, lureZ = 0;
for (var s = 0; s <= 40; s++) {
var t = s / 40;
var sy = stalkBaseY + Math.round(14 * Math.sin(t * Math.PI * 0.62));
var sz = Math.round(stalkBaseZ - 21 * t);
pb(CX, sy, sz, t < 0.15 ? 'polished_blackstone' : 'blackstone');
pb(CX, sy - 1, sz, 'polished_blackstone');
if (t < 0.3) { pb(CX - 1, sy, sz, 'polished_blackstone'); pb(CX + 1, sy, sz, 'polished_blackstone'); }
lureY = sy; lureZ = sz;
}
// the lure itself — hung DIRECTLY off the stalk tip so nothing floats
var lureCY = lureY - 4;
var lz2;
for (lz2 = lureY; lz2 >= lureCY + 2; lz2--) { pb(lureX, lz2, lureZ, 'blackstone'); } // short pendant neck
makeSphere(lureX, lureCY, lureZ, 'shroomlight', 3, true);
makeSphere(lureX, lureCY, lureZ, 'ochre_froglight[axis=y]', 1, true);
pb(lureX, lureCY + 3, lureZ, 'shroomlight'); // guarantee the sphere touches the neck
pb(lureX, lureCY + 2, lureZ, 'shroomlight');
// esca filaments, each ATTACHED to the lure body
ps(lureX, lureCY - 4, lureZ, 'end_rod[facing=down]');
ps(lureX - 4, lureCY, lureZ, 'end_rod[facing=west]');
ps(lureX + 4, lureCY, lureZ, 'end_rod[facing=east]');
ps(lureX, lureCY, lureZ - 4, 'end_rod[facing=north]');
pb(lureX - 2, lureCY - 3, lureZ + 1, 'shroomlight');
pb(lureX + 2, lureCY - 3, lureZ - 1, 'shroomlight');
// === FINS ===
// pectoral fins — small and stubby, swept back, low on the flanks
for (var pside = -1; pside <= 1; pside += 2) {
for (var fz = 0; fz < 7; fz++) {
var span = 7 - fz;
for (var fo = 1; fo <= span; fo++) {
var fzz = 50 + fz;
var fx = CX + pside * (Math.round(rxAt(fzz)) - 1 + fo);
var fy = Math.round(ycAt(fzz)) - 4 + Math.round(fz * 0.4);
pb(fx, fy, fzz, fo % 2 === 0 ? 'gray_concrete' : 'polished_blackstone');
}
}
}
// dorsal ridge fin along the back
for (var dz2 = 52; dz2 <= 66; dz2++) {
var dtop = Math.round(ycAt(dz2) + ryAt(dz2));
var dh = Math.max(1, Math.round((66 - dz2) * 0.35) + 1);
fill(CX, dtop, dz2, CX, dtop + dh, dz2, 'polished_blackstone');
if (dz2 % 3 === 0) pb(CX, dtop + dh, dz2, 'gray_concrete');
}
// anal fin under the tail
for (var az = 62; az <= 72; az++) {
var abot = Math.round(ycAt(az) - ryAt(az));
var ah = Math.max(1, Math.round((72 - az) * 0.3) + 1);
fill(CX, abot - ah, az, CX, abot - 1, az, 'polished_blackstone');
}
// caudal (tail) fan — vertical, rays with a notched trailing edge
for (var cz2 = 78; cz2 <= 89; cz2++) {
var prog = (cz2 - 78) / 11;
var hh = Math.round(4 + prog * 9);
var notch = Math.round(Math.abs(Math.sin(prog * Math.PI)) * 2);
var cyc = Math.round(ycAt(78) + prog * 3);
for (var cy = -hh; cy <= hh; cy++) {
if (Math.abs(cy) < notch && cz2 > 85) continue;
var thick = (Math.abs(cy) < 3) ? 1 : 0;
var mat = (Math.abs(cy) % 3 === 0) ? 'gray_concrete' : 'polished_blackstone';
pb(CX, cyc + cy, cz2, mat);
if (thick === 1) { pb(CX - 1, cyc + cy, cz2, mat); pb(CX + 1, cyc + cy, cz2, mat); }
}
}
// skin texture: scattered basalt "warts" on the back (anglerfish are lumpy)
for (var wz = 38; wz <= 70; wz += 1) {
for (var wa = 0; wa < 3; wa++) {
var hsh = (wz * 37 + wa * 91) % 11;
if (hsh > 3) continue;
var wrx = rxAt(wz), wyc = ycAt(wz), wry = ryAt(wz);
var wang = ((wz * 53 + wa * 29) % 180) * Math.PI / 180;
var wx2 = CX + Math.round(wrx * Math.cos(wang));
var wy2 = Math.round(wyc + wry * Math.sin(wang) * 0.95);
pb(wx2, wy2, wz, 'basalt[axis=y]');
}
}
// extra flank relief: lateral line + mottling so the sides are not one flat black field
for (var mz2 = 38; mz2 <= 74; mz2++) {
var mrx2 = rxAt(mz2), myc2 = ycAt(mz2);
var lgx = CX - Math.round(mrx2 - 0.3), rgx = CX + Math.round(mrx2 - 0.3);
var ly2 = Math.round(myc2 + Math.sin(mz2 * 0.35) * 2);
pb(lgx, ly2, mz2, 'gray_concrete');
pb(rgx, ly2, mz2, 'gray_concrete');
if (mz2 % 4 === 0) { pb(lgx, ly2 - 3, mz2, 'deepslate'); pb(rgx, ly2 - 3, mz2, 'deepslate'); }
if (mz2 % 5 === 0) { pb(lgx, ly2 + 4, mz2, 'polished_blackstone'); pb(rgx, ly2 + 4, mz2, 'polished_blackstone'); }
}
// === SEABED DRESSING: black rock, glowing tube worms, vents ===
function rock(rx2, rz2, rr) {
makeSphere(rx2, padY - 1, rz2, noisePalette([{ block: 'blackstone', weight: 45 }, { block: 'deepslate', weight: 35 }, { block: 'basalt', weight: 20 }], { seed: rx2 }), rr, true);
}
rock(14, 30, 5); rock(66, 34, 4); rock(20, 74, 5); rock(64, 76, 6); rock(10, 55, 4); rock(70, 58, 4);
function tubeWorm(tx2, tz2, hgt, capId) {
var i2; for (i2 = 0; i2 < hgt; i2++) pb(tx2, padY + 1 + i2, tz2, i2 % 2 === 0 ? 'bone_block[axis=y]' : 'white_terracotta');
pb(tx2, padY + 1 + hgt, tz2, capId);
}
var wormSpots = [[18, 40, 5], [22, 36, 3], [15, 45, 4], [62, 44, 5], [66, 48, 3], [58, 30, 4],
[26, 82, 4], [54, 84, 5], [30, 20, 3], [50, 18, 4], [12, 62, 4], [68, 66, 3]];
for (var wi2 = 0; wi2 < wormSpots.length; wi2++) {
tubeWorm(wormSpots[wi2][0], wormSpots[wi2][1], wormSpots[wi2][2], wi2 % 3 === 0 ? 'shroomlight' : (wi2 % 3 === 1 ? 'red_terracotta' : 'ochre_froglight[axis=y]'));
}
// glowing vents / bioluminescent patches on the floor
for (var vx = 8; vx <= 72; vx++) {
for (var vz = 12; vz <= 88; vz++) {
var vh = (vx * 41 + vz * 97) % 173;
if (vh > 2) continue;
if (vx > 24 && vx < 56 && vz > 16 && vz < 82) continue;
pb(vx, padY + 1, vz, vh === 0 ? 'sea_lantern' : (vh === 1 ? 'sea_pickle[pickles=4,waterlogged=false]' : 'verdant_froglight[axis=y]'));
}
}
// scattered bone / shell litter
for (var bx2 = 10; bx2 <= 70; bx2 += 7) {
for (var bz2 = 16; bz2 <= 86; bz2 += 9) {
if ((bx2 + bz2) % 3 !== 0) continue;
if (bx2 > 24 && bx2 < 56 && bz2 > 16 && bz2 < 82) continue;
ps(bx2, padY + 1, bz2, 'bone_block[axis=x]');
}
}