Skip to content

~/projects / perplex-image

PerplexImage

Image puzzle game: pick a photo, rearrange the tiles with drag and drop and beat your own time and move count.

role
sole author: gameplay, state, API proxy, tests
time
Feb 2024 – May 2026
type
personal
stack
Nuxt 3 · TypeScript · Pinia · Tailwind · Supabase · Vitest · Playwright
demo.mp4
[demo video: screen recording, 1–3 min]

01 / problem

A puzzle that works on every screen

Drag-and-drop puzzles are easy to build for a mouse and awkward everywhere else. The goal was a game that plays the same on mobile, tablet and desktop and never runs out of images to solve.

02 / solution

Tile puzzles on three difficulty levels

Players choose an image from the Pexels API, pick a level (9×13, 15×23 or 20×30 tiles) and drag pieces into place while a timer and a move counter run. The game can be paused and reset, and it shows progress. Pinia holds the game state; a Nitro server route proxies Pexels so the API key stays on the server, and an adapter for Supabase storage exists next to the Pexels one.

  • [screenshot 1]

    [caption]

  • [screenshot 2]

    [caption]

03 / architecture

How it works

Nuxt 3 with the Vue 3 Composition API, split into modules: core (shared utilities, store, types), game (pages, components, logic) and ui (generic components). Server routes under /server/api fetch images behind an adapter interface. Vitest covers units, Playwright covers end-to-end flows and Husky pre-commit hooks run the linter.

04 / results

Outcome

05 / lessons

What I learned

  • Keeping game logic in its own module, apart from generic UI components, keeps it testable with plain unit tests.
  • The image source sits behind an adapter, so Pexels and Supabase storage are interchangeable for the game.

gallery

  • [photo]

    [caption]

  • [photo]

    [caption]

  • [photo]

    [caption]