How it was built

Building MathSprint

An entire arcade game — four modes, streaks, cloud leaderboards — delivered as one HTML file with zero dependencies. The engineering story is about what was deliberately left out.

  • JavaScript
  • HTML/CSS
  • Supabase
  • Zero dependencies

The idea

Mental math gets rusty without practice, and most practice tools feel like homework. MathSprint's design brief was an arcade run instead: instant to load, obvious in five seconds, and always worth "one more game." The technical constraint followed from that: nothing between the player and the game — no login, no framework payload, no build step.

Under the hood

One file, an entire app

Markup, styles, and logic live in a single HTML file. The six screens — home, instructions, game, results, leaderboard, credits — are .page sections toggled by a tiny hand-rolled router that flips an active class. Navigation is instant because nothing loads; the whole game arrived in the first request. It also makes the game absurdly portable: copy one file anywhere a browser runs, and it works.

Questions with honest traps

Problems generate on the fly per mode, and the two wrong choices are built to be plausible — near-misses like off-by-one sums or adjacent times-table values, not random numbers. That's what makes the one-attempt rule meaningful: with obviously wrong distractors, multiple choice would be a reflex test; with close ones, it tests whether you actually did the math.

A leaderboard that degrades gracefully

Scores post to a Supabase table through its REST API, queried per game mode and ordered by score. The notable engineering choice is the fallback: if the Supabase configuration is absent or unreachable, the game silently switches to browser localStorage. The leaderboard becomes device-local instead of global, but nothing breaks — the file even works fully offline.

Key design decisions

No framework, on purpose

For a game this size, React would add a build step, a dependency tree, and load time — and solve no actual problem. Vanilla JS keeps it instant and unbreakable by ecosystem churn.

Pick your pace

Long enough to build rhythm, short enough that "one more run" is always justifiable. The session length is the retention mechanic — and with 30-, 60-, and 90-second timers, every run counts on the leaderboard.

Generative audio, zero files

The soundtrack is synthesized live with the Web Audio API — a bass pulse and pentatonic melody whose tempo and layers ramp with the timer. No audio assets, so the whole game stays one dependency-free HTML file.

Three choices, one attempt

Multiple choice keeps pace high (no number typing); the single attempt keeps it honest. Keyboard shortcuts (1/2/3) reward players who commit.

Per-mode leaderboards

One combined board would just measure addition speed. Separate boards per operation make each mode its own competition — and division its own glory.

The Claude Code process

MathSprint was specified, built, and polished conversationally with Claude Code: the core loop first, then streaks, then the leaderboard with its fallback behavior, then feel — button states, timing, and the details that make a 90-second loop compulsive. As with every project on this site, the loop was build → play → critique → revise until it felt right to use, not just correct to read.

See it running