not-cool

A collection of 8 classic pathfinding algorithms — built as interactive visualizations for the TIC-80 fantasy console · by whichxjy

They're not COOOOOOOOOOOOOOOOOL.

About

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.

Lua TIC-80 Pathfinding Algorithms Visualization Education

Demo

Watch the algorithms navigate the maze in real time:

Animated demo of pathfinding algorithms in TIC-80

Algorithms

Eight algorithms are included, spanning both informed (heuristic-driven) and uninformed (exhaustive) search strategies:

A* Search

Informed

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 queue

Breadth First Search

Uninformed

Explores 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 queue

Bidirectional BFS

Uninformed

Runs 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 queues

Depth First Search

Uninformed

Recursively 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 stack

Dijkstra's Algorithm

Uninformed

Finds 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 scan

Greedy Best First Search

Informed

Expands 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)

Iterative Deepening A*

Informed

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 limit

Iterative Deepening DFS

Uninformed

Runs 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 limit

Repository Structure

Each algorithm lives in its own directory with three files: the Lua cartridge, a shared sprite sheet, and a maze map.

not-cool/
├── README.md ← project documentation
├── demo.gif ← animated preview
├── index.html ← this page
├── A-Star/
│ ├── a-star.lua
│ ├── sprites.gif
│ └── world.map
├── BFS/ ← same structure
├── BiDirBFS/
├── DFS/
├── Dijkstra/
├── GBFS/
├── IDA-Star/
└── IDDFS/
Note: The 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.

Usage

Getting an algorithm running in TIC-80 is straightforward:

  1. Launch TIC-80 and open the code editor.
  2. Choose an algorithm — copy its .lua file into your TIC-80 working directory.
  3. Add dofile('xxx.lua') as the first line in the editor.
  4. Import sprites.gif (spritesheet) and world.map (maze layout), or draw your own map.
  5. Run the cartridge and use the keyboard to interact.

Controls

Once the cartridge is running, you can move the start and goal cells around the maze:

ActionKeyDescription
Control "C"ZSelect / confirm — switch control to the start cell
Control "L"XSwitch control to the goal cell
Move UpMove the active cell up (avoids walls)
Move DownMove the active cell down
Move LeftMove the active cell left
Move RightMove the active cell right
Tip: Change the start and goal positions to see how each algorithm adapts its search strategy to different maze layouts.

Comparison

Algorithm Category Data Structure Optimal? Grid
A* SearchInformedBinary heap28×28
BFSUninformedFIFO queue28×28
Bidirectional BFSUninformedTwo FIFO queues28×28
DFSUninformedRecursive stack28×28
DijkstraUninformedGrid min-scan28×28
Greedy Best-FirstInformedMin-heap (h only)28×28
IDA*InformedDFS + f-cost limit28×28
IDDFSUninformedDFS + depth limit28×15

Technical Notes