← Pirates and sea3D assetfogon/muelle-de-madera
Muelle de madera
Drag to turn it// «Muelle de madera» · gpt-6-sol (medium)
// A wooden pier section: a flat deck of warm brown planks along y standing on thick round posts that go down into a band of turquoise water, with a couple of mooring posts and a coil of rope.
// Turquoise water, with a few bright ripples around the pier.
for (let x = 2; x <= 45; x++) {
for (let y = 2; y <= 45; y++) {
set(x, y, 0, "#117f91");
set(x, y, 1, "#159eaa");
set(x, y, 2, rand() < 0.18 ? "#38d2c7" : "#24bdbb");
if ((x < 8 || x > 41 || y < 5 || y > 42) && rand() < 0.075) {
set(x, y, 3, "#8ce8d5");
if (x < 44 && rand() < 0.55) set(x + 1, y, 3, "#6cddd0");
}
}
}
// Six stout, round timber supports.
for (const x of [11, 38]) {
for (const y of [9, 24, 39]) {
cylinder(x, y, 1, 3, 13, "#80502d");
cylinder(x, y, 3, 2, 10, "#a96b36");
for (let z = 4; z <= 11; z += 3) {
set(x - 2, y - 1, z, "#c58a48");
set(x + 2, y + 1, z, "#684026");
}
// Dark wet wood and a pale ring of foam at the waterline.
cylinder(x, y, 1, 3, 2, "#755039");
for (let a = 0; a < Math.PI * 2; a += 0.33) {
const px = Math.round(x + 4 * Math.cos(a));
const py = Math.round(y + 4 * Math.sin(a));
if (rand() < 0.7) set(px, py, 3, "#a3ead7");
}
}
}
// Thick understructure and the dark gaps beneath individual planks.
box(8, 5, 11, 41, 42, 13, "#85512d");
box(8, 5, 13, 41, 42, 14, "#644028");
box(8, 5, 12, 41, 6, 14, "#a26836");
box(8, 41, 12, 41, 42, 14, "#a26836");
box(7, 5, 12, 8, 42, 14, "#b67a3d");
box(41, 5, 12, 42, 42, 14, "#8e582e");
// Long, chunky boards run along the length of the pier.
// Their short end joints alternate so the deck reads as planking.
const woods = ["#ad7139", "#bf8242", "#c78c49", "#b77b3d"];
for (let lane = 0; lane < 7; lane++) {
const x0 = 8 + lane * 5;
const joints = lane % 2 ? [5, 13, 22, 32, 42] : [5, 16, 26, 35, 42];
for (let j = 0; j < joints.length - 1; j++) {
const y0 = joints[j] + (j ? 1 : 0);
const y1 = joints[j + 1] - 1;
const color = woods[(lane + j) % woods.length];
box(x0, y0, 14, x0 + 3, y1, 15, color);
box(x0, y0, 15, x0, y1, 15, "#d69a52");
for (let y = y0 + 2; y < y1; y += 5) {
if (rand() < 0.7) set(x0 + 2, y, 15, "#d09750");
if (rand() < 0.35) set(x0 + 3, y + 1, 15, "#956033");
}
// Tiny black nailheads at the ends of each board.
for (const nx of [x0 + 1, x0 + 3]) {
set(nx, y0, 16, "#68442d");
set(nx, y1, 16, "#68442d");
}
}
}
// Two bold mooring bollards at the near end.
for (const x of [12, 37]) {
cylinder(x, 9, 16, 2, 5, "#8c542d");
cylinder(x, 9, 17, 2, 3, "#ad7138");
cylinder(x, 9, 21, 3, 2, "#a96934");
cylinder(x, 9, 23, 2, 1, "#db9a4c");
box(x - 3, 8, 20, x + 3, 10, 21, "#714329");
box(x - 2, 8, 22, x + 2, 8, 22, "#df9e50");
}
// A thick, pale rope coiled on the front of the deck.
for (const ring of [
{ radius: 4.2, z: 17 },
{ radius: 2.8, z: 18 },
{ radius: 1.5, z: 19 }
]) {
for (let a = 0; a < Math.PI * 2; a += 0.065) {
const x = Math.round(25 + ring.radius * Math.cos(a));
const y = Math.round(12 + ring.radius * Math.sin(a));
set(x, y, ring.z, Math.sin(a * 7) > 0 ? "#efcc85" : "#d9ac62");
}
}
line(29, 12, 17, 33, 10, 17, 0, "#e6bd75");
line(33, 10, 17, 35, 9, 19, 0, "#e6bd75");
for (let a = 0; a < Math.PI * 2; a += 0.14) {
set(
Math.round(37 + 2.5 * Math.cos(a)),
Math.round(9 + 2.5 * Math.sin(a)),
19,
"#edc780"
);
}import { draw } from "./assets/voxel";
import { muelleDeMadera } from "./assets/muelle-de-madera";
// Every frame: standing on (x, y), the centre of its base.
draw(ctx, muelleDeMadera, 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 muelle-de-madera
# With Fogón's tools (connector)
add_assets({ slug: "<your-game>", ids: ["muelle-de-madera"] })
# It lands in client/assets/muelle-de-madera.ts
# https://fogon.page/object/muelle-de-madera