Inspiration

Solo "vibe coders" live in a tight loop with their tools. We wanted a game about that life — and we wanted the cloud database, usually invisible plumbing, to be the star. What if you could watch your database respond while you play?

What it does

Glass Box Runner is a browser endless-runner with one twist: the database is the game. When a run ends, the score is submitted to Amazon DynamoDB and the API route measures the real write latency and returns it. The game shows it on screen — judges literally watch their own database respond in single-digit milliseconds.

The same transparency drives the anti-cheat. Because the game is deterministic, the server re-derives whether a score is physically possible; impossible runs are rejected live (422, with the reason shown in the UI).

How we built it

  • Frontend / game: HTML5 Canvas 2D, no engine, fully deterministic (seeded RNG).
  • App + API: Next.js (App Router) deployed on Vercel; the game posts each run to /api/run/submit.
  • Database: Amazon DynamoDB (ap-northeast-2), single-table design + one GSI, accessed via @aws-sdk/lib-dynamodb. Every access pattern is a single Query/Get — no scans.

Database design — Track 3 (Million-Scale)

One table, one index. Keys are shaped so reads are native Top-N queries:

Entity PK SK
Daily leaderboard DAILY#<date>#<diff>#<shard> SCORE#<zeropad>#<uid>
All-time ranking (GSI1) GLOBAL#<diff> SCORE#<zeropad>#<uid>
User best (drives GSI1) USER#<uid> BEST#<diff>
User run history USER#<uid> RUN#<ts>
Ghost replay GHOST#<runId> INPUT
Live concurrency LIVE#<date> SESSION#<uid> (TTL)
Daily quests USER#<uid> QUEST#<date>

Scores are zero-padded to a fixed 10-digit width, so lexicographic SK order is numeric score order — Top-N is a native Query, no server-side sorting.

Hot-partition mitigation — 10-way write sharding. A naive DAILY#date#diff key funnels every player on a day into one partition, which caps at ~1000 WCU and throttles at scale. We shard the write by djb2(uid) % 10DAILY#date#diff#<0..9> (~10,000 WCU ceiling) and read with scatter-gather: one parallel Query per shard for Top-N, then merge. Rank is a Select=COUNT per shard, summed — it never reads items.

Write resilience. Each submit is a 3-item BatchWrite; leftover UnprocessedItems under throttling are re-sent with exponential backoff (50→800 ms), so no score is lost.

GSI write economy. A single conditional Update keeps exactly one best-score item per user in the global ranking, so GSI writes scale with "best improved," not "every run."

Design — the front-end and back-end are one idea

The "glass box" is a UX principle, not just a backend trait. Server state that is normally invisible is surfaced inside the game: the real DynamoDB write latency, your live rank the instant you submit, the current number of live runners, and the anti-cheat verdict when a run is rejected. Front-end and back-end share one design — the game is deterministic, and the server re-uses that exact determinism to verify scores, so full-stack consistency is there by construction. There is no login wall either: an anonymous id lets you compete instantly.

Why it matters (impact)

This is not a demo that merely talks to a database; it is a live service on production-grade infrastructure — DynamoDB, Vercel, anti-cheat, and rate limiting all running in the open. It also makes an abstract, hard-to-teach idea tangible: most developers never see how a database behaves under scale. Glass Box Runner turns hot-partition sharding and write latency into something you watch while you play — useful to solo builders shipping their first scalable backend, and to anyone learning how single-table DynamoDB actually works.

Challenges we ran into

  • The daily leaderboard was a textbook hot partition — solved with deterministic write sharding + scatter-gather reads.
  • BatchWrite silently drops throttled items into UnprocessedItems — added a backoff retry loop so writes are lossless under load.

What we learned

At million-scale, the partition key is the architecture. Designing keys around access patterns up front — sharding, zero-padded sort keys, COUNT-only rank — is what keeps it cheap and throttle-free.

What's next

A live load run (CloudWatch proof of the sharded write spread) and a hidden-boss daily quest loop that resurrects yesterday's #1 ghost.

Built With

Share this project:

Updates