← Level pieces 23D assetfogon/nivel-lava-agrietada
Roca con lava
Drag to turn it// «Roca con lava» · gpt-6-sol (medium)
// A square ground tile that tiles seamlessly: a full 48x48 footprint (x 0..47, y 0..47), 8 blocks thick (z 0..7), a perfectly flat solid slab with straight vertical sides and no gaps. Dark volcanic basalt rock top in 3 shades of charcoal grey crossed by a network of 1-2 block wide glowing cracks of bright orange and yellow lava running across the surface; the sides are black rock with a few thin orange glowing veins. The lava cracks glow.
const paths = [
[[0,10],[7,10],[13,14],[20,14],[26,19],[34,17],[41,13],[48,10]],
[[0,32],[8,29],[16,32],[22,31],[29,35],[38,30],[43,33],[48,32]],
[[13,0],[12,8],[13,14],[17,23],[16,32],[19,40],[13,48]],
[[37,0],[35,8],[34,17],[38,24],[38,30],[35,40],[37,48]],
[[26,19],[25,25],[22,31]],
[[7,10],[5,18],[8,29]],
[[41,13],[45,22],[43,33]]
];
// Repeat the crack paths across tile boundaries so opposite edges match.
function crackDistance(x, y) {
let best = Infinity;
for (const path of paths) {
for (let i = 1; i < path.length; i++) {
for (let ox = -48; ox <= 48; ox += 48) {
for (let oy = -48; oy <= 48; oy += 48) {
const ax = path[i-1][0] + ox, ay = path[i-1][1] + oy;
const bx = path[i][0] + ox, by = path[i][1] + oy;
const dx = bx - ax, dy = by - ay;
const t = Math.max(0, Math.min(1,
((x - ax) * dx + (y - ay) * dy) / (dx*dx + dy*dy)));
best = Math.min(best, Math.hypot(x - ax - t*dx, y - ay - t*dy));
}
}
}
}
return best;
}
const distances = [];
for (let x = 0; x < 48; x++) {
distances[x] = [];
for (let y = 0; y < 48; y++) {
const d = crackDistance(x, y);
distances[x][y] = d;
// Every column is filled: a flat, solid, eight-block-thick tile.
for (let z = 0; z < 7; z++) {
let color = z < 2 ? "#171a1e" : "#202329";
if (x === 0 || x === 47 || y === 0 || y === 47)
color = z < 2 ? "#121417" : "#1b1e22";
if (rand() < 0.035) color = "#262a2e";
set(x, y, z, color);
}
let top = rand() < 0.18 ? "#41454a" : "#35393e";
if (rand() < 0.09) top = "#2e3237";
if (d < 2.1) top = "#292c30"; // dark lip around each glowing fissure
set(x, y, 7, top);
}
}
part("lava", [24, 24, 7]);
const orange = "#ff5a00", amber = "#ff9a1f", yellow = "#ffd23f";
for (let x = 0; x < 48; x++) {
for (let y = 0; y < 48; y++) {
const d = distances[x][y];
if (d < 0.82) {
set(x, y, 7, d < 0.36 ? yellow : (rand() < 0.6 ? amber : orange));
}
}
}
// Narrow veins descend from matching crack openings on all four sides.
for (let z = 3; z <= 6; z++) {
const drift = z <= 4 ? 1 : 0;
for (const seam of [10, 32]) {
const v = seam + drift;
for (const x of [0, 47])
set(x, v, z, z === 6 ? amber : orange);
}
for (const seam of [13, 37]) {
const v = seam + drift;
for (const y of [0, 47])
set(v, y, z, z === 6 ? yellow : orange);
}
}
animate("lava", {
type: "colors",
palette: ["#ff5a00", "#ff9a1f", "#ffd23f"],
pattern: "noise",
glow: 0.8
});import { draw } from "./assets/voxel";
import { nivelLavaAgrietada } from "./assets/nivel-lava-agrietada";
// Every frame: standing on (x, y), the centre of its base.
draw(ctx, nivelLavaAgrietada, 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-lava-agrietada
# With Fogón's tools (connector)
add_assets({ slug: "<your-game>", ids: ["nivel-lava-agrietada"] })
# It lands in client/assets/nivel-lava-agrietada.ts
# https://fogon.page/object/nivel-lava-agrietada