← Nature3D assetfogon/roca-mediana
Roca mediana
Drag to turn it// «Roca mediana» · gpt-6-sol (medium)
// A medium irregular boulder in grey stone with a few cracks and green moss patches on top, about 30 blocks across.
// A chunky, irregular storybook boulder.
const cx = 24, cy = 24;
const stone = ["#929b9b", "#a8b0ad", "#bcc4bd", "#d0d7ca"];
const moss = ["#3f8f48", "#58ae52", "#73c961", "#91dc72"];
for (let x = 6; x <= 42; x++) {
for (let y = 7; y <= 41; y++) {
const dx = x - cx, dy = y - cy;
const angle = Math.atan2(dy, dx);
const ripple = 1
+ 0.065 * Math.sin(5 * angle + 0.5)
+ 0.045 * Math.cos(9 * angle - 0.8);
const d = Math.pow(dx / (17 * ripple), 2)
+ Math.pow(dy / (15.5 * ripple), 2);
if (d >= 1) continue;
const top = Math.floor(
4.5 + 16.5 * Math.sqrt(1 - d)
+ 0.75 * Math.sin(x * 0.62 + y * 0.28)
+ 0.55 * Math.cos(y * 0.77 - x * 0.19)
);
for (let z = 0; z <= top; z++) {
// Pull in the bottom edge slightly, leaving a stable, flat footprint.
if (z < 3 && d > 0.91 + z * 0.025) continue;
const light = z > top - 3 ? 2 : y < 24 ? 1 : 0;
const shade = Math.max(0, Math.min(3,
light + (rand() < 0.105 ? 1 : 0) - (rand() < 0.08 ? 1 : 0)
));
set(x, y, z, stone[shade]);
}
}
}
// Moss follows the crown and spills a little over its edges.
const patches = [
[15, 19, 5.3, 3.5],
[29, 17, 4.5, 3.4],
[25, 31, 5.2, 3.5],
[35, 27, 3.5, 4.0],
[19, 27, 2.7, 2.3]
];
forEach((x, y, z) => {
const exposed = !get(x, y, z + 1) || !get(x, y - 1, z)
|| !get(x - 1, y, z) || !get(x + 1, y, z);
if (!exposed || z < 10) return;
for (const [mx, my, rx, ry] of patches) {
const shape = Math.pow((x - mx) / rx, 2) + Math.pow((y - my) / ry, 2);
const ragged = 0.12 * Math.sin(x * 2.1 + y)
+ 0.10 * Math.cos(y * 2.6 - x);
if (shape < 1 + ragged && rand() > 0.12) {
const topLit = !get(x, y, z + 1);
set(x, y, z, moss[topLit ? (rand() < 0.35 ? 3 : 2)
: (rand() < 0.5 ? 0 : 1)]);
break;
}
}
});
// Narrow, branching cracks on the viewer-facing stone.
forEach((x, y, z, color) => {
if (!color || y > 24 || z < 3 || get(x, y - 1, z)) return;
const leftCrack = z >= 5 && z <= 15 &&
Math.abs(x - (17 + Math.floor((z - 5) / 3) + (z === 10 ? 1 : 0))) < 0.6;
const leftBranch = z >= 8 && z <= 11 &&
Math.abs(x - (14 + (z - 8))) < 0.6;
const rightCrack = z >= 4 && z <= 12 &&
Math.abs(x - (33 - Math.floor((z - 4) / 3))) < 0.6;
if (leftCrack || leftBranch || rightCrack) {
set(x, y, z, "#687775");
}
});import { draw } from "./assets/voxel";
import { rocaMediana } from "./assets/roca-mediana";
// Every frame: standing on (x, y), the centre of its base.
draw(ctx, rocaMediana, x, y, { size: 64, angle: 0, t: performance.now() / 1000 });
// size: its longest side, in px
// angle: turn on the floor, in radians
// t: seconds; if it moves, that animates it# In a terminal, in the game's folder
fogon assets add roca-mediana
# With Fogón's tools (connector)
add_assets({ slug: "<your-game>", ids: ["roca-mediana"] })
# It lands in client/assets/roca-mediana.ts
# https://fogon.page/object/roca-mediana