Skip to main content
GrN.dk

Main navigation

  • Articles
  • Cases
  • Contact
  • Your Digital Project Manager
  • About Greg Nowak
  • Services
  • Portfolio
  • Container
    • Excel Freelancer
    • Kubuntu - tips and tricks
    • Linux Apache MySQL and PHP
    • News
    • Image Gallery
User account menu
  • Log in

Breadcrumb

  1. Home
  2. Cases

A 2020 phone game rebuilt for the browser, with a global leaderboard

Client
GrN.dk — internal build
Sector
Browser and mobile games
Period
Built 2020 · rebuilt and relaunched July 2026

veganpower.grn.dk ↗

Vegan Power running in a browser tab on a phone-shaped screen: seven full hearts and the score line "Vegan Power: 1" across the top, a blue sky of cartoon clouds with two oranges and a pear falling through it, a chicken, a dog and a penguin drifting down among them, and the round yellow player waiting with its mouth open at the bottom of the play column.

At a glance

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.

89 commits, 2020 to 2026 — the same game in two eras
34 game tests + 29 API tests gate every single push
20 Hz server-authoritative relay · 2-4 players · 90-second rounds

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.

The whole design brief — the first line of the game's 2020 README
  • Flutter
  • Flame
  • Games
  • browser games
  • Android
  • Custom Development
  • AI agents

Got a project that needs the same kind of hands-on delivery?

Your digital project manager

Review Greg on Google

Greg Nowak Google Reviews

 

Illustrated infographic summarizing: One Timeout, Two Orders: Make AI Actions Safe to Retry
One Timeout, Two Orders: Make AI Actions Safe to Retry
2026-07-25

A timed-out AI action may already have succeeded. Stable keys, durable ledgers, queues and stored results prevent a routine retry from duplicating real work.

Illustrated infographic summarizing: Your AI Visibility Dashboard Needs a Methodology, Not More Charts
Your AI Visibility Dashboard Needs a Methodology, Not More Charts
2026-07-24

A practical framework for measuring AI-search visibility with fixed prompts, repeated tests, separate metrics, retained evidence, and honest reporting.

Illustrated infographic summarizing: AI Admin APIs Are Here—But Your Directory Is Still the Source of Truth
AI Admin APIs Are Here—But Your Directory Is Still the Source of Truth
2026-07-23

New AI admin APIs can automate access and spend controls, but reliable governance still starts with authoritative directory data and clear ownership.

Illustrated infographic summarizing: OpenAI Presence Arrived—But Is Your Workflow Ready for an Agent?
OpenAI Presence Arrived—But Is Your Workflow Ready for an Agent?
2026-07-22

Before an AI agent can take on real work, its workflow needs clear scope, permissions, handoffs, evaluation cases, and production monitoring.

Illustrated infographic summarizing: Chatbot Transcripts Quietly Became a Retention and Redaction Problem
Chatbot Transcripts Quietly Became a Retention and Redaction Problem
2026-07-21

Chatbot transcripts spread across providers, logs and support tools. Here is how to map each copy, redact sensitive data and test deletion properly.

Illustrated infographic summarizing: Cloudflare Service Keys Stop in September: Find Every Caller
Cloudflare Service Keys Stop in September: Find Every Caller
2026-07-20

Cloudflare Service Keys stop working on September 30, 2026. Here is how to find every caller, move to scoped API tokens and avoid a late outage.

Illustrated infographic summarizing: Your AI Workflow Needs an Acceptance Test Before It Meets Customers
Your AI Workflow Needs an Acceptance Test Before It Meets Customers
2026-07-19

A practical way to test AI workflows using realistic scenarios, tool checks, human rubrics, regression suites, and clear release gates.

Three cover candidates for The Goats Were Load-Bearing fanned on a dark background: an ember-lit door, three slow knocks, and a founders' ledger
The Goats Were Load-Bearing: a fantasy where the bill always comes due
2026-07-19

A teaser for the upcoming darkly comic fantasy novel The Goats Were Load-Bearing — a village, a door that must stay poor, and the worst possible time to sell the herd. Readers pick the cover.

Vegan Power game: the yellow player catches falling fruit while a chicken and a cow look on
Vegan Power: The Little Game About Eating Fruit, Not Friends
2026-07-19

Vegan Power is a free browser game where you catch fruit, dodge the animals, protect seven hearts, and chase a better high score.

KotobaMon title screen: the Japanese logo コトバモン over a low-poly 3D island with monsters, cherry-blossom trees and a trainer.
KotobaMon: Shipping a 3D Browser Game With No Build Step and Self-Hosted Voice
2026-07-19

A look at fantasy.grn.dk, a browser-based 3D game that teaches Japanese with no build step, procedural art and self-hosted AI voice, and what its constraints show about shipping interactive products fast and cheap.

More articles
RSS feed

GrN.dk web platforms, web optimization, data analysis, data handling and logistics.