Skycritter: one review gate, unattended output
A weather app with a pixel kitten, on iOS and Android, whose generated character art runs through one human review gate. I set the pricing and designed the pipeline.

One human check, at base character generation, keeps review cost fixed per character.
The product
Skycritter is a weather app where a pixel critter reacts to the real weather outside: soggy in rain, giddy in snow, scared of thunder, a werewolf on real full moons. Underneath is a full forecast. It’s live on the App Store and Google Play, with paying users in the US and France.
The review gate
The critter art comes from a generative pipeline. I integrated the PixelLab MCP server into the production path so an LLM orchestrates the tool calls, and I defined the output contract and style rules the art has to meet.
There’s one human check, at base character generation. I review the new character against the style rules and approve or reject it. Most pass; the failures are outliers with unusual features. Once a character passes, every state and script for it generates unattended. Review cost stays fixed per character while output grows with the number of states.
Pricing
I set a lifetime Pro unlock alongside one-off character and skin purchases. These numbers are from the launch window. The user base has grown since and conversion has come down toward what’s typical for iOS apps. Over the first 2.5 months live, 18.4% of downloads led to a purchase within 35 days, on 14 in-app purchases and $39 in proceeds. That’s a small, early sample, and $39 is the whole revenue so far. Conversion more than doubled between day 1 and day 35, so the decision to buy happens while people use the app.
Discovery is the tighter limit. 1.74K impressions produced 311 product page views and 72 first-time downloads, so about a quarter of the people who opened the listing installed, and impressions cap everything after that.
Android
The Android version shares the same Swift code, compiled for Android with Skip. A one-week go/no-go spike found one hard problem: ambient animation ran about 30× too slow through the cross-platform bridge, so that layer is native Kotlin. The port took about ten weeks of part-time work, and there’s still only one codebase to maintain.