← Level pieces 23D assetfogon/nivel-cerca-de-piedra
Cerca de piedra
Drag to turn it// «Cerca de piedra» · gpt-6-sol (medium)
// A low modular stone fence: exactly 48 long on x (x 0..47), 8 thick (y 20..27), 16 tall, flat ends so it chains. Rounded grey field stones of different sizes in 3 shades stacked dry with dark gaps, a few mossy green patches, a flat cap row of slabs on top.
// Dark mortar keeps the fence solid while leaving crisp dry-stone joints.
box(0, 20, 0, 47, 27, 12, "#596368");
const courses = [
{ lo: 0, hi: 3, stones: [[0, 7], [9, 14], [16, 24], [26, 31], [33, 40], [42, 47]] },
{ lo: 5, hi: 7, stones: [[0, 4], [6, 14], [16, 21], [23, 30], [32, 38], [40, 47]] },
{ lo: 9, hi: 12, stones: [[0, 8], [10, 15], [17, 24], [26, 31], [33, 40], [42, 47]] }
];
const stoneShades = ["#929da0", "#a6afb0", "#828e93"];
for (let row = 0; row < courses.length; row++) {
const { lo, hi, stones } = courses[row];
for (let i = 0; i < stones.length; i++) {
const [left, right] = stones[i];
const shade = stoneShades[(i * 2 + row) % stoneShades.length];
// Stone cores, with subtly clipped corners on both visible faces.
for (let z = lo; z <= hi; z++) {
const edge = (z === lo || z === hi) ? 1 : 0;
const a = Math.min(right, left + edge);
const b = Math.max(a, right - edge);
box(a, 21, z, b, 26, z, shade);
for (const y of [20, 27]) {
const faceInset = edge + ((right - left > 6 && z === lo) ? 1 : 0);
const fa = Math.min(right, left + faceInset);
const fb = Math.max(fa, right - faceInset);
box(fa, y, z, fb, y, z, z === lo ? "#758187" : shade);
// A slim lit upper edge makes each rounded fieldstone readable.
if (z === hi && fb - fa >= 2)
box(fa + 1, y, z, fb, y, z, "#b7bfc0");
}
}
// Sparse, clean flecks rather than noisy stone surfaces.
if (right - left >= 6 && (i + row) % 3 === 0) {
set(left + 3, 20, lo + 1, "#c0c7c5");
set(right - 2, 27, lo + 1, "#737f84");
}
}
}
// Small moss patches tucked into joints and onto neighboring stones.
const moss = [
[12, 20, 5], [13, 20, 5], [12, 20, 6], [13, 20, 4],
[35, 20, 9], [36, 20, 9], [35, 20, 10], [34, 20, 8],
[20, 27, 2], [21, 27, 2], [20, 27, 3],
[44, 27, 9], [45, 27, 9], [44, 27, 10]
];
for (const [x, y, z] of moss) set(x, y, z, "#69a665");
for (const [x, y, z] of [[12, 20, 6], [35, 20, 10], [20, 27, 3], [44, 27, 10]])
set(x, y, z, "#8abf70");
// Flat, grid-aligned cap slabs. Narrow dark joints divide the row.
box(0, 20, 13, 47, 27, 13, "#78858a");
box(0, 20, 14, 47, 27, 14, "#abb5b5");
box(0, 20, 15, 47, 27, 15, "#c9d0cb");
for (const seam of [8, 16, 24, 32, 40]) {
box(seam, 20, 13, seam, 27, 14, "#68757a");
box(seam, 20, 15, seam, 27, 15, "#939fa0");
}
for (let x = 0; x < 48; x++) {
if (x % 8 !== 0) {
set(x, 20, 14, "#b7c0be");
set(x, 20, 15, "#d5dad2");
}
}import { draw } from "./assets/voxel";
import { nivelCercaDePiedra } from "./assets/nivel-cerca-de-piedra";
// Every frame: standing on (x, y), the centre of its base.
draw(ctx, nivelCercaDePiedra, 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 nivel-cerca-de-piedra
# With Fogón's tools (connector)
add_assets({ slug: "<your-game>", ids: ["nivel-cerca-de-piedra"] })
# It lands in client/assets/nivel-cerca-de-piedra.ts
# https://fogon.page/object/nivel-cerca-de-piedra