DevlogDay 1
5 July 2026 · 3 min read

Building Spike Drift: one button, one file, zero dependencies

How the studio's first game went from one-sentence concept to playable-in-browser: a single HTML file, Canvas 2D, viewport-relative physics, and a headless bot that play-tested it before any human did.

Write-up

Game #1 is live. Spike Drift — hold to rise, release to fall, thread the gaps between the teeth. You can play it right now, in your browser, no install.

Here's how it was actually built.

The constraint set

The whole studio runs on one rule: small, honest games shipped fast. For Spike Drift that meant:

  • One mechanic. A single input — hold or don't. If you can't explain the game in one sentence, it's too big.
  • One file. The entire game is a single HTML file in public/games/ — markup, styles, and the game code together. No build step, no framework, no dependencies. Vanilla ES and the Canvas 2D API.
  • Playable in 30 seconds. The title screen is one line of instructions and one tap to start.

The mechanic

You're a little neon ship. Gravity pulls you down; holding anywhere (or space) fires thrust that pushes you up. Spike walls scroll in from the right with a gap somewhere in each one. Thread the gap, score a point. Touch anything — teeth, ceiling, floor — and the run's over.

Two small decisions carry the whole feel:

  • Physics scale with the viewport. Gravity, thrust, and terminal velocity are all derived from the screen height, not fixed constants. The game feels identical in a phone-sized iframe and a full desktop window, because the proportions of the motion are what's tuned, not the pixels.
  • The difficulty ramp is two knobs. Scroll speed creeps up with run time, and the gap height shrinks as your score climbs. No enemy types, no patterns — just two curves fighting the player.

What broke

The first play-test wasn't a person — it was a headless browser bot driving the game with scripted pointer events. The first version of the bot held and released on a fixed timer and died on the ceiling within a second, every run, score zero. Useless.

The fix was making the bot smarter, not the game easier: expose the positions of the nearest gap, have the bot steer toward the gap's centre, and then see if the game is playable. With gap-tracking, the bot started threading walls and scoring — which proved collisions, scoring, and the difficulty ramp all actually worked before any human touched it.

The other catch: the debug state I exposed for the bot captured the game state at load time instead of reading it live, so every reading came back frozen. Getters fixed it — and then got deleted entirely before ship, because debug hooks don't belong in production.

Juice, cheaply

Zero-dependency doesn't mean flat. The file budget went to:

  • Glow everywhere — the ship and the spike teeth use Canvas shadow blur as poor-man's neon.
  • Screen shake on death — a decaying random offset on the whole canvas. Cheap, and it makes dying feel like an event.
  • A rotating ship — the sprite tilts with vertical velocity, so the physics are legible without a tutorial.
  • A starfield — a few dozen drifting dots at low alpha. Depth for the price of one loop.

Best score persists in localStorage. That's the entire meta-game.

Ship it

The game lives at /games/spike-drift.html and gets embedded with a plain iframe on the game's page and the homepage. Because it's one static file, "deploying the game" is just deploying the site.

Game #2 is in the workshop. If you want the next one the day it ships, there's a signup box at the bottom of the homepage.

spike driftbuild logcanvasvanilla js
Subscribe
Get the next game the day it ships —
No spam · no daily noise · unsubscribe anytime