Skip to content
mdr
All work
prototype2025·personal

Mini-Games Collection

Classic arcade rebuilds: Snake, Pong, Pacman, Pinball, Sudoku, Minesweeper, Word Search, more. Same atomic React + GSAP architecture.

Screenshot of Mini-Games Collection

TL;DR

  • Eleven arcade classics rebuilt to one quality bar.
  • Pure engine + canvas/RAF renderer split — logic is testable, drawing is separate.
  • First-class controls everywhere: keyboard + mouse on desktop, swipe/drag + thumb-sized buttons on touch.
  • Persisted best scores; the page never scrolls out from under you mid-play.
  • Each game a Next.js static export, synced to public/games and embedded at /games/<slug>.

Architecture

Flow
INPUTPER-GAMEOUTPUTSITEKeyboard + mousedesktopTouch controlsswipe · thumb buttonsEnginepure · testableRenderercanvas · RAF · interpolationBest scorespersistedStatic exportNext.jsNext.js/games/<slug>embedded iframe

The per-game pattern, repeated eleven times. A pure engine feeds a RAF canvas renderer; a controls layer normalises keyboard, mouse and touch into the same inputs. Each game static-exports and embeds on the site by slug.

sync · HTTP / RPCdata · read / write

Problem

Browser reimplementations of arcade classics are usually either faithful-but-clunky or pretty-but-desktop-only. The genuinely hard version is a broad set of games that are all actually good — that feel alive, remember your best score, and play as naturally with a thumb on a phone as with a keyboard on a desktop — without the page fighting you by scrolling mid-swipe. Doing that once is a project; doing it eleven times needs a pattern.

Approach

Every game is the same shape: a pure, testable engine holding all the rules and none of the drawing, plus a renderer that runs the canvas on a requestAnimationFrame loop with interpolation for smoothness, plus a controls layer that maps keyboard and mouse on desktop and swipe/drag and thumb-sized on-screen buttons on touch. Best scores persist locally. Each title is its own Next.js static export, built independently and synced into public/games, then embedded on this site at /games/<slug>. Splitting logic from rendering is what makes the games testable and what lets one pattern carry eleven of them.

Deep dive

One engine pattern, many games

Eleven good games is only tractable if they share a shape. Each one splits into a pure engine — all the rules, no drawing, no clock, no DOM — and a renderer that owns the canvas. Because the engine is pure, it's directly testable: feed it inputs, assert on the resulting state, no browser required. Because the renderer is separate, the same loop structure (advance state, interpolate, paint) carries every title. The pattern is the product as much as any single game is; it's what let the collection go broad without each entry becoming a bespoke rewrite.

Controls that work on a phone

Mobile-first here means the touch controls are designed in, not degraded down from a keyboard build. On desktop you get keyboard and mouse; on touch you get swipe and drag plus thumb-sized on-screen buttons placed where a thumb actually rests. Both funnel into the same commands the engine already understands, so the game logic doesn't care where an input came from. And the page is held still during play — no scroll or zoom hijacking a swipe — which is the difference between a game that's playable on a phone and one that only technically loads there.

Static export, embedded per-slug

Each game is its own Next.js static export: a self-contained build with no server behind it, which is exactly what makes it safe to drop onto the site. The built output syncs into public/games, and the portfolio embeds each one at /games/<slug> in an iframe. That per-game boundary keeps the games independent of the site's own bundle and of each other — one can be rebuilt or replaced without touching the rest — while still letting them all live and play in one place.

Outcome

Live on-site. Eleven playable titles — Snake, Pong, Pacman, Pinball, Sudoku, Minesweeper, Word Search, Tetris, OXO, Color Match, Crossword — each rebuilt to the same bar: juicy visuals, persisted best scores, and first-class controls on phone, tablet and desktop, with the page held still during play. All embedded per-slug via static export.

Related

More in games.