← Basics3D assetfogon/tractor
Tractor
Drag to turn it// «Tractor» · gpt-6-sol (medium)
// Tractor («Tractor»).
// Block-built green tractor, facing -y.
const green = "#23843a";
const lightGreen = "#44b84a";
const darkGreen = "#14532d";
const black = "#20262a";
const tire = "#25292b";
const gold = "#c39432";
function wheel(cx, cy, cz, radius, width) {
const outer = cx < 24 ? cx : cx + width - 1;
for (let x = cx; x < cx + width; x++) {
for (let y = Math.floor(cy - radius); y <= Math.ceil(cy + radius); y++) {
for (let z = Math.floor(cz - radius); z <= Math.ceil(cz + radius); z++) {
const d = Math.hypot(y - cy, z - cz);
if (d > radius) continue;
let c = d > radius - 1.5 ? "#171c1e" : tire;
if (d < radius - 2.2) c = "#303538";
if (z > cz + 2 && d < radius - 1.4) c = "#383d3e";
set(x, y, z, c);
}
}
}
// Broad, separated lugs around the tire's circumference.
for (let i = 0; i < 18; i++) {
const a = i * Math.PI * 2 / 18;
const yy = Math.round(cy + Math.cos(a) * (radius - 0.5));
const zz = Math.round(cz + Math.sin(a) * (radius - 0.5));
for (let x = cx; x < cx + width; x++) {
if (i % 3 !== 0 || x === cx || x === cx + width - 1)
set(x, yy, zz, i % 2 ? "#202426" : "#363b3c");
}
}
const face = cx < 24 ? outer - 1 : outer + 1;
const hubR = radius * 0.48;
for (let y = Math.floor(cy - hubR); y <= Math.ceil(cy + hubR); y++) {
for (let z = Math.floor(cz - hubR); z <= Math.ceil(cz + hubR); z++) {
const d = Math.hypot(y - cy, z - cz);
if (d > hubR) continue;
set(outer, y, z, d > hubR - 0.9 ? "#756032" :
z > cz ? "#dfb84e" : gold);
if (d < hubR - 1.1)
set(face, y, z, z > cz ? "#d7ad42" : "#a57829");
}
}
for (let i = 0; i < 8; i++) {
const a = i * Math.PI / 4;
set(face + (cx < 24 ? -1 : 1),
cy + Math.cos(a) * hubR * 0.72,
cz + Math.sin(a) * hubR * 0.72, "#e9ca69");
}
set(face + (cx < 24 ? -1 : 1), cy, cz, "#827044");
}
// Heavy chassis and rear axle.
box(13, 10, 10, 37, 38, 14, "#303635");
box(15, 12, 14, 36, 37, 17, darkGreen);
box(10, 29, 9, 40, 33, 11, "#3b4141");
// Four tires: tall rear tires and smaller, steerable-looking front tires.
wheel(5, 31, 10, 10, 8);
wheel(36, 31, 10, 10, 8);
wheel(9, 11, 7, 6, 6);
wheel(35, 11, 7, 6, 6);
// Green rear fenders, stepped to follow the wheel arches.
box(10, 24, 19, 17, 39, 21, darkGreen);
box(11, 25, 21, 18, 38, 23, green);
box(12, 26, 23, 18, 37, 24, lightGreen);
box(32, 24, 19, 39, 39, 21, darkGreen);
box(31, 25, 21, 38, 38, 23, green);
box(31, 26, 23, 37, 37, 24, lightGreen);
for (let y = 25; y <= 38; y += 3) {
box(11, y, 21, 15, y, 22, "#329741");
box(35, y, 21, 38, y, 22, "#329741");
}
// Engine housing: squared-off nose with a broad, gently stepped hood.
box(16, 7, 13, 35, 26, 21, darkGreen);
box(16, 9, 19, 35, 25, 23, green);
box(17, 9, 22, 34, 24, 24, lightGreen);
box(18, 9, 24, 33, 23, 24, "#61ca55");
box(17, 7, 19, 34, 10, 21, "#328d3a");
box(18, 7, 21, 33, 9, 22, "#4db84b");
// Dark engine side, with narrow cooling slots.
box(16, 12, 14, 16, 25, 19, "#133d2b");
box(35, 12, 14, 35, 25, 19, "#133d2b");
for (let y = 13; y <= 23; y += 2) {
box(15, y, 15, 15, y, 19, "#242e2d");
box(36, y, 15, 36, y, 19, "#242e2d");
}
box(15, 14, 20, 16, 23, 20, "#d5aa3c");
box(35, 14, 20, 36, 23, 20, "#d5aa3c");
// Silver-gray grille, headlights, and rugged front bumper.
box(18, 6, 12, 33, 7, 19, "#313b3d");
box(19, 5, 13, 32, 5, 18, "#a5afb1");
for (let x = 20; x <= 31; x += 3)
box(x, 4, 13, x + 1, 5, 18, "#75878b");
box(16, 6, 18, 19, 8, 21, "#f1dfaa");
box(32, 6, 18, 35, 8, 21, "#f1dfaa");
box(16, 5, 18, 19, 5, 20, "#e8c680");
box(32, 5, 18, 35, 5, 20, "#e8c680");
box(14, 3, 6, 37, 5, 8, "#3b4849");
box(15, 2, 8, 36, 4, 8, "#89999b");
box(17, 3, 5, 34, 5, 5, "#222b2d");
// Cab base and dark metal uprights.
box(16, 25, 15, 35, 39, 22, "#174c2f");
box(17, 25, 20, 34, 38, 23, "#2f973e");
box(15, 23, 23, 17, 26, 38, "#202c2e");
box(34, 23, 23, 36, 26, 38, "#202c2e");
box(15, 37, 23, 17, 39, 38, "#253333");
box(34, 37, 23, 36, 39, 38, "#253333");
// Front windshield and side windows: blue glass with pale reflections.
box(18, 24, 25, 33, 24, 37, "#79969b");
box(19, 23, 26, 32, 23, 36, "#64838b");
box(20, 22, 31, 20, 22, 34, "#abc4c5");
box(22, 22, 33, 22, 22, 36, "#b7cccc");
box(25, 22, 29, 26, 22, 31, "#a9c0c1");
box(29, 22, 34, 29, 22, 36, "#aec8c8");
box(18, 23, 25, 18, 23, 37, "#202b2d");
box(33, 23, 25, 33, 23, 37, "#202b2d");
box(16, 27, 25, 16, 36, 36, "#64838b");
box(35, 27, 25, 35, 36, 36, "#637e83");
box(16, 31, 31, 16, 31, 35, "#adc5c4");
box(35, 29, 32, 35, 29, 35, "#9db7b7");
box(16, 33, 24, 16, 33, 38, "#26383a");
box(35, 33, 24, 35, 33, 38, "#26383a");
// Roof with a deep shadowed lip and bright green top.
box(12, 21, 38, 39, 42, 39, "#174b2d");
box(12, 22, 39, 39, 41, 40, "#247c37");
box(14, 23, 41, 37, 39, 41, lightGreen);
box(15, 24, 42, 36, 38, 42, "#66cf59");
box(12, 21, 38, 39, 22, 38, "#103b27");
// Exhaust stack and two blocky mirrors.
box(36, 17, 23, 38, 19, 31, "#263133");
box(36, 16, 30, 39, 20, 32, "#3a4849");
box(36, 16, 33, 39, 20, 33, "#a9bec0");
box(11, 19, 31, 15, 20, 32, "#273537");
box(9, 17, 29, 12, 21, 34, "#303d40");
box(9, 17, 30, 9, 21, 33, "#9aadb0");
box(37, 21, 33, 41, 22, 34, "#2a3638");
box(40, 18, 31, 43, 23, 35, "#334347");
box(43, 19, 32, 43, 22, 34, "#a9bcbd");
// Small amber beacon on the roof.
box(23, 29, 43, 26, 32, 43, "#3b3830");
box(23, 29, 44, 26, 32, 45, "#cc8d20");
box(24, 29, 45, 25, 30, 45, "#ffd667");
box(23, 29, 46, 26, 32, 46, "#6c531d");import { draw } from "./assets/voxel";
import { tractor } from "./assets/tractor";
// Every frame: standing on (x, y), the centre of its base.
draw(ctx, tractor, 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 tractor
# With Fogón's tools (connector)
add_assets({ slug: "<your-game>", ids: ["tractor"] })
# It lands in client/assets/tractor.ts
# https://fogon.page/object/tractor