← Farm3D assetfogon/granero
Granero
Drag to turn it// «Granero» · gpt-6-sol (medium)
// A classic American red barn: tall red plank walls with vertical board texture, a big gambrel roof (two slopes per side) in dark grey shingles, white trim on all corners and roof edges, large double front doors with a white X brace on each door, a white-framed hayloft door above them with golden hay peeking out, a small weathervane rooster on the roof ridge, on a green grass base.
// Sunny cartoon barn, facing -y.
const red = "#bd3034";
const redLight = "#d8423f";
const redDark = "#98282d";
const white = "#f7f2df";
const whiteShade = "#dcdcd0";
const roof = "#454a50";
const roofLight = "#62676b";
const roofDark = "#343a40";
const wood = "#875034";
const hay = "#efc34c";
// Grass and the worn path to the doors.
box(3, 4, 0, 44, 43, 0, "#66b947");
for (let x = 3; x <= 44; x++) {
for (let y = 4; y <= 43; y++) {
if (rand() < 0.12) set(x, y, 0, rand() < 0.5 ? "#78c955" : "#55a83f");
}
}
for (let y = 4; y <= 10; y++) {
const halfWidth = 4 + Math.floor((10 - y) / 3);
for (let x = 24 - halfWidth; x <= 24 + halfWidth; x++) {
set(x, y, 0, rand() < 0.2 ? "#cfb077" : "#c3a16b");
}
}
// Low stone footing and solid red barn.
box(10, 10, 1, 37, 38, 2, "#aaa9a0");
box(11, 11, 3, 36, 37, 25, red);
// Give every exposed wall broad, individually shaded vertical planks.
for (let x = 11; x <= 36; x++) {
const shade = x % 3 === 0 ? redDark : x % 3 === 1 ? red : redLight;
for (let z = 3; z <= 25; z++) {
set(x, 11, z, shade);
set(x, 37, z, shade);
}
}
for (let y = 11; y <= 37; y++) {
const shade = y % 3 === 0 ? redDark : y % 3 === 1 ? red : redLight;
for (let z = 3; z <= 25; z++) {
set(11, y, z, shade);
set(36, y, z, shade);
}
}
// Narrow shadow grooves between boards.
for (let x = 14; x < 36; x += 3) {
box(x, 10, 4, x, 10, 24, redDark);
box(x, 38, 4, x, 38, 24, redDark);
}
for (let y = 14; y < 37; y += 3) {
box(10, y, 4, 10, y, 24, redDark);
box(37, y, 4, 37, y, 24, redDark);
}
// Gambrel profile: steep lower slopes, shallower upper slopes.
function roofHeight(x) {
const d = Math.abs(x - 23.5);
if (d <= 2) return 37;
if (d <= 9) return 37 - Math.ceil((d - 2) * 5 / 7);
return 32 - Math.ceil((d - 9) * 7 / 5);
}
// Solid red front and rear gables.
for (let x = 11; x <= 36; x++) {
for (let z = 26; z < roofHeight(x) - 1; z++) {
box(x, 11, z, x, 37, z, x % 3 === 0 ? redDark : red);
}
}
// Roof shingles, with staggered rows and a little sunny variation.
for (let x = 9; x <= 38; x++) {
const h = roofHeight(x);
for (let y = 9; y <= 40; y++) {
box(x, y, h - 1, x, y, h, roofDark);
const row = Math.floor((y + (Math.floor(x / 3) % 2)) / 3);
const shingleColor = row % 2 === 0 ? roof : roofLight;
set(x, y, h, y % 3 === 0 ? roofDark : shingleColor);
if (y > 10 && y < 39 && rand() < 0.055) {
set(x, y, h, "#74777a");
}
}
}
// Crisp white edges trace the characteristic double-slope roof.
for (let x = 9; x <= 38; x++) {
const h = roofHeight(x);
box(x, 8, h - 1, x, 8, h, white);
box(x, 41, h - 1, x, 41, h, whiteShade);
}
for (let y = 8; y <= 41; y++) {
box(9, y, roofHeight(9) - 1, 9, y, roofHeight(9), white);
box(38, y, roofHeight(38) - 1, 38, y, roofHeight(38), white);
}
box(22, 9, 38, 25, 40, 38, "#858a88");
// Corner boards, eave molding, and foundation trim.
for (const x of [11, 36]) {
for (const y of [10, 38]) box(x, y, 3, x, y, 25, white);
}
for (const x of [10, 37]) {
box(x, 11, 3, x, 37, 25, white);
}
box(12, 10, 24, 35, 10, 25, white);
box(12, 38, 24, 35, 38, 25, whiteShade);
box(12, 10, 3, 35, 10, 3, whiteShade);
// Oversized paired wooden doors.
box(16, 9, 4, 23, 10, 19, wood);
box(24, 9, 4, 31, 10, 19, wood);
for (let x = 17; x <= 30; x += 2) {
box(x, 8, 5, x, 8, 18, "#a66b3e");
}
for (const [a, b] of [[16, 23], [24, 31]]) {
box(a, 7, 4, a, 7, 19, white);
box(b, 7, 4, b, 7, 19, white);
box(a, 7, 4, b, 7, 4, white);
box(a, 7, 19, b, 7, 19, white);
line(a + 1, 6, 5, b - 1, 6, 18, 0, white);
line(a + 1, 6, 18, b - 1, 6, 5, 0, white);
}
box(15, 8, 3, 15, 8, 20, white);
box(32, 8, 3, 32, 8, 20, white);
box(15, 8, 20, 32, 8, 20, white);
box(23, 6, 10, 23, 6, 12, "#f4cb65");
box(24, 6, 10, 24, 6, 12, "#f4cb65");
// White-framed hayloft opening, full of golden straw.
box(20, 9, 25, 27, 10, 31, "#593b2e");
ellipsoid(23.5, 8, 27.5, 3, 1, 2, hay);
for (let x = 21; x <= 26; x++) {
set(x, 7, 29 + (x % 2), "#ffdc70");
if (x % 2 === 0) set(x, 7, 26, "#c89436");
}
box(19, 7, 24, 19, 7, 32, white);
box(28, 7, 24, 28, 7, 32, white);
box(19, 7, 24, 28, 7, 24, white);
box(19, 7, 32, 28, 7, 32, white);
box(23, 6, 31, 24, 6, 31, whiteShade);
// A white-trimmed window on each long side.
for (const x of [9, 38]) {
box(x, 22, 12, x, 29, 20, white);
box(x + (x === 9 ? -1 : 1), 23, 13,
x + (x === 9 ? -1 : 1), 28, 19, "#84c9db");
const outer = x === 9 ? 8 : 39;
box(outer, 25, 13, outer, 25, 19, white);
box(outer, 23, 16, outer, 28, 16, white);
box(outer, 23, 19, outer, 24, 19, "#c7eef2");
}
// A few cheerful clumps beside the path.
for (let i = 0; i < 32; i++) {
const x = 5 + Math.floor(rand() * 38);
const y = 5 + Math.floor(rand() * 35);
if (x >= 10 && x <= 38 && y >= 9 && y <= 41) continue;
if (x >= 17 && x <= 31 && y < 11) continue;
set(x, y, 1, rand() < 0.75 ? "#348e3e" : "#f8e48a");
}
// Galvanized weathervane, with a small rooster silhouette above the ridge.
box(24, 23, 39, 24, 23, 42, "#bfc4bd");
box(18, 23, 40, 30, 23, 40, "#bfc4bd");
line(18, 23, 40, 21, 23, 42, 0, "#e5e6dc");
line(18, 23, 40, 21, 23, 38, 0, "#e5e6dc");
box(29, 23, 39, 30, 23, 41, "#858e8b");
ellipsoid(24, 23, 43, 3, 1, 2, "#db9644");
box(21, 23, 43, 22, 23, 45, "#db9644");
box(20, 23, 44, 22, 23, 45, "#edb24f");
set(19, 23, 44, "#f6d061"); // beak
set(21, 22, 45, "#252b2a"); // eye
box(21, 23, 46, 22, 23, 46, "#cf3430"); // comb
line(27, 23, 43, 29, 23, 46, 0, "#b83530");
line(27, 23, 43, 30, 23, 44, 0, "#d94a34");
line(27, 23, 43, 29, 23, 42, 0, "#aa302f");import { draw } from "./assets/voxel";
import { granero } from "./assets/granero";
// Every frame: standing on (x, y), the centre of its base.
draw(ctx, granero, 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 granero
# With Fogón's tools (connector)
add_assets({ slug: "<your-game>", ids: ["granero"] })
# It lands in client/assets/granero.ts
# https://fogon.page/object/granero