← Fantasy3D assetfogon/slime
Slime
Drag to turn it// «Slime» · gpt-6-sol (medium)
// A cute slime monster, one single smooth gooey blob and nothing else: a wide rounded dome about 30 blocks wide and 22 tall, like a big gumdrop or a drop of jelly, flatter and slightly spread at the bottom. Bright lime green with a lighter yellow-green top and two small white shine highlights, darker green along the bottom edge. Its face is on the FRONT (the -y side, facing the viewer): two big glossy black oval eyes with white shine dots, close together at mid height, and a small happy open pink mouth below them. No antennae, no lines, no ears, nothing sticking out of the top. Two tiny green droplets on the floor beside it.
// The bouncing gumdrop
part("slime", [24, 24, 0]);
function radii(z) {
const t = (z - 4) / 19;
const dome = Math.sqrt(Math.max(0, 1 - t * t));
return {
rx: z < 4 ? 14.5 + z * 0.38 : 16 * dome,
ry: z < 4 ? 12.5 + z * 0.38 : 14 * dome
};
}
function frontY(x, z) {
const { rx, ry } = radii(z);
const f = Math.sqrt(Math.max(0, 1 - ((x - 24) / rx) ** 2));
return 24 - Math.floor(ry * f);
}
// A solid, softly rounded body, slightly squashed and spread at its base.
for (let z = 0; z <= 22; z++) {
const { rx, ry } = radii(z);
for (let x = 7; x <= 41; x++) {
for (let y = 9; y <= 39; y++) {
const d = ((x - 24) / rx) ** 2 + ((y - 24) / ry) ** 2;
if (d > 1) continue;
let color;
if (z <= 2) color = "#4b9d25";
else if (z <= 5) color = "#69c92e";
else if (z >= 17) color = "#bafa55";
else if (z >= 12) color = "#a5ed43";
else color = "#8fe239";
if (y > 27 && z < 17) color = z < 6 ? "#62bc2d" : "#87d638";
if (rand() < 0.045) color = z >= 14 ? "#c5fc65" : "#a5ed43";
set(x, y, z, color);
}
}
}
// Two large, close-set, glossy oval eyes on the front.
for (const cx of [20, 28]) {
for (let x = cx - 3; x <= cx + 3; x++) {
for (let z = 10; z <= 16; z++) {
if (((x - cx) / 2.35) ** 2 + ((z - 13) / 3.35) ** 2 > 1) continue;
const y = frontY(x, z) - 1;
set(x, y, z, "#173620");
set(x, y - 1, z, z <= 11 ? "#25412b" : "#101d1b");
}
}
set(cx - 1, frontY(cx - 1, 15) - 3, 15, "#ffffff");
set(cx, frontY(cx, 14) - 3, 14, "#e8fff3");
}
// Little open smile, with a bright pink tongue.
for (let x = 21; x <= 27; x++) {
for (let z = 5; z <= 9; z++) {
const shape = ((x - 24) / 3.15) ** 2 + ((z - 7.5) / 2.35) ** 2;
if (shape > 1) continue;
const y = frontY(x, z) - 2;
set(x, y, z, "#69294c");
if (shape < 0.67) set(x, y - 1, z, z <= 6 ? "#ff77a1" : "#b43870");
}
}
for (let x = 23; x <= 25; x++)
set(x, frontY(x, 6) - 3, 6, "#ff9ab5");
// Two soft glints on the jelly itself.
for (const [x, z, color] of [
[15, 17, "#f1ffd0"], [16, 18, "#ffffff"],
[17, 19, "#f1ffd0"], [18, 19, "#e5ffad"],
[31, 17, "#efffc5"], [32, 18, "#ffffff"],
[32, 19, "#e5ffad"]
]) {
set(x, frontY(x, z) - 1, z, color);
}
animate("slime", { type: "bob", axis: "z", speed: 3, amplitude: 1.5 });
// Two tiny droplets remain on the floor while the slime bounces.
part("body");
ellipsoid(5, 24, 0, 2, 2, 1, "#65c52f");
set(5, 23, 1, "#b9f46a");
ellipsoid(43, 26, 0, 2, 2, 1, "#71d437");
set(43, 25, 1, "#c4fa76");import { draw } from "./assets/voxel";
import { slime } from "./assets/slime";
// Every frame: standing on (x, y), the centre of its base.
draw(ctx, slime, 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 slime
# With Fogón's tools (connector)
add_assets({ slug: "<your-game>", ids: ["slime"] })
# It lands in client/assets/slime.ts
# https://fogon.page/object/slime