← Asian3D assetfogon/bonsai
Bonsái
Drag to turn it// «Bonsái» · gpt-6-sol (medium)
// A bonsai tree in a shallow rectangular glazed blue ceramic pot: twisted thick brown trunk leaning to one side, three flat round clouds of bright green foliage, small stones on the soil.
const blue = "#17658a", blueLight = "#328fb1", blueDark = "#124765";
const gold = "#dcb966";
// Foot and shallow glazed ceramic body.
box(12, 15, 0, 36, 33, 1, blueDark);
box(10, 13, 2, 38, 35, 7, blue);
box(10, 12, 3, 38, 12, 7, blueLight);
box(10, 13, 2, 38, 13, 2, blueDark);
box(11, 12, 3, 37, 12, 3, "#236f94");
// Small painted wave motifs on the front.
for (const cx of [16, 24, 32]) {
for (let dx = -3; dx <= 3; dx++) {
const z = 5 + Math.round(Math.sin((dx + 3) * Math.PI / 3));
set(cx + dx, 12, z, "#b4dce0");
}
set(cx, 12, 4, gold);
}
// Thick overhanging rim, with an open center.
box(7, 10, 8, 41, 38, 9, blueDark);
box(8, 10, 9, 40, 38, 10, blueLight);
box(10, 13, 8, 38, 35, 10, null);
box(10, 13, 8, 38, 35, 8, "#493d2d");
box(8, 10, 10, 40, 10, 10, "#70b6c8");
box(8, 11, 9, 40, 11, 9, gold);
box(8, 38, 10, 40, 38, 10, "#65aec2");
box(8, 11, 10, 8, 37, 10, "#70b6c8");
box(40, 11, 10, 40, 37, 10, "#70b6c8");
// Uneven soil and moss within the rim.
for (let x = 11; x <= 37; x++)
for (let y = 14; y <= 34; y++) {
set(x, y, 8, rand() < 0.14 ? "#59643d" : rand() < 0.25 ? "#625038" : "#483b2d");
if (rand() < 0.12) set(x, y, 9, "#597440");
}
// Pebbles on the exposed soil.
for (const [x, y, r, c] of [
[15, 18, 2, "#c4b9a2"], [32, 19, 2, "#9eaa9f"],
[17, 30, 2, "#a5a49a"], [35, 30, 1, "#d3c5aa"],
[28, 32, 1, "#b6afa1"]
]) {
ellipsoid(x, y, 9, r, r - 0.3, 1, c);
set(x - 1, y - 1, 10, "#ddd2bd");
}
// Exposed roots and a twisting, side-leaning trunk.
const bark = "#754126", barkDark = "#542f20", barkLight = "#a66a37";
line(23, 24, 9, 20, 23, 15, 3, barkDark);
line(20, 23, 15, 22, 25, 21, 3, bark);
line(22, 25, 21, 27, 24, 27, 2, barkDark);
line(27, 24, 27, 25, 23, 34, 2, bark);
line(25, 23, 34, 27, 23, 39, 1, bark);
line(22, 24, 11, 15, 19, 9, 1, bark);
line(22, 25, 11, 31, 30, 9, 1, barkDark);
line(21, 23, 13, 17, 27, 9, 1, barkLight);
// The three spreading limbs end beneath separate foliage clouds.
line(21, 24, 19, 16, 23, 23, 2, bark);
line(16, 23, 23, 11, 22, 26, 1, barkDark);
line(24, 25, 22, 31, 25, 27, 2, bark);
line(31, 25, 27, 37, 26, 30, 1, barkDark);
line(26, 23, 34, 21, 22, 38, 1, bark);
line(26, 23, 35, 32, 25, 39, 1, barkDark);
// Short, irregular bark highlights on the viewer-facing side.
line(21, 21, 13, 20, 22, 17, 0, barkLight);
line(21, 22, 19, 24, 23, 23, 0, barkLight);
line(25, 22, 27, 26, 21, 31, 0, barkLight);
line(25, 21, 34, 26, 21, 37, 0, barkLight);
line(18, 21, 22, 14, 21, 25, 0, barkLight);
// Broad, low, gently scalloped foliage pads.
function cloud(cx, cy, cz, rx, ry, rz) {
for (let x = Math.floor(cx - rx - 1); x <= Math.ceil(cx + rx + 1); x++)
for (let y = Math.floor(cy - ry - 1); y <= Math.ceil(cy + ry + 1); y++) {
const dx = (x - cx) / rx, dy = (y - cy) / ry;
const angle = Math.atan2(dy, dx);
const edge = 1 + 0.055 * Math.sin(7 * angle) + 0.045 * Math.cos(11 * angle);
const horizontal = (dx * dx + dy * dy) / (edge * edge);
if (horizontal > 1) continue;
for (let z = cz - rz; z <= cz + rz; z++) {
const vertical = (z - cz) / (rz + 0.25);
if (horizontal + vertical * vertical > 1.04) continue;
let color;
if (z < cz) color = rand() < 0.25 ? "#316c2c" : "#3b7c31";
else if (z === cz) color = rand() < 0.3 ? "#60aa3b" : "#4a9634";
else color = rand() < 0.24 ? "#9bd751" : rand() < 0.5 ? "#74bf40" : "#61ac37";
if (rand() < 0.045) color = "#b5e66a";
set(x, y, z, color);
}
}
}
cloud(13, 22, 26, 9, 7, 3);
cloud(35, 26, 30, 9, 7, 3);
cloud(26, 23, 39, 10, 7, 4);
// A few raised leaf clusters catch the light without obscuring the flat pads.
for (const [x, y, z] of [
[9, 20, 28], [17, 24, 28], [32, 23, 32], [38, 27, 32],
[21, 21, 42], [27, 25, 42], [31, 21, 42]
]) {
ellipsoid(x, y, z, 2, 2, 1, "#83ca48");
set(x, y - 1, z + 1, "#a3dc59");
}import { draw } from "./assets/voxel";
import { bonsai } from "./assets/bonsai";
// Every frame: standing on (x, y), the centre of its base.
draw(ctx, bonsai, 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 bonsai
# With Fogón's tools (connector)
add_assets({ slug: "<your-game>", ids: ["bonsai"] })
# It lands in client/assets/bonsai.ts
# https://fogon.page/object/bonsai