A collection of 8 classic pathfinding algorithms — built as interactive visualizations for the TIC-80 fantasy console · by whichxjy
They're not COOOOOOOOOOOOOOOOOL.
not-cool is an educational project that brings eight classic search and pathfinding algorithms to life inside the TIC-80 fantasy console — a constrained retro environment with a 240×136 display and a 16-color palette. Each algorithm is a self-contained Lua cartridge that lets you move the start and goal cells through the maze and watch the search unfold in real time.
Written in plain Lua with no external dependencies, the code is compact, readable, and designed for learning. It's not cool — it's better: it's a hands-on way to explore how these algorithms behave when you can see them work.
Watch the algorithms navigate the maze in real time:
Eight algorithms are included, spanning both informed (heuristic-driven) and uninformed (exhaustive) search strategies:
Combines actual path cost (g) with a heuristic estimate (h) via f = g + h. Uses Manhattan distance and a binary-min-heap priority queue. The gold standard for grid-based pathfinding.
Binary heap priority queueExplores the grid level by level with a FIFO queue. Guarantees the shortest path in an unweighted graph by expanding all nodes at distance d before any at distance d+1.
FIFO queueRuns two simultaneous BFS searches — one from the start and one from the goal. When their frontiers meet, the path is reconstructed from the intersection. Can be significantly faster than standard BFS.
Two FIFO queuesRecursively explores as far as possible along each branch before backtracking. Visits cells in priority order: up, down, left, right. Does not guarantee the shortest path.
Recursive call stackFinds the shortest path by repeatedly selecting the unvisited node with the smallest known distance. Uses an O(n²) brute-force minimum scan rather than a heap (edges are uniform weight, so functionally equivalent to BFS on this grid).
Full-grid min scanExpands nodes in order of Manhattan distance to the goal only — no accumulated path cost. Very fast but not optimal; can take suboptimal routes if the heuristic is misleading.
Min-heap (heuristic only)Combines the memory efficiency of depth-limited DFS with A*'s f-cost heuristic. Iteratively increases the f-cost threshold, pruning branches where f = g + h exceeds the limit. Memory efficient.
Recursive DFS + f-cost limitRuns repeated depth-limited DFS searches with increasing depth limits. Combines DFS's low memory footprint with BFS's completeness on unweighted graphs. The grid here is 28×15 (420 cells).
Recursive DFS + depth limitEach algorithm lives in its own directory with three files: the Lua cartridge, a shared sprite sheet, and a maze map.
sprites.gif file is identical across all
eight directories. The maze layouts (world.map) come in
three variants — one unique to A*, one shared by BFS & DFS,
and one used by the remaining five algorithms.
Getting an algorithm running in TIC-80 is straightforward:
.lua file
into your TIC-80 working directory.
dofile('xxx.lua') as the first line in the editor.
sprites.gif (spritesheet) and
world.map (maze layout), or draw your own map.
Once the cartridge is running, you can move the start and goal cells around the maze:
| Action | Key | Description |
|---|---|---|
| Control "C" | Z | Select / confirm — switch control to the start cell |
| Control "L" | X | Switch control to the goal cell |
| Move Up | ↑ | Move the active cell up (avoids walls) |
| Move Down | ↓ | Move the active cell down |
| Move Left | ← | Move the active cell left |
| Move Right | → | Move the active cell right |
| Algorithm | Category | Data Structure | Optimal? | Grid |
|---|---|---|---|---|
| A* Search | Informed | Binary heap | ✓ | 28×28 |
| BFS | Uninformed | FIFO queue | ✓ | 28×28 |
| Bidirectional BFS | Uninformed | Two FIFO queues | ✓ | 28×28 |
| DFS | Uninformed | Recursive stack | ✗ | 28×28 |
| Dijkstra | Uninformed | Grid min-scan | ✓ | 28×28 |
| Greedy Best-First | Informed | Min-heap (h only) | ✗ | 28×28 |
| IDA* | Informed | DFS + f-cost limit | ✓ | 28×28 |
| IDDFS | Uninformed | DFS + depth limit | ✓ | 28×15 |
TIC() function is called
60 times per second — it handles keyboard input, runs the search,
and renders the grid, start, goal, and path.