← Basics3D assetfogon/mesa-consola
Mesa consola
Drag to turn it// «Mesa consola» · gpt-6-sol (medium)
// Console table («Mesa consola»).
// Mesa consola — warm wood, two drawers, a lower shelf, and small tabletop objects.
const wood = "#ae693c", woodLight = "#d38a50", woodTop = "#dc9557";
const woodDark = "#704126", woodShadow = "#8b512f";
const brass = "#e7c46d", brassDark = "#a77937";
// Four sturdy, square legs.
for (const x of [8, 39]) {
for (const y of [13, 31]) {
box(x, y, 0, x + 2, y + 2, 25, wood);
box(x, y, 0, x, y + 2, 24, woodLight);
box(x + 2, y, 0, x + 2, y + 2, 24, woodShadow);
box(x, y, 0, x + 2, y + 2, 1, woodDark);
}
}
// Low open shelf and its supporting rails.
box(10, 15, 7, 40, 32, 8, woodShadow);
box(10, 15, 9, 40, 32, 9, woodLight);
box(10, 15, 10, 40, 15, 10, woodTop);
box(10, 16, 9, 40, 16, 9, woodTop);
box(11, 32, 7, 38, 33, 8, woodDark);
for (const y of [20, 27]) {
box(11, y, 9, 38, y, 9, "#bc7847");
}
// Cabinet beneath the tabletop.
box(9, 14, 20, 40, 33, 25, woodShadow);
box(9, 14, 23, 40, 33, 25, wood);
box(10, 13, 19, 39, 14, 24, woodDark);
box(10, 14, 19, 39, 14, 20, "#9a5931");
box(10, 15, 19, 11, 32, 23, woodDark);
box(38, 15, 19, 39, 32, 23, woodDark);
// Framed pair of front-facing drawers.
box(12, 12, 19, 38, 13, 24, "#623922");
for (const [a, b] of [[13, 24], [27, 37]]) {
box(a, 11, 20, b, 12, 23, "#b87340");
box(a + 1, 11, 22, b - 1, 11, 23, "#c78046");
box(a + 1, 11, 20, b - 1, 11, 20, "#87502c");
box(a, 11, 20, a, 11, 23, "#e19a58");
}
box(25, 11, 19, 26, 13, 24, woodDark);
for (const x of [19, 32]) {
box(x - 1, 10, 21, x + 1, 10, 21, brassDark);
box(x, 9, 21, x + 1, 10, 22, brass);
set(x, 9, 22, "#fff0a2");
}
// Thick overhanging top, with clipped corners.
for (let z = 25; z <= 27; z++) {
for (let y = 10; y <= 36; y++) {
for (let x = 5; x <= 44; x++) {
if ((x === 5 || x === 44) && (y === 10 || y === 36)) continue;
let c = z === 27 ? woodTop : z === 26 ? woodLight : woodDark;
if (z === 27 && rand() < 0.16) c = rand() < 0.5 ? "#e5a366" : "#ca8049";
set(x, y, z, c);
}
}
}
box(6, 10, 25, 43, 10, 25, "#8e502d");
box(6, 10, 26, 43, 10, 26, "#b9703e");
box(6, 11, 27, 43, 11, 27, "#e8a469");
box(6, 36, 25, 43, 36, 26, "#a96436");
box(44, 12, 25, 44, 34, 26, "#a76034");
// Subtle long plank joints.
for (const y of [19, 29]) {
for (let x = 8; x <= 42; x++) {
if (rand() < 0.78) set(x, y, 27, "#bd7945");
}
}
// Small stack of colorful books at the left of the lower shelf.
box(14, 17, 10, 21, 23, 11, "#287f83");
box(14, 16, 11, 21, 22, 12, "#df9a54");
box(15, 16, 12, 21, 22, 13, "#e6d3a0");
box(14, 17, 13, 20, 23, 14, "#317c82");
box(14, 17, 14, 20, 23, 14, "#49a3a1");
box(14, 17, 15, 21, 22, 15, "#ad6539");
box(15, 16, 12, 15, 16, 14, "#f0deb1");
box(18, 16, 12, 18, 16, 13, "#8b5535");
// Pale storage box on the shelf.
box(26, 20, 10, 35, 29, 16, "#a88c62");
box(27, 19, 11, 34, 19, 15, "#c4aa7a");
box(27, 19, 11, 34, 19, 11, "#8c7655");
box(26, 19, 16, 35, 29, 17, "#d4bd89");
box(27, 19, 17, 34, 28, 17, "#e4d0a0");
box(30, 18, 14, 32, 18, 14, brassDark);
box(30, 18, 15, 32, 18, 15, brass);
for (const x of [27, 34]) {
box(x, 20, 11, x, 28, 11, "#937e5c");
}
// Blue-green flowerpot on the tabletop.
box(12, 22, 28, 18, 28, 29, "#377f7d");
box(13, 22, 30, 17, 27, 32, "#438f8b");
box(12, 23, 31, 18, 27, 32, "#4caaa3");
box(12, 23, 32, 18, 28, 32, "#327d78");
box(13, 23, 33, 17, 27, 33, "#63b5aa");
box(14, 22, 30, 15, 22, 31, "#64b5ad");
box(17, 24, 30, 18, 26, 31, "#296f70");
box(13, 25, 33, 17, 27, 33, "#504a32");
// Stems, clustered leaves, and little ivory blossoms.
line(15, 25, 33, 15, 25, 40, 0, "#557b3d");
line(15, 25, 36, 12, 23, 39, 0, "#527443");
line(15, 25, 37, 19, 26, 40, 0, "#557b3d");
line(15, 25, 38, 16, 27, 42, 0, "#6b8545");
for (const [x, y, z] of [
[12, 23, 36], [13, 22, 37], [18, 26, 37], [19, 25, 38],
[13, 26, 39], [17, 24, 38], [16, 28, 39], [14, 26, 40]
]) {
box(x, y, z, x + 1, y + 1, z, rand() < 0.5 ? "#547f43" : "#668a4a");
}
for (const [x, y, z] of [[12, 23, 40], [16, 27, 43], [19, 26, 41]]) {
box(x, y, z - 1, x + 1, y + 1, z, "#d8ca83");
set(x, y, z + 1, "#f1e3aa");
set(x + 1, y + 1, z, "#b6aa70");
}
// A compact orange-covered book on the desk.
box(22, 17, 28, 31, 25, 28, "#293a45");
box(22, 17, 29, 31, 25, 29, "#e6d2a1");
box(22, 17, 30, 31, 25, 30, "#31434a");
box(21, 17, 31, 31, 25, 31, "#bc5d3c");
box(21, 18, 32, 31, 25, 32, "#e88455");
box(22, 17, 30, 23, 17, 31, "#853d32");
box(27, 16, 29, 29, 16, 29, "#eee2c0");
// Table lamp at the back right: dark base, thin stem, stepped linen shade.
box(34, 29, 28, 38, 33, 28, "#6b5037");
box(35, 28, 29, 37, 34, 29, "#9a784b");
box(35, 29, 30, 37, 33, 30, "#c09d63");
box(36, 30, 31, 36, 32, 36, "#8e754f");
box(36, 30, 31, 36, 30, 35, "#d0b989");
for (let z = 35; z <= 42; z++) {
const r = z <= 36 ? 6 : z <= 38 ? 5 : z <= 40 ? 4 : 3;
for (let y = 31 - r; y <= 31 + r; y++) {
for (let x = 36 - r; x <= 36 + r; x++) {
if (Math.abs(x - 36) === r && Math.abs(y - 31) === r) continue;
let c = "#c8bd9b";
if (z === 35 || z === 42) c = "#a69a79";
else if (y === 31 - r) c = "#eee3c5";
else if (x === 36 - r) c = "#ded4b2";
else if (x === 36 + r || y === 31 + r) c = "#aa9d7e";
if (rand() < 0.075) c = "#b7a988";
set(x, y, z, c);
}
}
}
// Shade ribs and a small finial.
for (const x of [32, 36, 40]) {
for (let z = 36; z <= 39; z++) {
const r = z <= 38 ? 5 : 4;
if (Math.abs(x - 36) <= r) set(x, 31 - r, z, "#c1b492");
}
}
box(35, 30, 43, 37, 32, 43, "#e6dab8");
box(36, 31, 44, 36, 31, 44, "#9e8b65");import { draw } from "./assets/voxel";
import { mesaConsola } from "./assets/mesa-consola";
// Every frame: standing on (x, y), the centre of its base.
draw(ctx, mesaConsola, 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 mesa-consola
# With Fogón's tools (connector)
add_assets({ slug: "<your-game>", ids: ["mesa-consola"] })
# It lands in client/assets/mesa-consola.ts
# https://fogon.page/object/mesa-consola