← Piratas y marObjeto 3Dfogon/taberna-del-puerto
Taberna del puerto
Arrastrá para girarlo// «Taberna del puerto» · gpt-6-sol (medium)
// A cozy two-story harbor tavern: warm stone ground floor, timber upper floor with cream plaster, a dark slate roof, a hanging sign with a mug, round windows glowing yellow, barrels by the door.
const stone = ["#d9ad78", "#e4bb87", "#c99564"];
const plaster = ["#f7e5ba", "#fff0cc", "#ead4a8"];
const wood = "#704126";
const darkWood = "#482b21";
const lightWood = "#a76a37";
const gold = "#f4bd42";
// Stone foundation and ground-floor walls.
box(9, 10, 0, 39, 38, 1, "#9a6847");
box(9, 10, 15, 39, 38, 17, "#805135");
for (let z = 2; z <= 15; z++) {
for (let x = 9; x <= 39; x++) {
let c = stone[(Math.floor(x / 5) + Math.floor(z / 3) + (rand() < 0.13 ? 1 : 0)) % 3];
set(x, 10, z, c);
set(x, 38, z, c);
}
for (let y = 11; y < 38; y++) {
let c = stone[(Math.floor(y / 5) + Math.floor(z / 3) + (rand() < 0.13 ? 1 : 0)) % 3];
set(9, y, z, c);
set(39, y, z, c);
}
}
// Subtle staggered mortar joints.
for (let z = 4; z < 16; z += 4) {
for (let x = 10; x < 39; x++) if (x % 6 === (z % 8 ? 2 : 5)) set(x, 9, z, "#b8865d");
}
// Projecting timber upper story.
box(7, 8, 17, 41, 40, 19, darkWood);
box(8, 8, 20, 40, 40, 32, "#bd895a");
for (let z = 20; z <= 31; z++) {
for (let x = 9; x <= 39; x++) {
set(x, 7, z, plaster[(Math.floor(x / 6) + Math.floor(z / 5) + (rand() < 0.08 ? 1 : 0)) % 3]);
set(x, 41, z, plaster[(Math.floor(x / 6) + Math.floor(z / 5)) % 3]);
}
for (let y = 9; y <= 39; y++) {
set(7, y, z, plaster[(Math.floor(y / 6) + Math.floor(z / 5)) % 3]);
set(41, y, z, plaster[(Math.floor(y / 6) + Math.floor(z / 5)) % 3]);
}
}
box(7, 6, 17, 41, 42, 19, wood);
box(7, 7, 31, 41, 41, 33, wood);
for (const x of [7, 19, 29, 41]) box(x, 6, 19, x + 1, 7, 32, wood);
for (const y of [8, 20, 30, 40]) {
box(7, y, 19, 8, y + 1, 32, wood);
box(40, y, 19, 41, y + 1, 32, wood);
}
for (let z of [21, 30]) {
box(8, 6, z, 40, 6, z, lightWood);
box(7, 9, z, 7, 39, z, lightWood);
box(41, 9, z, 41, 39, z, lightWood);
}
// Front gable, tucked beneath the roof.
for (let x = 8; x <= 40; x++) {
let top = 42 - Math.ceil(Math.abs(x - 24) * 0.59);
for (let z = 34; z <= top; z++)
set(x, 7, z, plaster[(Math.floor(x / 5) + z) % 3]);
}
// Broad, steep slate roof with chunky overlapping tile courses.
for (let x = 5; x <= 43; x++) {
let height = 43 - Math.ceil(Math.abs(x - 24) * 0.59);
for (let y = 6; y <= 42; y++) {
let tile = (Math.floor(y / 4) + Math.floor(x / 4)) % 3;
let c = ["#344451", "#405362", "#4b5f6b"][tile];
if (rand() < 0.09) c = "#5b6b75";
set(x, y, height - 1, "#263640");
set(x, y, height, c);
if (y % 4 === 0) set(x, y, height, "#283b47");
}
set(x, 5, height, "#263640");
set(x, 6, height - 1, darkWood);
}
box(23, 5, 43, 25, 43, 44, "#263640");
box(23, 5, 44, 25, 42, 44, "#52636d");
// Gable trim and a tiny glowing attic porthole.
for (let x = 8; x <= 40; x++) {
let h = 43 - Math.ceil(Math.abs(x - 24) * 0.59);
set(x, 5, h - 1, darkWood);
if (x % 3 === 0) set(x, 5, h, "#64717a");
}
for (let dx = -3; dx <= 3; dx++)
for (let dz = -3; dz <= 3; dz++) {
let d = dx * dx + dz * dz;
if (d <= 10) set(24 + dx, 5, 37 + dz, d >= 5 ? darkWood : "#ffd668");
}
// Stone chimney breaking through the right roof slope.
box(32, 27, 36, 36, 32, 44, "#b98259");
box(31, 26, 44, 37, 33, 45, "#7f5543");
box(33, 28, 45, 35, 31, 45, "#302d30");
box(32, 27, 45, 36, 27, 45, "#d3a176");
// Round glowing windows: warm glass inside thick timber and gold rims.
function roundFront(cx, cz, radius, y) {
for (let dx = -radius; dx <= radius; dx++)
for (let dz = -radius; dz <= radius; dz++) {
let d = dx * dx + dz * dz;
if (d <= radius * radius + 2) {
let c = d > (radius - 1) ** 2 ? darkWood :
d > (radius - 2) ** 2 ? gold :
(dx + dz > 0 ? "#ffd966" : "#ffed9b");
set(cx + dx, y, cz + dz, c);
}
}
box(cx, y - 1, cz - radius + 2, cx, y - 1, cz + radius - 2, wood);
box(cx - radius + 2, y - 1, cz, cx + radius - 2, y - 1, cz, wood);
set(cx - 1, y - 2, cz + 1, "#fff8cb");
}
roundFront(14, 25, 4, 5);
roundFront(34, 25, 4, 5);
roundFront(14, 9, 4, 9);
roundFront(34, 9, 4, 9);
// Paneled front door, recessed in a bold timber surround.
box(20, 8, 1, 29, 10, 14, darkWood);
box(22, 7, 1, 27, 7, 12, "#7d492a");
for (const x of [22, 24, 26]) box(x, 6, 2, x, 6, 11, "#a96838");
box(21, 6, 0, 21, 9, 13, lightWood);
box(28, 6, 0, 28, 9, 13, lightWood);
box(21, 6, 13, 28, 9, 14, wood);
set(26, 5, 6, gold);
set(26, 5, 7, "#ffe489");
box(21, 4, 0, 28, 6, 0, "#d7ac77");
box(22, 7, 0, 27, 9, 0, "#b9895a");
// Cheerful red-and-white striped entrance awning.
box(19, 4, 14, 30, 9, 15, darkWood);
for (let x = 19; x <= 30; x++) {
let stripe = Math.floor((x - 19) / 2) % 2;
box(x, 3, 14, x, 8, 14, stripe ? "#fff1d9" : "#d64b3d");
set(x, 3, 13, stripe ? "#fff1d9" : "#d64b3d");
}
box(19, 3, 15, 30, 3, 15, gold);
// Barrel stacks flanking the entrance.
function barrel(cx, cy, z) {
cylinder(cx, cy, z, 3, 7, "#93592f");
cylinder(cx, cy, z + 1, 3, 1, "#b4773e");
cylinder(cx, cy, z + 5, 3, 1, "#b4773e");
cylinder(cx, cy, z + 2, 3.2, 1, "#43484b");
cylinder(cx, cy, z + 6, 3.2, 1, "#43484b");
cylinder(cx, cy, z + 7, 2.3, 1, "#c38a4d");
set(cx, cy, z + 7, "#76482c");
}
barrel(16, 5, 0);
barrel(34, 5, 0);
barrel(38, 8, 0);
// Hanging tavern sign, mounted out from the upper story.
box(38, 4, 28, 44, 7, 29, darkWood);
box(43, 3, 27, 44, 4, 29, gold);
box(41, 3, 25, 41, 4, 28, "#665344");
box(38, 2, 18, 44, 4, 25, darkWood);
box(39, 1, 19, 43, 1, 24, "#bd713d");
box(39, 1, 19, 43, 1, 19, gold);
box(39, 1, 24, 43, 1, 24, gold);
box(39, 1, 19, 39, 1, 24, gold);
box(43, 1, 19, 43, 1, 24, gold);
// A foamy mug icon on the sign's outward face.
box(40, 0, 20, 41, 0, 22, "#ffe3a0");
box(40, 0, 23, 42, 0, 23, "#fff9dd");
set(42, 0, 22, "#ffe3a0");
set(42, 0, 21, "#ffe3a0");
set(40, 0, 20, gold);
// Lantern and a few bright dockside touches.
box(10, 5, 13, 11, 7, 14, darkWood);
box(10, 4, 10, 11, 5, 12, gold);
box(10, 3, 11, 11, 3, 11, "#ffefa0");
box(9, 4, 9, 12, 6, 9, darkWood);
box(9, 4, 13, 12, 6, 13, darkWood);
box(8, 8, 16, 40, 9, 16, "#e6bd81");
for (let x = 10; x <= 38; x += 6) set(x, 8, 16, "#f3ce90");import { draw } from "./assets/voxel";
import { tabernaDelPuerto } from "./assets/taberna-del-puerto";
// En cada cuadro: parado sobre (x, y), el centro de su base.
draw(ctx, tabernaDelPuerto, x, y, { size: 64, angle: 0, t: performance.now() / 1000 });
// size: lo que mide en px su lado más largo
// angle: giro sobre el piso, en radianes
// t: segundos; si se mueve, se anima solo con eso# En una terminal, en la carpeta del juego
fogon assets add taberna-del-puerto
# Con las herramientas de Fogón (conector)
add_assets({ slug: "<tu-juego>", ids: ["taberna-del-puerto"] })
# Queda en client/assets/taberna-del-puerto.ts
# https://fogon.page/object/taberna-del-puerto