Why I built my own game engine.
Five hobby games became one. Here's what I learned owning the whole stack — and why you might want to.
A platformer. A rally racer. Tetris. A stealth game. An F1 racer. Different on screen — but underneath I kept writing the same things:
Game six would start from zero again. Unless I stopped re-writing the spine and named it.
If the goal is to ship fast — a jam, a deadline, a client — reach for an engine, gladly. I didn't. On purpose.
I wanted to own every line, understand every part, and be able to teach it. Borrowed power you can't see inside isn't power you understand. This is a talk about the other road.
Your game's rules are a pure function:
// no clock. no randomness. no DOM. same inputs → same result. function tick(state, input) { return nextState; // a fresh state, every frame }
Everything else — the screen, the speaker, the gamepad, the network — is a thin shell wrapped around that function. The rules never touch the outside world.
Keeping the core pure looks like a constraint. It's the opposite — it buys you the two things that are hardest to get later:
// a run-tape: the seed + every input. replay() reconstructs the run exactly. {"frame":128, "type":"input", "data":{"held":"right,jump"}}
Each game had already solved one hard thing well. The engine is those solutions, generalised and pulled into one place — consolidation, not invention.
| smb | reading real NES ROMs — the structural archaeology of an old game |
| rally | pseudo-3D road projection + a track-builder language |
| tetris | full gamepad remapping, and local 2-player on one screen |
| stealth | anonymous playtest feedback + an A* solver that proves a level is beatable |
| redline | JSONL telemetry that doubles as a deterministic replay tape |
Thirteen small, single-purpose packages. A game pulls in only what it needs.
Stealth gave the engine the most — anonymous playtest feedback, and the crown jewel: an A* search that plays the real game through the same tick(). A route it finds isn't a guess — it's a proof the level is beatable, so all twenty hand-curated levels are certified winnable and fair. That solver became @lockstep/validation. (Level 17 is named "Lockstep" — the engine took its name from a level in this very game.)
So the engine has rules — and they're not polite suggestions:
So a machine checks it. One command, five gates — and a new game cannot be born missing any of them:
A cozy gamepad train-track toy. You lay chunky track, then watch your train roll the loop.
Designed in words first, built on the engine, playtested, and mirrored to its own repo. Nothing in the engine knows Trackbound exists — that's the whole point.
A pure function. Determinism. Documentation a machine enforces. These aren't game-dev tricks — they're how you reason about any system you want to trust.
And owned tooling compounds: the second game starts ahead of where the first ended; the third ahead of the second. The engine is where the lessons live — on purpose, documented for whoever comes next.
A jam. A deadline. A paying client. This road is the slow one — you trade speed now for understanding and tools that compound later. Know which one you're buying.
But if you want to understand your craft from the floor up: build the thing, own the thing.
Play them → davidslv.uk/games