Skip to content
← All work

SWARMGEDDON

A twin-stick survival shooter on a hand-rolled engine: fixed timestep, spatial hash, fully deterministic.

Private build TypeScriptPixiJSWebGLCapacitorPWA
SWARMGEDDON: A twin-stick survival shooter on a hand-rolled engine: fixed timestep, spatial hash, fully deterministic.

v1 content-complete: Endless and Daily modes, per-world personal bests. Code private.

The idea

I wanted the feel of Crimsonland in a browser tab: hundreds of enemies, screen-filling particles, zero loading screens. Off-the-shelf engines make that easy and heavy. I wrote the engine instead, and kept it honest: the whole game is TypeScript, PixiJS for WebGL rendering, and no physics library.

What I built

The simulation runs at a fixed 60 Hz, decoupled from rendering with interpolation, so gameplay is identical on a 144 Hz monitor and a tired phone. Collisions are circle overlaps against a hand-rolled spatial hash; entities live in object pools so a wave of two hundred enemies does not churn the garbage collector. All randomness flows through one seeded PRNG: a seed reproduces a run exactly, which is what makes the Daily Challenge fair for everyone playing the same date.

The audio engine is synthesized in WebAudio at runtime: every shot, hit, and music layer is generated, zero sound files shipped. Gore accumulates on a persistent render target, so the battlefield remembers the whole run without a per-frame cost. The fiction is data: 10 weapons, 15 enemies, 25 perks and a queen boss are content definitions, so reskinning the entire game touches no engine code. Capacitor wraps the same build for iOS and Android, with haptics, safe areas, and the back button isolated behind a platform seam.

The hard parts

01

Determinism versus juice

Screen shake, hit-stop, and splatter want randomness too, but cosmetic effects must never touch the simulation PRNG or seeded runs desync. Two random streams, one sacred, one decorative.

02

A thousand moving things at 60fps

The spatial hash keeps collision checks near-linear, pools keep allocation flat, and the persistent gore layer converts what would be thousands of particles into one texture. The frame budget is spent on gameplay, not bookkeeping.

03

One codebase, three platforms

Web PWA, iOS, and Android ship from the same build. The fixed timestep hides refresh-rate differences; the platform seam hides everything else.

What’s next

Store submission. The build, signing notes, and store assets are ready; it is a matter of pressing go.