Get in touch

From the workshop

SkyGames

Tiny screen. Big fun.

A growing catalogue of pixel-perfect arcade games for Garmin watches.

Live Web Garmin
Monkey C Connect IQ Laravel backend
The build story
  • SkyRunner

    Visit →

    Retro endless runner. Jump, dodge, sprint through pixel-perfect obstacles.

    Featured by Garmin Connect IQ

    32,039 players · 160 countries · 432,636 runs

  • SkyLander

    Visit →

    Space trading across the solar system. Upgrade your ship, trade goods, dock at 25+ stations.

    9,685 pilots · 18,861 quick flights · 40M credits earned

  • SkyLing

    Visit →

    A virtual pet on your wrist. Hatch eggs, raise creatures, discover dozens of species.

    3,103 keepers · 7,268 skylings hatched · 78,164 play sessions

The build story

Fifteen frames per second.

A Garmin watch is a spectacularly bad games console. The frame budget is 67 milliseconds — 15 FPS on a good day — the memory ceiling is measured in double-digit kilobytes, and the screen is a circle. SkyGames exists because that sounded like a fun set of rules rather than a reason not to try. It’s now a catalogue: SkyRunner (endless runner, 50 handcrafted levels), SkyLander (space trading), and SkyLing (a virtual pet that lives on your wrist), all sharing one Laravel backend and one set of hard-won lessons.

Every pixel goes through the budget office

SkyRunner’s game loop runs player movement, two spawning systems, six kinds of collision detection, and a full render pass inside that 67ms window — with a profiler wrapped around each stage so regressions show up as numbers, not vibes. The game targets seventy watch models across eight screen resolutions, from a 218-pixel Forerunner to a 454-pixel AMOLED Fenix: everything is authored once at the largest size and every pixel literal in the codebase passes through a scale manager at runtime. Levels are authored as plain text files and compiled by a Python step into Monkey C data arrays before every build — the watch never parses a level, it just reads structs that were code all along.

Shipped, then shipped again

SkyRunner hit the Connect IQ store in November 2025. The online level editor — build a level in the browser, play it on your wrist — followed eleven days later. By January the Pro paywall was gone and everything went free; by April there was an in-game diamond shop. Somewhere in there, Garmin featured it on Connect IQ, and the player counts on this page stopped being hypothetical — they’re live numbers from the same events pipeline the games report into, spanning real players in 160-odd countries.

A virtual pet needs a backend

SkyLing pushed the catalogue somewhere stranger: a pet that keeps living while the watch sleeps. Its decay logic extrapolates hunger and mood server-side (capped at 24 hours, and politely paused during your sleep window), and its companion watch face syncs through a pairing scheme designed for a device that can’t hold secrets: a one-time four-digit code, aggressively rate-limited so the tiny keyspace can’t be scanned, exchanged on first use for a long-lived 96-bit key. The analytics behind all three games had its own growth moment — the day the events table got big enough to OOM the dashboard, aggregation moved from PHP into SQL, and a notification now pings my phone at every fiftieth new device.

Three games, three rabbit holes

None of these shipped in a straight line. A mascot got fired, a ship grew five new bodies, a virtual pet refused to get hungry, and a font had to be drawn one pixel at a time for the cheaper watches. Below is the honest version of each game’s development — a few of the real turns, redesigns and platform fights pulled straight from the commit history. Each track scrolls sideways; drag or swipe through to dig in.

SkyRunner

Endless runner · from Oct 2025
Oct 2025 Rendering
One scale manager, 70 watches

Every Garmin model has a different screen, so a single scale manager was built to size every sprite, font and hitbox off the device resolution — a 4,500-line refactor that made multi-resolution support possible at all.

Oct 2025 Art
Not a monkey — a test sprite
Not a monkey — a test sprite

The Garmin starter project shipped with a sample “monkey” asset that never actually rendered. The first real player was this scrappy little hand-drawn runner, dropped in just to start testing.

Oct 2025 Physics
New Zealand wildlife, as hazards
New Zealand wildlife, as hazards

Sheep, kiwi, kākā and a bee joined the obstacle roster — each needing a hand-tuned hitbox so collisions matched the visible pixels, not the bounding box.

Nov 2025 Levels
Levels become a compiled format
Levels become a compiled format

A Python step compiles authored levels into Monkey C data the watch just reads — plus auto-generated preview images and a stack of validation rules for ledge spacing, reachable jumps and safe landings.

Dec 2025 Art
The dude gets a remaster — before The dude gets a remaster — after
The dude gets a remaster

v1.4.0 redrew the dude — and every other sprite — into a proper six-frame run cycle with new celebrate, death, jump and slide states. Same scrappy runner, glow-up applied.

Jan 2026 Launch
Tearing down the paywall
Tearing down the paywall

For a while the free version literally hit a wall — a brick paywall that spawned across the track at 9.8km and stopped Lite players cold. v1.5.0 tore it down: every Pro licence check ripped out, all levels and the browser editor unlocked for everyone.

Apr 2026 Economy
The Diamond Shop opens
The Diamond Shop opens

The diamonds players had been hoarding finally became a currency — a shop selling Endless-Mode power-ups like the slingshot, bubble and extra life. (A wallet bug shipped with it, hot-fixed two weeks later.)

SkyLander

Space trading · from Nov 2025
Nov 2025 Ship
First spacecraft sprites land
First spacecraft sprites land

The opening art drop: three workhorse ships — the nimble Mosquito, the cargo Mule and the Vector — drawn through a custom AI asset pipeline and packed across seven watch resolutions.

Dec 2025 Physics
Ships that bank into their turns
Ships that bank into their turns

Flight feel jumped when the ship started rotating to face its velocity vector, with the thrust flames re-aligned to match — flat top-down drifting suddenly read as real flying.

Dec 2025 Economy
Fuel becomes a real budget
Fuel becomes a real budget

The economy moved from flat zone multipliers to fuel-cost-per-AU, progressive distance burn, cargo-weight penalties and a mandatory landing reserve — every trade route became a fuel-vs-profit sum.

Jan 2026 Ship
Five faces of the Mosquito — before Five faces of the Mosquito — after
Five faces of the Mosquito

The Mosquito grew a five-tier upgrade ladder — Reinforced, Racer, Combat, Elite, Legendary — each a distinct sprite, the plain grey fighter becoming a gold-and-purple cruiser.

Jan 2026 Economy
The 100,000-credit oopsie

To test buying every skin, starting credits got bumped from 1,000 to 100,000 — then sheepishly walked back to 1,000 the same day. Leftover debug money, narrowly un-shipped.

Jan 2026 Typography
Hand-built bitmap fonts
Hand-built bitmap fonts

Cheaper watches like the Venu 3 have no scalable fonts, so a font manager rendering 5×7 and 6×9 pixel glyphs was written from scratch — later given borders and shadows to stay legible.

Jan 2026 UI
The “Too Many Timers” bug

The new toast notifications spawned a timer each and hit Garmin’s hard timer limit; the fix routed every auto-dismiss through one shared timer. A very watch-platform kind of war story.

SkyLing

Virtual pet · from Dec 2025
Dec 2025 Creatures
First it was a dragon
First it was a dragon

SkyLing didn’t start as a roster — it started as Drago, a single red dragon, the art-pipeline guinea pig. A cast of named characters followed (including Zorro, the family border collie) before the whole lot was cut and rethought.

Dec 2025 Hatching
One egg to rule them all
One egg to rule them all

Those named characters — and a three-egg picker — got scrapped for a single Mystery Egg. Every Skyling now starts identical, and which of ~27 species you get is decided at hatch time by how active you’ve been.

Dec 2025 Simulation
Why won’t it get hungry?

An eight-hour offline test exposed that hunger never decayed while the app was closed. The fix pinned the real-time-to-game-time ratio and hardened the decay maths against nulls — the first real offline-simulation milestone.

Dec 2025 Creatures
Thirteen creatures in a day
Thirteen creatures in a day

A single batch generated configs and sprites for thirteen new Skylings at once, growing the roster toward its eventual ~27 species across bio, cosmic, synthetic and oddball families.

Jan 2026 Creatures
Buzz gets a glow-up — before Buzz gets a glow-up — after
Buzz gets a glow-up

A wholesale art pass regenerated every frame of the Buzz creature — idle, eat, emerge — a clean before/after on the very same sprite.

Jan 2026 Typography
Aa
Fonts for the font-less

Older watches were rendering text wrong, so a font manager and bitmap fonts were added with per-context scaling — menu, important, detail — to keep type sharp across the device zoo.

May 2026 Pairing
Type a code, mirror your pet

The companion watch face arrived: the app makes a short pairing code, pushes signed state to the backend, and the face polls to mirror your live pet. The code shrank from six letters to a four-digit PIN to make it typeable on Garmin Connect.

May 2026 Simulation
Let sleeping pets lie

Friendly Mode (reduced decay, no death) and Pause-During-Sleep landed — your Skyling’s hunger and mood freeze overnight, with a 24-hour cap so a long-unsynced pet can never come back already starved.

The two that didn’t make the cut

SkyGames isn’t only the things that shipped. Two bigger swings live in the SkyLands universe — a dark-fantasy world of islands shattered across a breathable void, a setting I built out far past any single game — and neither has quite earned its place on a watch yet. Parked, not dead.

Key art for SkyRift: Relics of the Aether
≈97% built · parked

SkyRift: Relics of the Aether

Real-time action RPG · Diablo-inspired

Procedurally-generated floating islands, auto-combat, a full town with shops and quests, bosses, an economy — genuinely most of a game. It also kept losing a fight with the hardware: on a real watch the frame rate sat near six per second where the simulator flew, the watchdog timer kept killing map generation until it was sliced into async chunks, and a core render cache quietly refused to cache. The closest thing here to finished — and the clearest case of asking a wrist computer for a little too much.

Key art for SkyLands
shelved · scope

SkyLands

Endless text RPG · Darklands-inspired

A data-driven, endless RPG in the spirit of Darklands — branching vignettes, reputation, turn-based combat, all authored as data and compiled onto the watch. The engine works. What ran away was the world: a 500,000-word lore bible across 200-odd wiki pages, declared ‘complete’ three days in and promising six hundred quests — against a game with exactly one quest and one location actually playable. It didn’t get out of hand so much as start out of hand. Shelved, with enormous fondness.

Both wear the same world on their sleeve, and it’s a world I fully intend to come back to.

Why bother?

Because constraints are a forcing function. There’s no room for a framework, an asset store, or an unconsidered allocation — every feature has to justify its bytes. The catalogue keeps growing (there are more Sky-somethings in various stages of playable), and every one of them starts from the same question that started SkyRunner: how much fun fits in 67 milliseconds?

Working with a brutal platform constraint that still has to feel effortless? Here’s how we could work together.

Visit SkyGames