TerminalTrajectory
completedA 2D space shooter that runs entirely in the terminal, with a from-scratch physics engine doing the gravity, momentum, and collisions in ASCII.
the problem
Most "physics game" tutorials let the engine do everything and skip the part where you actually have to think about Euler integration, collision response, and frame timing. I wanted to build the engine, not configure it — and a terminal renderer was the constraint that forced me to keep the physics honest, because a sloppy simulation looks broken when every cell is one of 80×24 ASCII characters.
the approach
- Physics core — a small 2D engine with gravitational forces between objects, semi-implicit Euler integration, AABB + circle collision detection, and momentum-conserving collision response. Numpy for the vector math.
- Renderer —
cursesfor terminal manipulation, with an ASCII particle system for thrust, explosions, and projectile trails. Subpixel positions get rounded to character cells only at draw time, so motion stays smooth. - Game loop — fixed-timestep update (60 Hz physics) decoupled from render, the canonical Glenn Fiedler pattern. Stops physics from going weird on slow terminals.
a hard decision
Decoupling the physics tick from the render tick. Single-loop is shorter to write, but on a slow terminal it makes orbits visibly drift, which betrays that the physics isn't physical. Implementing the fixed-step loop took a weekend of debugging interpolation, and made the game look correct on every machine I tried.
what came out
A playable terminal game with believable physics. The most useful thing I got out of it isn't the game itself — it's the gut feel for why every game engine I've used since structures its main loop the way it does.
stack
python · numpy · curses · custom 2D physics engine