← Fantasy3D assetfogon/circulo-de-runas
Círculo de runas
Drag to turn it// «Círculo de runas» · gpt-6-sol (medium)
// A magic summoning circle on the floor: a wide flat round platform of dark grey stone slabs, with a big glowing ring and a five-point star of light-violet runes inlaid in it, and five short standing stones around the edge, each with a carved glowing rune and a small floating crystal on top.
const C = {
stone: ["#41464a", "#484e51", "#51585a", "#5b6262"],
dark: "#30363b",
grout: "#353a3e",
edge: "#343b3e",
moss: ["#526c52", "#63805b", "#789363"],
gold: "#aa8650",
goldLight: "#d9b778",
violet: "#bb70ff",
bright: "#e3acff",
teal: "#77f7ed"
};
const cx = 24, cy = 24;
// A broad, low platform of individually shaded stone slabs.
for (let x = 3; x <= 45; x++) {
for (let y = 3; y <= 45; y++) {
const d = Math.hypot(x - cx, y - cy);
const rough = (rand() - 0.5) * 0.45;
if (d > 21 + rough) continue;
const shade = C.stone[Math.floor(rand() * C.stone.length)];
for (let z = 0; z <= 2; z++) {
set(x, y, z, z === 0 ? C.dark : shade);
}
if (d < 19.8) {
const joint = (x + 1) % 6 === 0 || (y + 2) % 6 === 0;
set(x, y, 3, joint ? C.grout :
C.stone[1 + Math.floor(rand() * 3)]);
} else {
set(x, y, 3, C.edge);
}
if (d > 19.6 && d < 20.5 && rand() < 0.13)
set(x, y, 4, C.gold);
}
}
// Brass studs and little breaks in the old outer binding.
for (let i = 0; i < 60; i++) {
const a = i * Math.PI * 2 / 60;
const x = Math.round(cx + 19.3 * Math.cos(a));
const y = Math.round(cy + 19.3 * Math.sin(a));
if (i % 3 === 0) set(x, y, 4, C.goldLight);
}
// Moss stays near the outer edge, leaving the magic legible.
for (let i = 0; i < 125; i++) {
const a = rand() * Math.PI * 2;
const r = 18.1 + rand() * 2.3;
const x = Math.round(cx + r * Math.cos(a));
const y = Math.round(cy + r * Math.sin(a));
if (get(x, y, 3) && rand() < 0.72)
set(x, y, 4, C.moss[Math.floor(rand() * C.moss.length)]);
}
// Five squat standing stones, evenly spaced around the circle.
const stones = [];
for (let i = 0; i < 5; i++) {
const a = i * Math.PI * 2 / 5;
const x = Math.round(cx + 18.5 * Math.sin(a));
const y = Math.round(cy - 18.5 * Math.cos(a));
stones.push({x, y, a});
box(x - 2, y - 2, 3, x + 2, y + 2, 4, C.dark);
box(x - 2, y - 2, 5, x + 2, y + 2, 8, C.stone[i % 3 + 1]);
box(x - 2, y - 1, 9, x + 2, y + 1, 10, C.stone[2]);
box(x - 1, y - 1, 11, x + 1, y + 1, 11, C.stone[3]);
// Rounded-looking stepped shoulders and a darker carved face.
set(x - 2, y - 2, 10, C.stone[1]);
set(x + 2, y - 2, 10, C.stone[1]);
box(x - 1, y - 3, 6, x + 1, y - 3, 9, C.dark);
set(x - 2, y - 2, 6, C.moss[1]);
set(x + 2, y + 1, 5, C.moss[0]);
set(x - 1, y, 12, C.gold);
set(x + 1, y, 12, C.gold);
}
// Small friendly fantasy mushrooms beside a few stones.
for (const i of [0, 2, 4]) {
const s = stones[i];
const x = s.x + (i === 2 ? -4 : 4);
const y = s.y + 1;
box(x, y, 4, x, y, 5, "#e9dcc2");
box(x - 1, y, 6, x + 1, y, 6, i === 2 ? "#cf81b3" : "#cf8b72");
set(x, y, 7, "#f0b99f");
}
// All inlaid light and carved runes share one flowing magical color cycle.
part("glyphs", [24, 24, 3]);
function ring(radius, step, z, color) {
for (let a = 0; a < Math.PI * 2; a += step) {
set(Math.round(cx + radius * Math.cos(a)),
Math.round(cy + radius * Math.sin(a)), z, color);
}
}
ring(15.7, 0.012, 4, C.violet);
ring(16.5, 0.019, 3, "#8958cf");
ring(14.9, 0.025, 3, "#8958cf");
// The pentagram is drawn as five long, unbroken luminous strokes.
const points = [];
for (let i = 0; i < 5; i++) {
const a = -Math.PI / 2 + i * Math.PI * 2 / 5;
points.push([
cx + 12.9 * Math.cos(a),
cy + 12.9 * Math.sin(a)
]);
}
for (let i = 0; i < 5; i++) {
const p = points[i], q = points[(i + 2) % 5];
line(p[0], p[1], 4, q[0], q[1], 4, 0.55, C.violet);
line(p[0], p[1], 3, q[0], q[1], 3, 0, C.bright);
}
// Glowing seals at the star's tips and short radial rune strokes.
for (let i = 0; i < 5; i++) {
const a = -Math.PI / 2 + i * Math.PI * 2 / 5;
const x = Math.round(points[i][0]);
const y = Math.round(points[i][1]);
set(x, y, 5, C.bright);
for (const side of [-1, 1]) {
set(x + Math.round(side * Math.sin(a)),
y - Math.round(side * Math.cos(a)), 4, C.teal);
}
const inner = 13.7, outer = 14.8;
line(cx + inner * Math.cos(a), cy + inner * Math.sin(a), 4,
cx + outer * Math.cos(a), cy + outer * Math.sin(a), 4,
0, C.bright);
}
// Little orbiting-looking dashes fill the space between star and ring.
for (let i = 0; i < 20; i++) {
const a = (i + 0.5) * Math.PI * 2 / 20;
const r = i % 2 ? 14.25 : 14.55;
set(Math.round(cx + r * Math.cos(a)),
Math.round(cy + r * Math.sin(a)), 4,
i % 2 ? C.teal : C.bright);
}
// Five different simple runes, carved into the viewer-facing stone faces.
for (let i = 0; i < 5; i++) {
const {x, y} = stones[i];
const fy = y - 4;
line(x, fy, 6, x, fy, 9, 0, C.bright);
if (i % 2 === 0) {
line(x - 1, fy, 8, x + 1, fy, 8, 0, C.violet);
set(x - 1, fy, 6, C.teal);
set(x + 1, fy, 6, C.teal);
} else {
set(x - 1, fy, 9, C.teal);
set(x + 1, fy, 9, C.teal);
line(x - 1, fy, 7, x + 1, fy, 7, 0, C.violet);
}
set(x, fy, 10, C.teal);
}
animate("glyphs", {
type: "colors",
palette: ["#a968ff", "#f176df", "#72eee9", "#d5a4ff"],
pattern: "wave",
glow: 0.9
});
// Suspended, faceted crystals all bob gently together.
part("crystals", [24, 24, 14]);
for (let i = 0; i < 5; i++) {
const {x, y} = stones[i];
const colors = i % 2
? ["#8351c7", "#b17aff", "#e6b5ff"]
: ["#398c9a", "#66dfdc", "#b2fff1"];
set(x, y, 13, colors[0]);
box(x - 1, y - 1, 14, x + 1, y + 1, 15, colors[0]);
box(x - 1, y - 1, 16, x + 1, y + 1, 16, colors[1]);
set(x, y, 17, colors[2]);
set(x - 1, y - 1, 15, colors[2]);
set(x, y - 1, 16, colors[2]);
}
animate("crystals", {type: "bob", axis: "z", speed: 2, amplitude: 1});import { draw } from "./assets/voxel";
import { circuloDeRunas } from "./assets/circulo-de-runas";
// Every frame: standing on (x, y), the centre of its base.
draw(ctx, circuloDeRunas, 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 circulo-de-runas
# With Fogón's tools (connector)
add_assets({ slug: "<your-game>", ids: ["circulo-de-runas"] })
# It lands in client/assets/circulo-de-runas.ts
# https://fogon.page/object/circulo-de-runas