Products

Pearl Diver

A one-tap browser game. One mechanic, tuned until it felt right.

The Pearl Diver title screen: the game’s wordmark over a dark underwater scene, above Dive and Skin shop buttons.

The brief

A game with exactly one input. You tap to swim up, gravity does the rest, and everything else — coral to thread, pearls to collect, a shop of skins to spend them in — hangs off that single verb.

The point of building it was feel. A one-tap game has nowhere to hide: if the physics are half a beat wrong, no amount of art rescues it.

The constraints

  • It has to run instantly in a browser. No install, no loading screen, no engine download — a link someone opens and is playing within a second.
  • The same code plays with a thumb and with a keyboard. Tap, click and space are the same input.
  • Progress has to survive a closed tab without an account, since asking someone to sign up to a one-tap game is how you lose them.

The decisions

Tuning was the work; the feature list was not

Gravity, impulse, gap size and scroll speed are four numbers, and almost all of the build was moving them against each other until failure felt like a mistake rather than an ambush. Nothing was added to the game until those four numbers were right.

What it costs: a long stretch of work with nothing visibly new to show for it. It is also the only reason the game is worth playing twice.

The shop spends attention, not money

Collected pearls buy cosmetic skins. There is no currency purchase, no advertisement, no timer that resolves itself if you pay. The reward loop exists to give the score a use, and it stops there.

What it costs: no revenue model at all — which for a portfolio piece is the correct answer.

Everything is drawn, nothing is loaded

The diver, the coral, the light shafts and the fish are drawn to a canvas at runtime rather than shipped as sprite sheets. The whole game is a single page with no asset pipeline behind it.

What it costs: a ceiling on visual complexity. In exchange it loads instantly and there is no build step to maintain.

Built with

  • Vanilla JS
  • Canvas 2D
  • requestAnimationFrame
  • localStorage
  • Cloudflare Pages