← Nature3D assetfogon/pila-de-lena
Pila de leña
Drag to turn it// «Pila de leña» · gpt-6-sol (medium)
// A neat stack of firewood logs: cut log cylinders piled in a pyramid shape, ends showing light rings, with a small axe stuck in a chopping block beside it.
// Firewood pile: four logs at the bottom, tapering to one at the top.
const rows = [
{ z: 4, xs: [7, 16, 25, 34] },
{ z: 10, xs: [11, 20, 29] },
{ z: 16, xs: [16, 25] },
{ z: 22, xs: [20] }
];
function drawLog(cx, cz) {
const radius = 4.3;
for (let y = 14; y <= 39; y++) {
for (let x = cx - 4; x <= cx + 4; x++) {
for (let z = cz - 4; z <= cz + 4; z++) {
const d = Math.hypot(x - cx, z - cz);
if (d > radius) continue;
const end = y === 14 || y === 39;
let color;
if (end && d < 3.55) {
// Pale cut wood with bold, uneven growth rings.
if (d < 0.9) color = "#f9df9e";
else if (d < 1.65) color = "#d89955";
else if (d < 2.25) color = "#f7d28b";
else if (d < 2.85) color = "#c88546";
else color = "#f3c77f";
if (rand() < 0.09) color = "#ffdfa0";
if (y === 39 && rand() < 0.32) color = "#d8aa70";
} else {
const upper = z > cz + 1;
const groove = ((y + 2 * x) % 9 === 0 && d > 2.7) ||
((y + z) % 13 === 0 && d > 3.2);
color = groove ? "#754024"
: upper ? (rand() < 0.26 ? "#bf7b40" : "#aa6230")
: z < cz - 1 ? (rand() < 0.18 ? "#754024" : "#8d4c28")
: (rand() < 0.22 ? "#b36d36" : "#98552b");
if (end) color = "#754024"; // Bark rim around each cut end.
}
set(x, y, z, color);
}
}
}
// Tiny radial checks make the cut faces recognizable from a distance.
set(cx, 14, cz, "#fff0b7");
set(cx + 2, 14, cz, "#a96b3d");
set(cx - 1, 14, cz + 2, "#b87943");
}
for (const row of rows) {
for (const x of row.xs) drawLog(x, row.z);
}
// A short chopping stump beside the front of the pile.
for (let z = 0; z <= 9; z++) {
for (let x = 35; x <= 45; x++) {
for (let y = 2; y <= 12; y++) {
const d = Math.hypot(x - 40, y - 7);
if (d > 5.1) continue;
let color;
if (z === 9) {
color = d < 1.2 ? "#f7d995"
: d < 2.3 ? "#c7894c"
: d < 3.0 ? "#efd092"
: d < 3.9 ? "#bd7b40"
: "#f1c985";
if (d > 4.5) color = "#85502b";
} else {
const groove = (x + 3 * y) % 7 === 0;
color = groove ? "#784322"
: z > 6 ? "#ad6b36"
: z < 2 ? "#824822"
: "#98572c";
if (rand() < 0.08) color = "#bd7840";
}
set(x, y, z, color);
}
}
}
// A few darker splits and a bright nick on its chopping surface.
line(37, 6, 9, 39, 7, 9, 0, "#a96a39");
line(42, 8, 9, 44, 9, 9, 0, "#ad7140");
set(41, 5, 9, "#ffe2a1");
// Axe handle, buried in the stump and leaning slightly left.
line(41, 7, 8, 39, 7, 23, 0.85, "#95572d");
line(40, 6, 12, 39, 6, 21, 0, "#c88749");
set(39, 7, 24, "#653b28");
// Broad, cartoon-style steel axe head. Its thin left edge is the blade.
for (let x = 35; x <= 40; x++) {
for (let z = 19; z <= 25; z++) {
const inBlade =
(x === 35 && z >= 21 && z <= 23) ||
(x === 36 && z >= 20 && z <= 24) ||
(x >= 37 && x <= 38 && z >= 19 && z <= 25) ||
(x >= 39 && z >= 20 && z <= 24);
if (!inBlade) continue;
for (let y = 6; y <= 8; y++) {
const color = x === 35 ? "#d8f0ed"
: x === 36 ? "#bedbdc"
: z >= 23 ? "#aec8ca"
: y === 6 ? "#a2babd"
: "#81999e";
set(x, y, z, color);
}
}
}
box(38, 5, 21, 40, 5, 23, "#d3e5df");
box(39, 8, 21, 40, 8, 23, "#607a81");
// Small cheerful grass tufts, kept clear of the cut log faces.
for (const [x, y] of [[6, 10], [12, 11], [30, 10], [45, 16]]) {
set(x, y, 0, "#4f9e42");
set(x, y, 1, "#68bd4b");
set(x - 1, y, 0, "#80ca55");
set(x + 1, y, 0, "#72ba49");
}import { draw } from "./assets/voxel";
import { pilaDeLena } from "./assets/pila-de-lena";
// Every frame: standing on (x, y), the centre of its base.
draw(ctx, pilaDeLena, 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 pila-de-lena
# With Fogón's tools (connector)
add_assets({ slug: "<your-game>", ids: ["pila-de-lena"] })
# It lands in client/assets/pila-de-lena.ts
# https://fogon.page/object/pila-de-lena