A small, header-light 2D game engine for terminals built on ncurses. It exposes a tiny set of building blocks — Characters, Movements, and Relationships that client code composes into a game. The included game is a Breakout-style demo (src/main.cc) that exercises every part of the engine.
make # builds build/breakout
make run # plays interactively
make snapshot # prints a 25x80 text frame to stdoutControls: w / a / s / d to move the paddle. Ctrl+C to quit.
Requires a C++20 compiler and ncurses. On macOS with Homebrew the Makefile auto-detects /opt/homebrew/opt/ncurses.
src/ engine + game source
build/ objects and the breakout binary (created by make)
docs/ README screenshot
| Concept | Role |
|---|---|
Engine |
Owns characters and relationships; ticks the world and renders a top-down view |
Display |
Thin ncurses wrapper |
Character |
Abstract entity with X/Y/Z, health, attack, and a list of movements |
Movement |
Strategy applied each tick to mutate a character's position / visibility |
Relationship |
Pairwise interaction between two characters (collision rule, etc.) |
Concrete characters: SingleCharacter, RectangleCharacter, BitMapCharacter.
Concrete movements: StraightLine, UserInputMovement, HideMovement, UnhideMovement.
Concrete relationships: PassThrough, BounceOff, Battle.
The Z value is a draw-priority — higher Z wins overlap rendering, and characters at different Z values pass through each other.
src/main.cc is the example. The shape of any game is the same:
initscr()/noecho()/nodelay(stdscr, true)to set up ncurses.- Construct an
Engine(width, height). - Create characters, attach movements with
addMovement. - Wire up
BounceOff/Battle/ etc. relationships between pairs. - Call
engine.play().
./build/breakout --snapshot N runs N simulation ticks with no input and prints the resulting frame as plain text. The README screenshot above was rendered from such a snapshot.
