Project · Public

🕹️ Arcade

A small games hub — a growing shelf of self-contained browser games, built one weekend at a time. No accounts, no downloads, no tracking, just pick a cartridge and play.

What it is

One repo, many cartridges

Every game lives at its own URL as a single self-contained HTML file — its own inline <style> and <script>, nothing shared beyond one small embed script. Land on the front page and pick a card; there's no login, no install, no data collected about you.

30+
Games Live
0
Accounts / Sign-ups
0
Build Step
1
Optional Worker
How it's built

Static by design

No framework, no package manager, no database. The whole site is plain HTML/CSS/JS, deployed straight from the repo — a deliberate constraint that keeps every game easy to drop in and easy to reason about on its own.

A landing page that's just data

The homepage renders every "cartridge" card — name, tagline, emoji, gradient, tags — from a single GAMES array in its inline script. Shipping a new game is: drop the folder in, add one object to the array, done. No template engine, no build step re-runs.

Vanilla JSData-driven cards

Shared chrome, not a shared framework

Every game pulls in one script, assets/game-embed.js, which injects the top nav bar ("← All games") and a support link — without any per-game CSS or markup. It's the only thing games have in common; everything else in a game folder is free to do its own thing.

One embed script

An optional play-count counter

A small Cloudflare Worker (src/worker.js) backs a single KV namespace tracking how many times each game's been played, read back on the homepage as "Played N times." It's genuinely optional — if it's not wired up, the fetch calls fail silently and every game still works exactly the same.

Cloudflare WorkerKV storage

Ship on push, no manual deploy

Cloudflare Workers Builds watches master and deploys automatically on every push — no local wrangler deploy, no separate release step. A game isn't really done until it's merged to master; a feature branch alone never reaches the live site.

Auto-deploy
Design principles

Rules every game follows

A few constraints repeat across all 30+ games, mostly learned the hard way while building for a phone-first audience.

Mobile-first, not mobile-adapted

Nothing that says "this is clickable" or "here's how you go back" may rely on :hover — touch devices never trigger it, so borders, glows and badges on interactive elements have to be visible at rest, not just on interaction.

Consistent Easy/Hard, not per-game guesswork

Every reflex/arcade game exposes an Easy and Hard mode, and "harder" always means retuning spawn and reaction parameters — never removing the safety margin that keeps a run physically fair. Ramps always have a hard cap; procedurally placed hazards are spaced using the player's real jump arc or lane count, so nothing is ever unreachable by construction.

A version string you can actually check

assets/version.js is the single source of truth for a displayed version and date, shown in the homepage footer and every game's nav bar — a quick way to confirm you're looking at the latest deploy rather than a stale cached copy.

Built with Claude Code. Each game — physics, difficulty tuning, mobile-fit quirks and all — has been built and iterated on with Claude Code, with the repo's own CLAUDE.md capturing the patterns and past bugs so the next game session starts from what was already learned, not from scratch.

Go on, play one

New games get added when they're ready, not on a schedule — check back for more cartridges.

Play the Arcade ↗