← City3D assetfogon/arbol-de-vereda
Árbol de vereda
Drag to turn it// «Árbol de vereda» · gpt-6-sol (medium)
// A sidewalk tree: a square patch of grey concrete sidewalk tiles with a square earth planter in the middle bordered by a low brick curb, and a leafy plane tree growing from it with a brown trunk and a big rounded green crown with 3 shades of green and a few lighter spots.
// Square concrete sidewalk with subtle tile joints.
box(4, 4, 0, 43, 43, 0, "#929a97");
box(4, 4, 1, 43, 43, 1, "#b1b8b4");
for (let x = 4; x <= 43; x++) {
for (let y = 4; y <= 43; y++) {
const joint = (x - 3) % 10 === 0 || (y - 3) % 10 === 0;
const tile = (Math.floor((x - 4) / 10) + Math.floor((y - 4) / 10)) % 2;
set(x, y, 2, joint ? "#a1aaa6" :
rand() < 0.035 ? "#d9ddda" : tile ? "#c5ccc8" : "#cdd3cf");
}
}
// Earth inside the square planter.
for (let x = 16; x <= 31; x++) {
for (let y = 16; y <= 31; y++) {
set(x, y, 2, rand() < 0.12 ? "#67513a" : "#594734");
if (rand() < 0.07) set(x, y, 3, "#567c3b");
}
}
// Low, warm-red brick curb.
for (let x = 14; x <= 33; x++) {
for (let y = 14; y <= 33; y++) {
if (x >= 16 && x <= 31 && y >= 16 && y <= 31) continue;
for (let z = 3; z <= 5; z++) {
set(x, y, z, z === 5 ? "#c87959" :
rand() < 0.08 ? "#a84f3d" : "#b75e45");
}
}
}
// Little mortar joints on the curb's visible faces.
for (let x = 18; x <= 30; x += 5) {
set(x, 14, 3, "#e0ab89");
set(x + 2, 14, 4, "#d99776");
set(x, 33, 3, "#d99776");
}
for (let y = 18; y <= 30; y += 5) {
set(14, y, 3, "#e0ab89");
set(33, y, 3, "#d99776");
}
// Chunky plane-tree trunk and spreading roots.
box(21, 21, 3, 26, 26, 7, "#74523a");
box(22, 22, 8, 25, 25, 22, "#816046");
box(22, 22, 23, 25, 25, 27, "#755039");
line(22, 23, 5, 18, 20, 3, 1, "#77543c");
line(25, 24, 5, 29, 21, 3, 1, "#77543c");
line(23, 25, 5, 20, 29, 3, 1, "#77543c");
line(25, 25, 5, 29, 28, 3, 1, "#77543c");
// Plane trees have distinctive pale, flaking patches of bark.
for (let z = 9; z <= 22; z += 4) {
set(23 + (z % 2), 21, z, "#c4a77a");
set(23 + (z % 2), 21, z + 1, "#b69a70");
set(21, 23 + (z % 3), z + 1, "#ac8b64");
set(26, 23, z + 2, "#c3a67a");
}
line(23, 23, 22, 17, 22, 32, 1, "#78563d");
line(25, 24, 23, 32, 22, 33, 1, "#78563d");
line(24, 25, 23, 25, 32, 33, 1, "#78563d");
line(23, 23, 25, 21, 17, 33, 1, "#78563d");
// A full, slightly irregular rounded crown, with darker lower leaves.
const lobes = [
[24, 24, 35, 12, 12, 9],
[17, 23, 34, 8, 9, 8],
[31, 23, 34, 8, 9, 8],
[23, 17, 35, 9, 8, 8],
[25, 31, 35, 10, 8, 8],
[19, 29, 37, 7, 7, 7],
[30, 29, 37, 7, 7, 7]
];
for (let x = 8; x <= 40; x++) {
for (let y = 8; y <= 40; y++) {
for (let z = 25; z <= 44; z++) {
let inside = false;
for (const [cx, cy, cz, rx, ry, rz] of lobes) {
const d = ((x - cx) / rx) ** 2 +
((y - cy) / ry) ** 2 +
((z - cz) / rz) ** 2;
if (d < 1 - rand() * 0.045) { inside = true; break; }
}
if (!inside) continue;
const n = rand();
const color = z < 30 ? (n < 0.23 ? "#438745" : "#326d3a") :
z < 37 ? (n < 0.30 ? "#68a64e" : "#478b43") :
(n < 0.34 ? "#82b75b" : "#60a34c");
set(x, y, z, color);
}
}
}
// A few sunny flecks on the upper surface, rather than an even pattern.
for (const [x, y] of [
[17, 19], [20, 15], [27, 15], [32, 19],
[34, 25], [29, 30], [22, 34], [16, 28],
[24, 22], [28, 25], [20, 25]
]) {
for (let z = 44; z >= 27; z--) {
if (get(x, y, z)) {
set(x, y, z, "#9ac66a");
if (get(x + 1, y, z)) set(x + 1, y, z, "#87ba5d");
break;
}
}
}import { draw } from "./assets/voxel";
import { arbolDeVereda } from "./assets/arbol-de-vereda";
// Every frame: standing on (x, y), the centre of its base.
draw(ctx, arbolDeVereda, 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 arbol-de-vereda
# With Fogón's tools (connector)
add_assets({ slug: "<your-game>", ids: ["arbol-de-vereda"] })
# It lands in client/assets/arbol-de-vereda.ts
# https://fogon.page/object/arbol-de-vereda