Skip to content
Games by Harring

Devlog, Engineering

Runish devlog: turning real GPS runs into a game

Devlog for Runish, my map-first running game — custom native Capacitor plugins for background GPS and HealthKit, Mapbox as a game board, and why async is the only honest multiplayer for runners.

Halfdan Harring

Halfdan Harring

Indie game developer · Aarhus, Denmark

Runish is the game where your legs are the controller: real GPS runs become moves on a map-shaped game board — routes claimed, stamps collected, times left for friends to chase. It’s also, by a comfortable margin, the most native engineering I’ve done in any game. Devlog below.

The design truth: running multiplayer must be async

A running game cannot ask two people to run at the same time — life doesn’t schedule like a lobby. So Runish is built async to the bone: you run when you run, your friends run when they run, and the game weaves the competition afterwards. Quick Run turns any spontaneous run into progress; Route Challenges let you set a route, post a time, and dare someone to beat it — this week, on their own schedule.

Async also fixes the motivation curve. Trackers hand you a graph and wish you luck; a graph has never gotten anyone out the door in week eight. A rival’s time on your route has.

The hard part: background GPS that never lies

Everything above is design; this is where the engineering lives. Reliable run tracking on iOS means background location — and background location is where web-first development genuinely ends. So I wrote custom native Capacitor plugins:

  • The run tracker owns the native location session: accuracy profiles, pause detection when you stop at a light, battery-sane sampling, and survival when iOS backgrounds the app for an hour. It hands the game layer a clean, honest route — not a cloud of jittery points.
  • The HealthKit bridge writes workouts back to Apple Health, because a run that doesn’t count in your rings didn’t happen, psychologically.

This is the part of the project where every bug costs a real run — mine. I have jogged the same neighbourhood loop so many times for GPS validation that I could draw it blindfolded. Test-driven development where the test suite is cardio.

Mapbox as a game board, not a chart

The map is Mapbox, styled away from “fitness app” toward “territory”. Claimed routes render like held ground; stamps mark conquered places; the block you haven’t run yet looks pointedly unclaimed. Presentation is doing real game-design work here: the same data drawn like Strava reads as exercise, drawn like Runish it reads as a board mid-game.

Scoring runs server-side on Firebase Functions from the raw GPS trace — distance, pace, and route-matching for challenges (did you actually run this route?). Server-side scoring keeps async leaderboards honest, the same integrity principle as Dolphin Beyond’s replay verification, applied to sweat.

Where it stands

The monorepo — React + Capacitor app, Functions backend, the native plugins — is at V1 release-candidate stage. XP, levels and route stamps are in; the map feels like a board; my test loop is thoroughly conquered. What remains is the last mile of any iOS game: TestFlight rounds and the App Store gauntlet.

Follow the Runish page — and when it ships, the first route challenge in Aarhus is mine. Come take it.