The Math of Optimization

Q1K3, Dominic Szablewski’s 13KB homage to Quake, shipped as a 13,304-byte zip. The competition limit is 13,312 bytes, so it cleared the bar with eight bytes to spare. Inside: two levels, three weapons, dynamic lighting, a soundtrack, and a WebGL renderer written from scratch.

What made it fit wasn’t better zip settings. The game’s 31 textures would’ve cost around 150KB as PNGs; stored as tiny procedural recipes and drawn to canvas at load time, they cost about 1.3KB. The assets weren’t compressed so much as replaced by the code that generates them, and that swap is where the serious byte savings live.

Drop the framework, keep the math

Start a jam entry with a UI framework and a physics package and you’ve spent half the budget before writing a line of gameplay. The runtime cost is the part that follows you back to your day job: every abstraction between your inner loop and the JIT gets paid sixty times a second.

Plain arrays and vanilla loops are unreasonably fast. Q1K3’s collision map is a single bit-packed array covering a 128x128x128 grid, 262,144 bytes where a byte-per-cell layout needs two megabytes, and a hit test compiles down to a shift, an index, and a mask. Typed arrays keep that data contiguous, so the hot loop stays in cache instead of chasing object pointers around the heap.

The same arithmetic should kill the reflex to ship math off to a server. I’ve watched people fire a fetch() at an API to do work a for loop could’ve finished before the request even serialized. A round trip costs tens to hundreds of milliseconds; multiplying a few thousand floats locally costs microseconds. If the dataset fits in memory, the browser is the fast path.

Prediction is a client-side problem

Shifting from a 13KB game rendering pipeline to real-world statistical models doesn’t change the underlying physics of hardware. We have been conditioned to think that any application predicting live outcomes or processing high-velocity datasets requires a heavy, multi-tenant server cluster. But if your algorithmic footprint is optimized, lightweight inference handles beautifully right in the user’s browser tab.

While framework giants like TensorFlow.js or ONNX have made client-side machine learning accessible, we are starting to see practical, domain-specific implementations prove how lightweight this architecture can be. For instance, a platform like Shurzy runs its sports predictive modeling directly on the client side, bypassing database-heavy API roundtrips by evaluating probability matrices right in the user’s browser. By avoiding heavy framework overhead and relying on the client’s JIT compiler to do the math, the actual runtime footprint remains practically invisible.

Your enemy AI is already a probability engine

Game developers do predictive modeling all the time without calling it that. An enemy state machine is a weighted transition table: idle flips to patrol with some probability each tick, patrol snaps to attack when a raycast lands. Write those weights out in rows and columns and you’re holding a probability matrix.

Procedural generation leans on the same object from the other side. A dungeon generator that chooses the next room conditioned on the current one is sampling a Markov chain, whether or not the code ever uses the word. Q1K3’s texture tool is the idea in miniature: five drawing primitives plus noise, composed into flat arrays of numbers that rebuild all 31 textures at load time.

Pathfinding sits in the same family. The heuristic in A* is a prediction, an estimate of remaining cost that gets rewritten as the world changes underneath it. Tune enemy aggression by reweighting a transition table and you’re doing, at toy scale, what a production model does with bigger matrices and more input data.

Where that leaves your 13KB

None of this asks for cleverness so much as subtraction. Drop the dependencies and keep your data flat and typed; the engine will do the rest. Szablewski shrugs off his own brute-force collision checks in his making-of notes: “This is all terribly inefficient, but it doesn’t matter. CPUs are fast.” Two decades of JIT engineering are on your side, and 13,312 bytes is more room than it sounds.

🔙 Back to Articles list.