veganpower.grn.dk is Vegan Power, a catch-the-fruit arcade game with a rule you understand in one second: eat fruit, not friends. Fruit falls and you catch it. A chicken, a cow or a penguin falls and you dodge it — each one you hit costs one of your seven hearts. It began in 2020 as a small Flutter and Flame game for Android, released on Google Play that December. In 2026 it was taken apart and rebuilt: it now opens in any browser with no install and no account, keeps a global high-score table on its own small API, and carries a multiplayer beta where two to four players share one arena and shove each other off the fruit.
- Client
- GrN.dk — internal build
- Sector
- Browser and mobile games
- Period
- Built 2020 · rebuilt and relaunched July 2026
At a glance
The challenge
The starting point was a five-year-old hobby game that only existed as an app. To play it you had to find it in a store and install it, which is a lot of friction for something that takes ninety seconds to enjoy. Inside, the code showed its age too: one long game loop that drew every element by hand, a high score saved only on the device, and no way to test any of the gameplay rules without running the whole app.
The brief for the rebuild was therefore not "add features". It was: make it playable instantly from a link, on a phone or a desktop, anywhere in the world; give the score somewhere to live so a run means something; and do it so that the thing stays cheap to run and can be maintained a card at a time rather than in long, risky sessions.
Two constraints made that harder than it sounds. First, a Flutter game in a browser ships a large graphics runtime before it can draw a single frame — and the server is in Europe while a good share of the players are in Asia, so "it works here" says nothing about how it feels there. Second, the headline feature people ask for — real-time multiplayer — is a physics problem, not a feature request: in a reflex game, the distance between a player's finger and the server is felt directly, and no amount of code makes the speed of light shorter.
The solution
The game. Five kinds of fruit fall (banana, orange, pear, strawberry, watermelon) and six animals (chicken, cow, dog, elephant, penguin, pig). Catching fruit scores, and four catches in a row without a hit start a multiplier that climbs to five times; a hit resets it and costs a heart, of which there are seven. The fall speed and your own speed both rise with the score, so a round starts gentle and ends frantic. Every catch plays one of thirteen little voice clips — the "yum" and "no!" noises are in a handful of languages, Danish, Polish, German and Thai among them — over a single jazzy loop, with a screen shake and a particle burst on impact.
A modern engine underneath the same game. The hand-rolled render loop is gone. The game is now an ordinary Flame game where the views are router pages, and the hearts, score, combo, buttons and leaderboard panel are all self-positioning components. Just as important, the rules that used to be tangled into the loop are now plain functions with no graphics attached — difficulty curve, board geometry, and the collision check that decides whether you caught something. That last one is a swept test rather than a snapshot, so a fast-falling fruit cannot teleport straight through the player between two frames. Thirty-four automated tests cover those rules, plus a golden image of the home screen.
Making it behave in a browser. Two things were learned the hard way and are now written into the code as warnings. The game only renders reliably as a bare game widget — every attempt to wrap it in a layout widget blanked the screen — so the letterboxing is done inside the game instead: one centred nine-tile play column that the background, the HUD, the buttons and every spawn anchor to, at any window size. And the graphics runtime was being served uncached, which meant roughly 28 KB/s to a distant player: a caching rule at the edge took that to around 60 MB/s worldwide, which is the difference between "black screen, must be broken" and "it just opens".
A small API of its own. Global scores run on a FastAPI service with a SQLite file behind it, on the same server, proxied at vpg-api.grn.dk. There are no accounts and no email addresses: identity is an anonymous id minted in the browser on first play, with an optional nickname that goes through a profanity filter, and a transfer code if you want to carry your profile to another device. Because a public score endpoint is an invitation, submissions are signed, timestamped, rate-limited per device and per address, and capped at a score no honest round can reach. (One detail worth remembering: the free certificate at the edge covers only a single subdomain level, so api.veganpower.grn.dk could never work and the API lives at vpg-api.grn.dk instead.)
Fruit Rumble, the multiplayer beta. Two to four players join a four-letter room code for a ninety-second round in a shared arena, where bumping into someone shoves them — steal the fruit they were lining up, or push them into a cow. The server owns the simulation and runs it twenty times a second, because otherwise two players will never agree about who shoved whom; clients send only their input. Your own character is predicted locally and reconciled against the server's acknowledgement, the rest of the world is interpolated through a buffer that sizes itself from the jitter it actually measures, and an on-screen NET readout shows the round-trip time, the jitter and the current buffer so the feel can be argued about with numbers instead of adjectives.
Shipping it, every push. A build runs within ten minutes of a commit and refuses to go out if anything is red: the analyzer, the thirty-four game tests and the twenty-nine API tests all gate it. A green build deploys the web version, purges the edge cache, builds a signed Android release, installs it on a real Android emulator and runs a launch smoke test — and only a passing smoke promotes the public download link, mirrors the file to Drive and uploads to the store's internal testing track. A version tag is what promotes a build to production. Either way an email arrives saying "ready" or "BLOCKED", with the reason.
Seeing it, not assuming it. A game that renders on a canvas shows nothing to a script that reads the page, so verification is done with real eyes: a GPU browser and a real Android emulator that are driven, screenshotted and checked. The picture at the top of this page was made that way — an agent opened the live site, waited for the first frame, tapped START with real touch events, played a round, and captured it.
The results
Vegan Power is live at veganpower.grn.dk: open the link and play, on a phone or a desktop, with no install, no account and nothing stored about you beyond an anonymous id in your own browser. The Android build is still there for anyone who wants it — a signed APK from the latest commit, plus the original 2020 release on Google Play.
The global high score works end to end: finish a round and the game-over screen shows the global top three and your own rank, served by the project's own API. That was confirmed in the same automated session that produced the screenshot above.
The running cost is deliberately close to nothing: static files behind a CDN, one small API process and a SQLite file that the nightly backup already covers.
What is not finished, in the owner's own words. Multiplayer is labelled a beta on the home screen because that is what it is. Moving the relay to a connection that lands on a nearby edge location cut the network round trip from roughly 250 ms to around 100 ms for players in Thailand, and the relay's own work is under a millisecond — but everything except your own character is drawn through a smoothing buffer, so opponents and fruit still arrive a quarter of a second behind your finger. The verdict after a real round was "better, but still not playable", and the honest answer is that closing that gap means predicting the whole world locally and judging catches against what the player actually saw. Those two pieces are designed and scoped; they are not built. Solo play, which is the game most people will open, is unaffected.
The other thing this project demonstrates is how it was made: the whole rebuild came off a Trello board one card at a time, each picked up by an AI agent — the web build, the caching fix, the leaderboard, the engine modernisation, the multiplayer relay and the latency measurements are each traceable to the card that asked for them, including the ones where the user simply wrote "web build is not doing well on full screen" and got a root cause back. There is a plain-language write-up of the game itself here: Vegan Power: the little game about eating fruit, not friends.
Eat fruit not friends.