← Nature3D assetfogon/hormiguero
Hormiguero
Drag to turn it// «Hormiguero» · gpt-6-sol (medium)
// An anthill: a cone-shaped mound of brown dirt with a dark hole on top and a few tiny black ants on the side.
const cx = 24, cy = 24;
const dirt = ["#8f552f", "#a96535", "#bc7940", "#cc8b4a"];
const darkDirt = "#63391f";
// A broad, gently uneven cone with a chunky storybook silhouette.
for (let z = 0; z <= 28; z++) {
const baseRadius = 19.3 - 0.55 * z;
for (let x = 4; x <= 44; x++) {
for (let y = 4; y <= 44; y++) {
const dx = x - cx, dy = y - cy;
const angle = Math.atan2(dy, dx);
const uneven = 0.42 * Math.sin(angle * 7 + z * 0.19)
+ 0.27 * Math.sin(angle * 11 - z * 0.13);
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance > baseRadius + uneven) continue;
// Leave a deep opening at the summit.
if (z >= 21 && distance < 2.8) continue;
const n = rand();
let color = z < 4 ? dirt[n < 0.38 ? 0 : 1]
: n < 0.13 ? dirt[0]
: n < 0.57 ? dirt[1]
: n < 0.88 ? dirt[2] : dirt[3];
if (z > 20 && n > 0.32) color = dirt[3];
set(x, y, z, color);
}
}
}
// Dark, recessed interior and a sunlit lip.
for (let x = 19; x <= 29; x++) {
for (let y = 19; y <= 29; y++) {
const d = Math.hypot(x - cx, y - cy);
if (d < 2.8) {
set(x, y, 19, "#34241d");
set(x, y, 20, d < 1.9 ? "#241d1b" : darkDirt);
if (d > 2.1) set(x, y, 21, "#51301f");
} else if (d < 4.5) {
for (let z = 26; z <= 28; z++) {
if (get(x, y, z) && !get(x, y, z + 1))
set(x, y, z, rand() < 0.55 ? "#dc9b54" : "#c78344");
}
}
}
}
// A few pale grains and little earthen pebbles on the visible slope.
for (let i = 0; i < 65; i++) {
const x = 8 + Math.floor(rand() * 33);
const z = 2 + Math.floor(rand() * 19);
for (let y = 5; y <= 24; y++) {
if (get(x, y, z)) {
if (rand() < 0.68) set(x, y - 1, z, rand() < 0.5 ? "#d99550" : "#76502e");
break;
}
}
}
// Tiny grass shoots around the foot of the mound.
for (const [x, y] of [
[6, 23], [10, 12], [16, 7], [34, 8], [41, 19],
[40, 34], [30, 42], [14, 39], [8, 32]
]) {
set(x, y, 0, "#509a43");
set(x, y, 1, "#60b64e");
set(x, y, 2, "#82cb60");
set(x - 1, y, 1, "#77bf57");
set(x + 1, y, 1, "#4da047");
}
// Put each ant just in front of the mound's visible surface.
function frontY(x, z) {
for (let y = 4; y <= 24; y++) if (get(x, y, z)) return y - 1;
return 12;
}
function ant(x, z) {
for (let dx = -2; dx <= 2; dx++) {
const ax = x + dx;
const y = frontY(ax, z);
set(ax, y, z, dx === -2 || dx === 2 ? "#302b27" : "#1e2425");
if (dx === -1 || dx === 1) set(ax, y - 1, z, "#252a29");
if (dx === -2 || dx === 0 || dx === 2)
set(ax, frontY(ax, z - 1) - 1, z - 1, "#38312b");
}
// Two bent antennae above the head.
for (const ax of [x + 1, x + 2]) {
set(ax, frontY(ax, z + 1) - 1, z + 1, "#252a29");
}
set(x + 2, frontY(x + 2, z + 2) - 1, z + 2, "#252a29");
}
ant(14, 7);
ant(30, 11);
ant(21, 16);
ant(35, 5);import { draw } from "./assets/voxel";
import { hormiguero } from "./assets/hormiguero";
// Every frame: standing on (x, y), the centre of its base.
draw(ctx, hormiguero, 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 hormiguero
# With Fogón's tools (connector)
add_assets({ slug: "<your-game>", ids: ["hormiguero"] })
# It lands in client/assets/hormiguero.ts
# https://fogon.page/object/hormiguero