Inspiration

A free mobile game is usually not a game that is free. It is a game whose revenue comes from a small number of people who spend a lot, and everything else in it is arranged to find those people and keep them spending.

That arrangement is now measured. A 2026 study in Frontiers in Public Health surveyed 2,308 Austrian students aged 10 to 19 about what they spend inside games. The top 10% of spenders accounted for 61.4% of all the money, and the heavy spenders had higher rates of gaming disorder and gambling disorder than the casual ones. The authors say the concentration looks like the pattern you see in gambling markets, and that it is not explained by how well off the family is. (Meschik, Hammer, Malischnig, Wächter and Griffiths, 2026, https://doi.org/10.3389/fpubh.2026.1867460)

The mechanics that do the finding are not a fringe thing either. When York researchers surveyed the 100 top-grossing games on each store, 58.0% of the Google Play list and 59.0% of the App Store list contained loot boxes, and 93.1% of the Android ones that had them were rated suitable for children aged 12 and up. (Zendle, Meyer, Cairns, Waters and Ballou, Addiction, 2020, https://doi.org/10.1111/add.14973)

The money is real and regulators have started sending some of it back. Epic agreed to pay $245 million in 2023 to settle FTC allegations that it used deceptive practices to trick Fortnite players into purchases they did not want. By June 2025 the FTC had issued nearly $200 million of that in two rounds of refunds, 629,344 payments in December 2024 and another 969,173 the following June. (FTC, 25 June 2025, https://www.ftc.gov/news-events/news/press-releases/2025/06/ftc-sends-126-million-refunds-fortnite-players-who-were-charged-unwanted-items-reopens-claims) Five months before that, the developer of Genshin Impact paid a $20 million penalty and was barred from selling loot boxes to under-16s without a parent's consent. The FTC's complaint says the layered virtual currency hid what a prize actually cost, and that some children spent hundreds or thousands of dollars chasing one. (FTC, 17 January 2025, https://www.ftc.gov/news-events/news/press-releases/2025/01/genshin-impact-game-developer-will-be-banned-selling-lootboxes-teens-under-16-without-parental)

Then there is what it costs everyone else, which is the time. An energy bar is a design that exists to stop you playing. It is aimed at the spender, and the bill for it is paid by every other person who opened the app with seven minutes to spare.

So I went and read what players ask for when nobody is selling to them. I pulled 198 posts about mobile games from a large Android gaming community, going back to September 2024, and sorted them by what they wanted. 92 of those posts, carrying 2,509 upvotes and comments between them, asked for premium or no-ads games and said they would pay to avoid pay-to-win. 38, with 1,317, wanted something that works offline, in portrait, one-handed, in short sessions. 10 were about ads that were predatory or plain offensive, including adult content inside ordinary games.

A market asking that clearly, and still getting energy timers.

Drift Kitchen started somewhere else. It was built as a Reddit game with Devvit, where the community layer is the point: a whole community shares a weekly feast, a cookbook pays you a cut when somebody else cooks your dish, and the daily cravings come out of real activity in the subreddit. That version still exists and it is still good. It also needs a connection and an account, which rules out the bus.

So I took the same kitchen and made it run on a phone with no network, no account, and nothing between you and the first order.

What it does

The seven minutes you actually have are the problem. You are on a bus, or in a queue, or waiting for a kettle. A game that spends three of those minutes on an unskippable ad and then tells you your energy is empty has taken the whole window and given nothing back.

Drift Kitchen opens on a shift. Tap a bin to pick up an ingredient, drag it to a station, let it cook, drop it on a plate, and hand it over before the bar above the customer's head empties. Leave a patty on the grill too long and it burns and goes in the bin.

Serve fast and the combo climbs to 3x. Drop one order and you are back to 1x. At 42% into every shift, rush hour lands: customers arrive at more than twice the rate and every tip doubles, for twenty-two seconds. That is the stretch that decides the day.

Four kinds of customer stand at the counter and none of them behave the same. The Impatient one waits 22 seconds and pays 1.15x. The Regular waits 32 and pays 1x. The Critic waits 34 and pays 2.6x, which makes the patient one the valuable one. The VIP waits 45 and pays 1.6x. Reading the queue is most of the skill.

Between shifts the shop opens. Eight kinds of station across five kitchen sizes, from a room with a grill and a soda machine up to a floor with a smoker and a dessert counter. Prep speed takes 12% off every cook time per level. A cook costs 600 coins and runs one station without you. A waiter costs 900 and carries finished plates out, which leaves your hands for the tickets that are actually hard.

Cravings turn over each day and change which dishes pay more. Offline they come from a date seed, so every player gets the same rotation on the same day, with no server and no account to make that work.

No energy timer. No ad. Nothing counts down to your next go. You open it and you are cooking within a couple of seconds, which is the whole point of a game played in seven-minute pieces.

How I built it

The trap in porting a community game is the fork. You copy the code, tear the network parts out of the copy, and now you maintain two games, one of which is visibly the lesser one.

The game is TypeScript and Phaser, first written as a Devvit custom post type where the handlers talk to Redis. The Android build is a Kotlin WebView shell around that same code. RevenueCat's Galaxy Store support has no Flutter or Capacitor SDK, so a native shell was the honest route, not a compromise.

The shell does not fork the game. It runs the same src/handlers against a local store shaped like the Redis one the Reddit version uses, so the cooking logic has one implementation. Platform sits behind a single interface, which is why the Reddit build keeps its shared leaderboards and community feast while the offline build keeps those personal and says so on screen.

None of the art is a file. The kitchen is an isometric grid drawn at runtime with Phaser graphics calls, the food is drawn shape by shape in DishArt.js, and the music and sound effects are synthesised in WebAudio, a four-bar lo-fi loop at 92 bpm over I-vi-IV-V. There is not one PNG or one MP3 in the project. The whole game is 340 KB of code next to the Phaser build.

The Android dependency list is five lines long and two of them are RevenueCat. There is no ad SDK and no analytics SDK, because "no ads, no tracking" is a claim a build file either backs up or does not. The app declares one permission, INTERNET, and the only thing that uses it is the purchase check.

69 vitest tests on the game logic, 25 JUnit tests on the shell.

How Drift Kitchen uses RevenueCat

RevenueCat's Android SDK with purchases-store-galaxy runs the paywall and the head_chef entitlement, and CustomerInfo is what the game reads, never a local flag.

The whole game is free. Every station, every tier, every shift, every day.

Head Chef is one purchase. It pays 500 coins once and adds 10% to coins from then on. Neither of those is bespoke paid content: they are level 1 of two meta-upgrades the economy already sells for Renown, the currency you earn by playing. Buying the pack moves you along a track you can walk anyway, and the shop screen says exactly that.

Restore purchases and a support ID are both in About, because losing a purchase on a new phone is one of the complaints that came up again and again in those 198 posts.

Challenges I ran into

A run-through on a real device found four things no test catches. The Cookbook button was invisible against its own background. Every single pick-up played the error buzz. Opening the shop zeroed idle income. And real subreddit names were still sitting in the offline HUD, where they mean nothing to somebody who has never used Reddit.

The subtler problem was deciding what to remove. Offline, /api/claim-offline returns zero, the leaderboards hold one player, and the feast is a solo weekly goal. The temptation is to leave all of it in and let it look busy. The listing, the store text and this submission leave it out instead, because a leaderboard with one name on it is worse than no leaderboard.

Getting the demo to look like play rather than a slideshow took a second pass too. The first cut barely moved between frames. The final one is live play, with 69% of frames changing.

Accomplishments that I'm proud of

It shipped on 15 August 2026 and has passed 3,000 downloads, with no ads, no energy bar and nothing to buy mid-shift.

One codebase across two platforms that could not be less alike, with no gameplay fork. The Reddit version keeps the community layer. The Android version works on a plane. Neither is a stripped copy of the other.

And a mobile game with no ads, no energy bar, no coin packs and one optional purchase, shipped because people asked for it in writing, not because I had a hunch.

What I learned

Porting a community game teaches you which parts were actually the game. The cooking loop survives alone. The cookbook and the feast do not, and faking them with an empty leaderboard would have been worse than cutting them.

The other thing I learned is that "no dark patterns" is not a positioning statement, it is a list of things you have to not build. There was no ad SDK to configure, no coin pack to price, no energy timer to tune. Each of those is a day I did not spend, and the game got the day instead.

What's next

Supabase behind the same platform interface, so the offline build can gain the cookbook, real leaderboards and the weekly feast without changing a single handler. Offline first, shared later, was always the plan.

Built With

Share this project:

Updates

Submission history