Reverse engineering Meowdoku: the tactics behind a $73M a year puzzle game
- $73Ma year from ads, estimated
- 2M+daily players, estimated
- 10M+downloads on Google Play
Revenue and daily players: Gamigion estimates (revenue annualised from about $200K a day). Downloads: Google Play, October 2026.
The 50Fold team found that Meowdoku, a free cat-themed logic puzzle game, fakes both its competition and its community.
Gamigion estimates the game makes about $200,000 a day, all from ads (Gamigion): about $73 million a year.
We wanted to know how a free puzzle earns that, so we used the 50Fold engineering agent to reverse engineer the app. Each finding below comes with the code behind it.
How we read it
- The 50Fold engineering agent reverse engineered Meowdoku.
- The app ships default settings its server can change. The findings describe what ships in the app; live values may differ.
- 50Fold is not affiliated with or endorsed by Oakever Games, Meowdoku's developer.
1. The leaderboard is you and 49 bots
What we found. The daily leaderboard unlocks at level 11. It ranks you against 49 bots the game generates on your phone, with no server call for rankings.
- Names. In the control group, about 4 in 10 bots get human-style names like Harper Bailey or sweetdream421. The rest get IDs like P738J1.
- "Playing now." If no bot within two places of you looks online, the code switches the nearest one to "Playing now".
- Likes come back on a schedule. Each time you win a level, every bot you've liked gets a 35% roll to like you back, and every bot gets a 5% roll. A message pops up, such as "Wow! [name] liked you".
- No label. We found nothing marking them as bots on screen, in the game's text, on its Google Play listing or in its terms of service (checked October 2026).
Our redraw of the leaderboard in our playthrough, level 11. We are 50FOLD.COM. Every other name is in the game's bot name list, including BG09UN, "Playing now".
What it means for you. There are no other players on the board, so every like you get comes from a bot.
The code. The bot count, the robot flag, and the like-back odds:
const ROBOT_COUNT: int = 49
...
pi.is_robot = true
...
return 35 if player_liked_robot else 5Why it matters. The board feels alive with zero players and no server. It is the cheapest "social" feature there is.
What a small team can ethically copy this week.
- Start with practice rivals. A leaderboard can run on the phone with no server. Call the rivals practice rivals, so nobody mistakes them for people.
- Swap in real players as you grow. Mix in real scores once you have enough players, and mark which is which.
2. The bots are built around your last score
What we found. Each leaderboard event lasts a day. When a new one starts, the game sets the bots' target score from your score in the last event:
| Where you finished last time | Bots' target (control group) |
|---|---|
| 1st | 8% above your last score |
| Top 10 | 3% above |
| Top 30 | 10% below |
| Lower | 20% below |
The bots' final scores are spread up to that target. An A/B test covering about 7 in 10 players goes further:
- A first-place finish sets the target 24%, 40% or 80% above.
- A hot-streak boost (our name): winning levels in a row multiplies your points, and each time you score, until you pass the target, bots move up by 20% to about double your points.
What it means for you. Win or lose, the next race starts close.
The code. s_prev is your last score; alpha is the adjustment for where you finished:
var raw: float = float(s_prev) * (1.0 + alpha)
...
var alpha_first: float = 0.08Why it matters. Rubber-band competition, tuned to each player, with four settings.
What a small team can ethically copy this week.
- Scale the challenge to the last result. Set each new target from the user's own last score: a bit higher after a win, lower after a loss.
- Reward streaks. Multiply points for wins in a row, so a good run feels bigger.
3. Robot stalking
What we found. Once your score passes the bots' target:
- The game deletes every bot's remaining scheduled points.
- Up to 10 of the top bots chase you. Each time you score, they climb to at most 2 points behind you, tagged "Playing now".
- In the shipped settings they never pass you. A built-in mode that lets them pass by up to 4 points is switched off.
The code calls this RobotStalking. The developers' debug logs call it "companion".
What it means for you. The rival 2 points behind you stopped playing the moment you passed the target. It only moves when you do.
The code. _freeze_future deletes each bot's future points; stalk_dn_offset keeps the chasers 2 points behind you:
if not pool.stalk_active and score > pool.x_base:
...
_freeze_future(r, elapsed_min, cfg)
...
var stalk_dn_offset: int = -2Why it matters. The closest race on the board is scripted.
What a small team can ethically copy this week.
- Race the user's own best. Show their personal best right behind their current score, so there is always a close rival, and say it is them.
4. The "X% of players" pop-ups are random
What we found. From level 11, each level opens with a pop-up such as:
"72.4% of players clear this level on first try!"
Meowdoku start-of-level pop-up (example number)
The number is random: 60 to 80 on normal levels, 40 to 60 on hard ones. It stays the same for that level until you win or restart the app. The other pop-up lines with a percentage work the same way, each with its own range.
Our redraw of a pop-up from our playthrough, level 11. The code draws this line's number at random between 30 and 50.
What it means for you. It reads like data about other players. It is a dice roll.
The code. randf_range is the engine's random-number call:
{ key = "TOAST_TEXT_G2_FIRST_0",
pct = { normal = Vector2(60, 80), hard = Vector2(40, 60), format = "xx.x%" } },
...
pct = randf_range(range_vec.x, range_vec.y)Why it matters. Fake social proof takes one line of code. Don't copy it.
What a small team can ethically copy this week.
- Show real numbers. Log each level's results and show the real clear rate.
- No data yet? Show none. A plain "New level" beats a made-up stat.
5. The ad ramp
What we found. Pop-up ads play at the start of a level, never before level 11 and your second app launch. After that, the minimum gap between ads shrinks the longer you've had the app. Shipped settings for the US and ten other countries:
| Days since install | Minimum gap between pop-up ads |
|---|---|
| 0–1 | 2 minutes |
| 2–6 | 100 seconds |
| 7–13 | 90 seconds |
| 14–30 | 80 seconds |
| 31+ | 1 minute |
The gap is a minimum, not a schedule. In our playthrough, the first session had no ads; the first pop-up ad played at the start of level 15, in a later session.
What it means for you. A calm start, then up to twice as many pop-up ads after a month.
The code. The level gate in the code, then the bundled config's gaps between ads, in seconds by days since install:
const DEFAULT_UNLOCK_LEVEL: int = 11
...
"param_key":"inter_cd_lc","param_value":"{120},{100},{90},{80},{60}"Why it matters. This is the fair part, and the most copyable: protect new players, then pace ads by tenure.
What a small team can ethically copy this week.
- Protect new users. No pop-up ads until they are invested: Meowdoku waits for level 11 and a second session.
- Pace by tenure. Shorten the gap between ads as users stay longer, from 2 minutes to 1 over a month.
- Test features with a subset of users. Meowdoku's shipped settings hold a 5% test group of US players out of banner ads.
6. The pressure level
What we found. In a test group of about 1 in 80 players, the code runs a rule it marks mark_g4_pressure_level. It kicks in when both are true:
- You hold more than 10 of any tool (hints and three others).
- Your tools and revives used today add up to fewer than 4.
Then levels ending in 3, from level 13, are forced to the hardest difficulty tier for your level range. On those levels:
- There is no "Hard" warning, unlike the game's scheduled hard levels.
- The puzzles have no one-square region, so there is no free first cat.
- The helper cat you'd have earned is skipped.
The developers' debug text calls it a "pressure level".
What it means for you. In that group, save up your hints and some levels ending in 3 jump to the top tier, with nothing telling you.
The code. The trigger: a level ending in 3 while you hold more than 10 of a tool:
elif ctx.level_num >= ENGAGE_MIN_LEVEL and ctx.level_num % 10 == TRIGGER_LEVEL_DIGIT and _pressure_condition_met():
...
if GameState.get_tool_count(kind) > STOCK_THRESHOLD:
...
GameState.mark_g4_pressure_level(_ctx.level_num)Why it matters. It's a test, and the code shows the trigger, not the reason. It is still the one difficulty rule we found that depends on what you own, not how well you play.
What a small team can ethically copy this week.
- Ease off when users struggle or stay away. Meowdoku makes your first level each day easier. Fail a level twice and the next ones get easier, sometimes with a free cat. Leave mid-level for three days and it swaps in an easier puzzle.
- Warn before a spike. Meowdoku labels its scheduled hard levels. Label every hard step you add.
Our verdict
In our view, Meowdoku isn't a puzzle game with a leaderboard. It's a competition simulator wrapped around ads.
To be fair, the puzzles themselves are real, and actually pretty fun. Given how popular the app is, they could easily build real social features.
What never to copy
- Fake players. Bots with human-style names and "Playing now" tags, with nothing saying they are bots.
- Fake stats. Random numbers shown as player stats. Show real numbers or none.