Grids — pathfinding & automata
A first-class 2-D cell grid — the one primitive under tilemaps, spatial pathfinding (space, not graph’s topology), cellular automata and Wave Function Collapse. Cells address like matrix/table ({id}.r{i}c{j}); seed a maze from a compact # . @ * ASCII string; the pathfinders reuse the algo kit’s exact colour grammar (discovered cyan → current magenta → done lime), and generation pre-simulates at build time then replays with run.
Each block is the whole file — copy it into x.manic and run manic x.manic (live) or --record out (video).
grid-astar
A* over a seeded ASCII maze: open cells flood by f-score (frontier cyan → current magenta), a live frontier/visited readout counts up, and the shortest route traces out in gold as {id}.path. neighbors picks 4- or 8-connectivity.
title("A* Pathfinding — Search Over Space");
canvas("16:9");
template("neon");
watermark(mark, (w*0.15, h*0.05), "Made With Manic");
// A cell grid seeded from a compact ASCII maze: `#` wall, `.` open, `@` start,
// `*` goal. A* explores the open cells (frontier cyan → current magenta), then
// the shortest route is traced in gold — the spatial sibling of the algo kit's
// graph search, sharing its exact colour grammar.
grid(g, "@ . . . . . . . ; # # # # # # . # ; . . . . . . . . ; . # # # # # # # ; . . . . . . . . ; # # # # # # # *", (cx, cy+20), 8, 6, 78);
neighbors(g, "4");
gridastar(g, (0,0), (7,5), manhattan);
draw(g.path, 1.4);
grid-life
Conway’s Game of Life: a glider seeded with setcell, then evolve pre-simulates six generations at build time (alive = a filled cell, Conway’s B3/S23) and run replays them — the glider walks diagonally across the grid.
title("Conway's Life — A Glider");
canvas("16:9");
template("neon");
watermark(mark, (w*0.15, h*0.05), "Made With Manic");
// A cellular automaton on the same cell grid. `step` pre-simulates one Conway
// generation at build time (alive = a filled `wall` cell, 8-neighbourhood);
// `run` then replays the stored generations. This glider walks diagonally.
grid(life, (cx, cy+10), 14, 12, 42);
setcell(life, 1, 2, wall);
setcell(life, 2, 3, wall);
setcell(life, 3, 1, wall);
setcell(life, 3, 2, wall);
setcell(life, 3, 3, wall);
evolve(life, "life"); evolve(life, "life"); evolve(life, "life");
evolve(life, "life"); evolve(life, "life"); evolve(life, "life");
run(life, 6, 5.0);
grid-wfc
Wave Function Collapse: collapse pre-simulates a seeded, neighbour-constrained settling row by row, then run replays the grid resolving from empty into a finished maze — deterministic, so the same seed always settles the same way.
title("Wave Function Collapse — A Maze, Settling");
canvas("16:9");
template("neon");
watermark(mark, (w*0.15, h*0.05), "Made With Manic");
// `collapse` pre-simulates a seeded Wave-Function-Collapse-style settling at
// build time — each cell is decided under its neighbours' constraints, one row
// at a time — then `run` replays the grid resolving from empty to a finished
// maze. Seeded, so it is fully deterministic (same seed ⇒ same maze).
grid(mz, (cx, cy+10), 20, 14, 30);
collapse(mz, "maze", 7);
run(mz, 14, 5.0);
grid-life-zoo
Conway’s Life’s whole taxonomy — a still life (Block), an oscillator (Blinker) and a
spaceship (Glider) — three grids seeded with setcell, evolved eight generations and
run in parallel: the Block holds, the Blinker flips, the Glider walks. The famous
pattern zoo, entirely in the grid kit.
// Conway's Life — the Zoo. img_4.png's taxonomy (still lifes / oscillators /
// spaceships) is nothing more than Conway's Life on a grid — which the grid kit
// already does: seed cells, `evolve` a few generations at build time, then `run`
// to replay them. Three grids run in parallel: a Block that never moves, a Blinker
// that oscillates, and a Glider that walks across its grid. No new kit needed.
title("Conway's Life — the Zoo");
canvas("16:9");
template("mono");
let u = (w+h-abs(w-h))/1440;
text(kicker, (cx, h*0.10), "STILL LIFE · OSCILLATOR · SPACESHIP — all just Conway's Life");
size(kicker, 22*u); color(kicker, dim); bold(kicker); wrap(kicker, w*0.9);
// --- Still life: Block (never changes) ---
grid(blk, (w*0.22, cy), 6, 6, 40);
setcell(blk, 2, 2, wall); setcell(blk, 2, 3, wall);
setcell(blk, 3, 2, wall); setcell(blk, 3, 3, wall);
text(blkL, (w*0.22, cy+180*u), "Block — still life"); size(blkL, 20*u); color(blkL, cyan);
// --- Oscillator: Blinker (period 2) ---
grid(bln, (w*0.5, cy), 6, 6, 40);
setcell(bln, 2, 1, wall); setcell(bln, 2, 2, wall); setcell(bln, 2, 3, wall);
text(blnL, (w*0.5, cy+180*u), "Blinker — oscillator (p2)"); size(blnL, 20*u); color(blnL, cyan);
// --- Spaceship: Glider (translates) ---
grid(gld, (w*0.78, cy), 8, 8, 34);
setcell(gld, 1, 2, wall);
setcell(gld, 2, 3, wall);
setcell(gld, 3, 1, wall); setcell(gld, 3, 2, wall); setcell(gld, 3, 3, wall);
text(gldL, (w*0.78, cy+180*u), "Glider — spaceship"); size(gldL, 20*u); color(gldL, cyan);
// Pre-simulate 8 generations of each (build time), same count so they replay in sync.
evolve(blk, "life"); evolve(blk, "life"); evolve(blk, "life"); evolve(blk, "life");
evolve(blk, "life"); evolve(blk, "life"); evolve(blk, "life"); evolve(blk, "life");
evolve(bln, "life"); evolve(bln, "life"); evolve(bln, "life"); evolve(bln, "life");
evolve(bln, "life"); evolve(bln, "life"); evolve(bln, "life"); evolve(bln, "life");
evolve(gld, "life"); evolve(gld, "life"); evolve(gld, "life"); evolve(gld, "life");
evolve(gld, "life"); evolve(gld, "life"); evolve(gld, "life"); evolve(gld, "life");
// Replay all three at once — the whole zoo, self-animating.
par {
run(blk, 8, 5.0);
run(bln, 8, 5.0);
run(gld, 8, 5.0);
}
wait(0.6);