← Nature3D assetfogon/cascada
Cascada
Drag to turn it// «Cascada» · gpt-6-sol (medium)
// A small waterfall: a tall stack of grey stone ledges at the back with a band of bright blue and white water pouring down the front into a small round pool at the bottom ringed with rocks.
const stone = ["#69747a", "#879299", "#aab4b5", "#cbd2ce"];
const moss = ["#368e58", "#53ad60", "#80c96b"];
// Chunky cliff rising behind the pool.
box(11, 31, 0, 37, 40, 10, stone[0]);
box(13, 33, 9, 36, 41, 21, stone[1]);
box(15, 34, 20, 34, 41, 32, stone[1]);
// Rounded shoulders and projecting ledges.
ellipsoid(13, 35, 8, 5, 6, 7, stone[1]);
ellipsoid(36, 36, 7, 5, 5, 6, stone[0]);
ellipsoid(15, 36, 19, 4, 5, 5, stone[1]);
ellipsoid(34, 37, 19, 4, 4, 5, stone[0]);
box(10, 29, 10, 19, 38, 11, stone[2]);
box(29, 29, 10, 39, 39, 11, stone[2]);
box(12, 31, 21, 20, 39, 22, stone[2]);
box(28, 31, 21, 37, 39, 22, stone[2]);
box(14, 32, 33, 35, 41, 34, stone[2]);
// Sunlit stone caps and scattered moss, kept away from the watercourse.
for (const [x0, x1, y0, y1, z] of [
[10, 18, 29, 38, 12], [30, 39, 29, 39, 12],
[12, 19, 31, 39, 23], [29, 37, 31, 39, 23],
[14, 19, 33, 41, 35], [30, 35, 33, 41, 35]
]) {
for (let x = x0; x <= x1; x++)
for (let y = y0; y <= y1; y++)
if (rand() < 0.47) set(x, y, z, rand() < 0.27 ? moss[1] : stone[3]);
}
for (let i = 0; i < 95; i++) {
const x = 11 + Math.floor(rand() * 29);
const z = 3 + Math.floor(rand() * 28);
if (x > 19 && x < 30) continue;
const y = z < 11 ? 30 : z < 22 ? 32 : 33;
if (get(x, y, z)) set(x, y - 1, z, moss[Math.floor(rand() * 3)]);
}
// Shallow round basin and its uneven ring of individual boulders.
ellipsoid(24, 19, 0, 18, 15, 2, stone[0]);
for (let i = 0; i < 38; i++) {
const a = i * Math.PI * 2 / 38;
const wobble = (rand() - 0.5) * 1.3;
const x = 24 + Math.cos(a) * (17.5 + wobble);
const y = 19 + Math.sin(a) * (14.3 + wobble);
const r = 1.6 + rand() * 0.9;
ellipsoid(x, y, 1, r + 0.4, r, 1.5 + rand(), stone[i % 4 === 0 ? 2 : 1]);
if (rand() < 0.3) set(x, y, 3, moss[1]);
}
// A few cheerful flowers tucked between the front rocks.
for (const [x, y, flower] of [
[9, 13, "#ff87ab"], [15, 5, "#ffdc61"],
[33, 5, "#ff87ab"], [40, 14, "#ffdc61"]
]) {
set(x, y, 1, moss[0]);
set(x, y, 2, moss[1]);
set(x, y, 3, flower);
}
// The entire stream and pool surface share one flowing color animation.
part("water", [24, 25, 2]);
ellipsoid(24, 19, 1, 16, 12, 1, "#38b7eb");
ellipsoid(24, 19, 2, 14, 10, 0, "#65d4f4");
// Three offset drops make the water tumble over the ledges.
for (let z = 4; z <= 34; z++) {
const y = z <= 11 ? 29 : z <= 22 ? 31 : 32;
const halfWidth = z < 7 ? 6 : 5;
for (let x = 24 - halfWidth; x <= 24 + halfWidth; x++) {
const edge = Math.abs(x - 24) >= halfWidth - 1;
box(x, y, z, x, y + 1, z,
edge || (x + z) % 9 === 0 ? "#a2eeff" : "#28baf1");
if ((x * 3 + z) % 11 === 0) set(x, y - 1, z, "#efffff");
}
}
box(19, 30, 33, 29, 35, 34, "#55cafa");
box(18, 28, 22, 30, 32, 22, "#75dcfa");
box(18, 27, 11, 30, 30, 11, "#72d9f8");
// Splashing white foam at the foot and along the pool.
ellipsoid(24, 29, 3, 8, 4, 1, "#d9fbff");
for (let i = 0; i < 42; i++) {
const x = 11 + Math.floor(rand() * 27);
const y = 9 + Math.floor(rand() * 20);
if (get(x, y, 2)) {
set(x, y, 2, rand() < 0.55 ? "#e6fcff" : "#93e7fa");
if (rand() < 0.35) set(x + 1, y, 2, "#a8effb");
}
}
animate("water", {
type: "colors",
palette: ["#23b5ed", "#4dccf5", "#86e1fa", "#e7fcff"],
pattern: "wave",
glow: 0.2
});
part("body", [24, 24, 0]);import { draw } from "./assets/voxel";
import { cascada } from "./assets/cascada";
// Every frame: standing on (x, y), the centre of its base.
draw(ctx, cascada, 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 cascada
# With Fogón's tools (connector)
add_assets({ slug: "<your-game>", ids: ["cascada"] })
# It lands in client/assets/cascada.ts
# https://fogon.page/object/cascada