Work / 06 of 06

Portfolio island

3D web game · walkable portfolio

A portfolio you can walk around: a low-poly island where every project has a house in the market and a minigame of its own.

Visit Portfolio island
Role
Solo: game design, 3D, physics and front end
Years
2026
Status
Live, built for desktop; phones partly supported
Stack
React Three Fiber · Three.js · Zustand
Portfolio island on desktop and mobile

The brief

A CV page tells you what someone built. I wanted one that lets you play it. The island is my portfolio as a small game: walk up to the house, the campfire or the notice board to read about me, and step into a project's house in the market to play a minigame made as a tribute to it. It still has to work as a portfolio, so the same content loads first as a plain card that search engines can read, and there is a flat overview for anyone who just wants the facts.

What I built

  • A low-poly island in React Three Fiber, laid out as plain data (shoreline, paths, landmarks and seeded prop placement) that the scene, collisions, ground texture, minimap and map all read.
  • Two vehicles: a skateboard with real ollies that lands on low props and rides along them, and a go-kart with a two-axle tyre model, handbrake drifts, skid marks, smoke and grass that it flattens as it drives.
  • Five minigames, one per project: melt-me's candle workshop, food-lib's spaghetti kitchen, workout-lib's idle-tycoon gym, Coach's rooftop rhythm workout and pokehelper's real-time Pokémon battle.
  • Partial phone support: it is designed for a keyboard and a big screen first, but on a phone held sideways it plays with touch controls (joystick, A and B buttons, a kart you steer by pointing) and a pared-down HUD so the small view stays clear.
  • A server-rendered landing card with Open Graph tags, JSON-LD, a sitemap and llms.txt, all generated from the same content file as the island.

Inside

Decisions

  1. 01

    Text first, island second

    The landing card is rendered to HTML at build time and painted before any 3D code loads. The app and Three.js are imported only after the first contentful paint, minigames are fetched in the background once a visitor sets off, and shaders are compiled one task at a time so the first frame never freezes the page. Without a GPU the island waits until Explore is pressed, and without WebGL the site falls back to the card and an overview.

  2. 02

    A kart that drifts like one

    The kart runs a two-axle tyre model in 240 Hz substeps: slip angles give each axle its sideways force up to its grip, and the rear shares grip with the engine and brakes. A held drift swaps to a kinematic slide whose arc stays the same at any speed, with the tail on a damped spring and the wheels countersteering by themselves, so a drift starts and ends without a jolt.

  3. 03

    Controls that follow the camera

    The camera always faces north. Steering relative to the kart flipped the controls whenever it drove towards the screen, which felt broken on a phone. On touch screens the stick now points where to go: the kart turns to head that way, drifts on its own through a sharp turn, and backs up when you point behind it.

  4. 04

    Games that are fair

    Each minigame teaches itself with a how-to-play screen, a checklist and a ring on the next station. The battle's rival was tuned by simulating thousands of fights against a bot. Its damage follows the main games' formula and type chart, scaled so a fight lasts about half a minute.

  5. 05

    Small over the wire

    Vercel's CDN doesn't compress .glb files, so the build brotli-compresses the models in place and serves them with the matching header: 5.6 MB of models arrive as 2.4 MB.