← Pirates and sea3D assetfogon/tablon
Tablón
Drag to turn it// «Tablón» · gpt-6-sol (medium)
// A wooden plank sticking out from the edge of a short ship rail section: rough warm brown plank pointing toward -y, the rail behind it with a rope.
// Short ship-deck section
const dark = "#65361f";
const shadow = "#804627";
const wood = "#a96232";
const warm = "#bf7940";
const light = "#d89452";
const edge = "#e7aa64";
const ropeDark = "#aa7841";
const rope = "#e6bf79";
const ropeLight = "#f5d999";
const gold = "#efbd47";
// Chunky deck, built from separate lengthwise boards.
box(6, 28, 0, 42, 40, 3, dark);
for (let x = 7; x <= 41; x += 5) {
box(x, 29, 4, Math.min(x + 3, 41), 39, 6, wood);
box(x, 29, 6, Math.min(x + 3, 41), 39, 6, warm);
line(x + 1, 30, 7, x + 1, 37, 7, 0, light);
}
box(6, 27, 2, 42, 29, 5, shadow);
box(6, 27, 5, 42, 27, 6, light);
box(6, 39, 2, 42, 40, 5, shadow);
for (let x = 10; x <= 39; x += 7) {
set(x, 27, 4, gold);
set(x, 27, 3, "#ffe083");
}
// The plank's stout mounting timbers.
box(19, 28, 6, 28, 36, 9, dark);
box(20, 27, 9, 27, 35, 11, shadow);
box(19, 27, 10, 28, 29, 10, warm);
box(20, 26, 8, 21, 32, 10, dark);
box(26, 26, 8, 27, 32, 10, dark);
// Rough projecting plank: broad at the rail, slightly chamfered at its tip.
box(19, 8, 10, 28, 34, 13, shadow);
box(20, 5, 10, 27, 8, 13, shadow);
box(21, 3, 10, 26, 5, 13, wood);
box(19, 9, 13, 28, 33, 13, warm);
box(20, 5, 13, 27, 9, 13, light);
box(21, 3, 13, 26, 5, 13, light);
box(19, 10, 12, 19, 29, 12, dark);
box(28, 12, 12, 28, 31, 12, dark);
// Long grain, split ends, and uneven sunlit scuffs.
line(21, 7, 14, 21, 27, 14, 0, edge);
line(26, 10, 14, 26, 31, 14, 0, "#d48b49");
for (const y of [11, 18, 25, 30]) {
line(23, y, 14, 25, y + 2, 14, 0, "#a85f30");
}
line(23, 3, 14, 23, 7, 14, 0, dark);
set(24, 4, 14, dark);
for (let i = 0; i < 40; i++) {
const x = 20 + Math.floor(rand() * 8);
const y = 8 + Math.floor(rand() * 24);
if (get(x, y, 13)) set(x, y, 14, rand() < 0.55 ? light : wood);
}
for (const y of [19, 29]) {
set(20, y, 14, gold);
set(27, y, 14, gold);
}
// Rail behind the plank, with open gaps between chunky balusters.
box(7, 34, 7, 41, 37, 8, dark);
box(8, 34, 9, 40, 36, 9, warm);
for (const x of [13, 17, 31, 35]) {
box(x, 34, 9, x + 2, 37, 15, shadow);
box(x, 34, 10, x, 34, 14, light);
}
box(7, 34, 15, 41, 38, 18, dark);
box(7, 33, 17, 41, 37, 19, wood);
box(7, 33, 19, 41, 37, 19, edge);
box(8, 33, 16, 40, 33, 16, warm);
for (const x of [8, 40]) {
box(x - 2, 31, 5, x + 2, 38, 20, dark);
box(x - 1, 31, 7, x + 1, 36, 20, wood);
box(x - 1, 31, 18, x + 1, 32, 20, light);
box(x - 2, 31, 21, x + 2, 38, 21, warm);
box(x - 2, 31, 22, x + 2, 38, 22, edge);
set(x, 30, 11, gold);
set(x, 30, 16, gold);
}
// Two heavy rope swags, tied to the posts and hanging in front of the rail.
for (const [a, b] of [[10, 18], [30, 39]]) {
let prev = null;
for (let x = a; x <= b; x++) {
const t = (x - a) / (b - a);
const z = 17 - Math.round(4 * Math.sin(Math.PI * t));
if (prev) line(prev[0], 30, prev[1], x, 30, z, 0.8, ropeDark);
set(x, 29, z, rope);
if (x % 3 === 0) set(x, 28, z, ropeLight);
prev = [x, z];
}
}
for (const x of [8, 40]) {
line(x - 2, 30, 16, x + 2, 30, 16, 0, rope);
line(x - 2, 30, 18, x + 2, 30, 18, 0, ropeLight);
line(x, 30, 15, x, 30, 19, 0, rope);
set(x, 29, 17, ropeLight);
}import { draw } from "./assets/voxel";
import { tablon } from "./assets/tablon";
// Every frame: standing on (x, y), the centre of its base.
draw(ctx, tablon, 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 tablon
# With Fogón's tools (connector)
add_assets({ slug: "<your-game>", ids: ["tablon"] })
# It lands in client/assets/tablon.ts
# https://fogon.page/object/tablon