pickuma.
Infrastructure

Eleven Browser Games in a Week — What a Design System Buys You

play.pickuma.com now has eleven games. After the first two, the bottleneck was no longer game logic — it was the chrome around each game. Here's the design system that made the next nine fast.

6 min read

A week ago play.pickuma.com had two games. As of today it has eleven. The new nine took less wall-clock time per game than the first two did — by a wide margin. The interesting part wasn’t the game logic. It was the chrome.

The eleven

In order of build time, fastest first:

  • Reaction — wait for green, click ASAP, five rounds median. 1 hour.
  • Numbers — Schulte table, click 1 to N in order on a shuffled grid. 2 hours.
  • Color Match — a hex code, twelve swatches, pick the matching one. 2 hours.
  • Color Echo — Simon-style memory, every round adds one. 3 hours.
  • Perfect Square — draw a closed square in one stroke; we compute corner angles and side ratios. 4 hours.
  • Stack — drop a moving block on a tower; misaligned edges fall off. 4 hours.
  • Knife Hit — throw knives at a rotating target; don’t clash with knives already stuck. 5 hours.
  • Crossing — Frogger-style endless lane crossing, one button to step. 5 hours.
  • Paper Plane — Flappy-style one-button side-scroll. 5 hours.
  • Stop at 7.77 — hidden timer, stop at exactly 7.77 seconds. 8 hours. (Was first; spent more time on the dot animation than the timer logic.)
  • Eagle Run — third-person 3D-ish flight survival on canvas 2D. 2 days. (Also first; complex projection logic.)

Eleven games. Two days of game logic. The rest was shared infrastructure that paid back nine times over.

What’s shared

After the first two games shipped, I extracted a DESIGN.md — well, a private one — codifying everything every game needed. The pattern is the same one shadcn-ui uses for its component library: name what’s shared, name what’s per-instance, write down the contract.

Per-instance: one CSS variable

Each game gets one signature accent color via --game-accent. Stop at 7.77 is blue, Eagle Run is amber, Numbers is mint, Crossing is orange. Inside each game route:

<section style="--game-accent: #34d399">
<!-- everything inside derives from this -->
</section>

Buttons, score color, hover states, OG image, particles — all reference var(--game-accent). To brand a new game I write the hex once.

Shared: everything else

The same code handles every game’s:

  • HTML structure (header strip, stage area, overlay card, share panel)
  • Buttons (.btn-pill for primary action, .btn-rect for secondary chrome)
  • Motion curve (cubic-bezier(0.16, 1, 0.3, 1) at 180ms, site-wide)
  • Score readouts (JetBrains Mono Variable, tabular numerals, font-variant-numeric: tabular-nums)
  • Bouncing dot animation (used by Stop at 7.77’s hard mode, available to anyone)
  • Stage backdrop (dot-grid radial-gradient pattern)
  • Result reveal (220ms spring-out keyframe)

Pick up the per-instance variable, drop in your game’s mechanics, ship.

What the games share at the JS level

Every game has the same five things:

  1. A state machineidle → playing → result (sometimes menu → playing → dead).
  2. A performance.now() clock for any time-sensitive measurement.
  3. localStorage personal bestlocalStorage.setItem('<game>-best', value).
  4. A share functionnavigator.share with clipboard fallback, same string template across games.
  5. Three GA4 eventsplay_start, play_end, share_click, with consistent param names so all eleven funnels are comparable.

Once those five are stamped, the only original code in a new game is the loop in the middle: spawn obstacles, accept input, compute score. Eagle Run’s was 290 lines. Reaction’s was 60.

Builds and OG images

Both projects (pickuma.com and play.pickuma.com) are Astro 6 → Cloudflare Workers + Static Assets. The play project’s build runs three things in order:

Terminal window
bun scripts/gen-og.ts # render 11 PNGs from SVG templates
astro build # static site generation
bun scripts/post-build-patch.ts # inject SESSION KV id

Each OG image is a 1200×630 PNG rendered server-side at build time via @resvg/resvg-js. Template-driven: I describe a game with { slug, accent, display, title, tagline, url } and the renderer produces a card with the game accent glow, the dot-grid backdrop, and the title block. Eleven cards generate in under a second total. No edge function, no dynamic OG, no infra to maintain.

What it cost

Eleven games, each with:

  • One Astro page (averaging 50 lines)
  • One JS file (averaging 200 lines)
  • One pre-rendered OG image
  • One spot on the hub grid
  • One row in the itch.io upload script
  • Three GA4 events
  • A Cmd+Click away from running locally

Total disk: 4,200 lines of code across pickuma-play/. Total commit count: 19. Wall clock from git init to game 11: 9 days.

The interesting unit economics: the first game cost a day. The last three games cost a half-day each. The design system absorbed every cost that didn’t have to be repeated.

Try them

The full hub is at play.pickuma.com. All eleven are mobile-friendly (touch is mapped where it makes sense), all are free, none ask for an email.

If you build something on a similar stack, send it. I’d particularly like to see what happens if someone applies this design-system-first pattern to a single deeper game instead of a wide portfolio of shallow ones.

Related tools

Some links above are affiliate links. We may earn a commission if you sign up. See our disclosure for details.