A tilt-controlled space adventure for a bare ARM microcontroller and a 128×128 screen, written in C++ with no engine, starring a Dragon capsule and a Roadster with a dead battery.
It was Project 2 of ECE 2035, Georgia Tech's embedded systems class, in spring 2019. The course handed us a skeleton: pin setup, the outline of a game loop, a few interfaces. The game was up to us. On the last day of class, mine was featured as one of the best.
The theme is SpaceX's Starman, stranded in space with a dead Roadster. The only battery is in the Tesla Gigafactory on Earth, so you fly there, work through a two-door maze to get it, and bring it back. Then the Roadster reveals a secret power, blowing up asteroids, and you blast your way through the ring around Mars to land.
main() is a fixed 100 ms loop, so at most ten frames a second and one tile of movement per frame. Tilt the board far enough and you move one tile that way, if the tile is walkable.
The world isn't a 2D array. Each map is a chained hash table that stores only occupied cells, so empty space is just a lookup that returns NULL. XY_KEY packs x and y into one key, and the hash is key % 127.
Every MapItem carries a pointer to its own draw function, and the renderer never switches on type. It just calls item->draw(u, v). That turned every state change into a pointer swap: a floor button lights up, an asteroid explodes, Starman's tile becomes your empty capsule.
The screen hangs off a serial link, so every pixel costs time. The view is an 11×9 window of 11-pixel tiles, and each frame compares the MapItem pointer under every tile to the one there last frame. Same pointer, no draw. Flying through empty space mostly repaints the stars as they slide past.
Sprites are 121-character string literals, one character per pixel, so the art lives in flash and is sort of visible right in the source.
Over a serial link, the cheapest pixel is the one you never send.
Giving every map item its own draw function made "change how this looks" a one-line swap.
Storing only occupied cells kept memory proportional to what's actually on the map.
How long you sit on the title screen seeds the galaxy, no entropy hardware required.
NULL for empty space. Address 0 on this chip is readable flash, so it reads as walkable. It works for reasons nobody should rely on.main() again, so every playthrough nests one more frame on a 4 KB stack.deleteItem logs an error on every call, successful or not.