Our first league system had 5 ranks: Rookie, Sharp, Clever, Genius, Mastermind. The idea was simple — play games, earn PQ, move up. The problem? Casual players never moved.
A casual Cabo player who plays 3 times a week earns maybe 2-3 PQ points. The threshold from Rookie to Sharp was 50 PQ. At 2.5 points per week, that’s 20 weeks — five months — to promote. Nobody’s going to stick around for five months to go from “Rookie” to “Sharp.”
The design flaw: PQ delta is too compressed. It’s a skill score, not an engagement score. Leagues need weekly movement, and skill moves slowly by definition.
Five ranks, five months of stagnation
The original system used PQ bands:
| Rank | PQ range | Problem |
|---|---|---|
| Rookie | 1000–1050 | 90% of players stuck here forever |
| Sharp | 1050–1150 | Weekly delta of 2-5 points = no movement |
| Clever | 1150–1300 | Only hardcore players ever see this |
| Genius | 1300–1500 | 2% of players |
| Mastermind | 1500+ | Nobody reached this |
With only 5 tiers, promotions were rare and demotions were even rarer (you’d need to lose PQ, which requires not playing for weeks). The system felt static.
52 tiers, weekly movement
We replaced the 5 PQ bands with 52 league tiers. Each tier has a name, a rank, and two thresholds: promotionThreshold and demotionThreshold in weekly XP.
[
{ "id": "bronze", "pqLeague": true, "promotionThreshold": 50, "demotionThreshold": 0, "title": "Bronze" },
{ "id": "silver", "pqLeague": true, "promotionThreshold": 150, "demotionThreshold": 20, "title": "Silver" },
{ "id": "gold", "pqLeague": true, "promotionThreshold": 400, "demotionThreshold": 80, "title": "Gold" },
{ "id": "platinum", "pqLeague": true, "promotionThreshold": 800, "demotionThreshold": 250, "title": "Platinum" },
{ "id": "diamond", "pqLeague": true, "promotionThreshold": 1500, "demotionThreshold": 500, "title": "Diamond" },
{ "id": "obsidian", "pqLeague": true, "promotionThreshold": 2500, "demotionThreshold": 1000, "title": "Obsidian" },
{ "id": "mythril", "pqLeague": true, "promotionThreshold": 4000, "demotionThreshold": 1800, "title": "Mythril" }
]Bronze 1 promotes at 50 XP. A casual player who plays 3 Cabo games and 2 Trek puzzles in a week can easily earn 150+ XP. That’s promotion to Silver 1 in the first week. The next week, 400 XP means Gold 1. Within a month, they’re in Platinum — with a real sense of progress.
The full 52 tiers go from Bronze 1 through Legendary 52. We only configured 7 with thresholds in the initial Remote Config. The remaining 45 tiers inherit sensible defaults. This lets us start hard and soften later — easier to nerf upward than tighten downward.
Why weekly XP, not weekly PQ delta
This is the key insight. PQ delta in a week is 0–80 for the vast majority of players. Weekly XP delta is 0–10,000+. The spread in XP creates real differentiation in the league — you can clearly see who played hard this week. The spread in PQ delta makes everyone look the same.
The two metrics coexist:
pq— long-term skill identity. Displayed on profiles. Rarely moves more than 20 points per week.weeklyXPDelta— this week’s engagement. Drives league migration. Resets every Monday. Moves hundreds or thousands of points.
The ghosting paradox
Inactive players (weeklyXPDelta == 0) are skipped entirely during league migration. They keep their current league. This means:
- An active Silver player who earned 80 XP stays Silver (below the 150 threshold).
- An inactive Diamond player who earned 0 XP stays Diamond.
This feels wrong at first. A Diamond player who hasn’t logged in for a week is still Diamond, while a Silver player who played every day can’t reach Gold.
But the alternative is worse: demoting inactive players creates a “welcome back to Bronze” experience. A player who returns after two weeks and finds themselves demoted to Bronze 1 is more likely to uninstall than to grind back up. League preservation for inactive players is a retention trade-off.
Remote Config, not app updates
All league thresholds are in Firebase Remote Config. If Bronze 1 promotes too easily at 50 XP, we change it to 75 in the Firebase console. No app update, no review cycle, no waiting for users to update. The pqLeagueboolean flag also lets us A/B test the league system — some users see it, some don’t, and we compare retention.
What I’d Tell My Past Self
- 5 tiers create stagnation. 52 tiers create momentum. More rungs on the ladder means everyone can see progress weekly.
- Use XP for leagues, PQ for profiles. XP has 100× more spread. Duolingo proved this works.
- Don’t demote inactive players. It’s a retention loss. Let them keep their league. They’ll demote naturally when they start playing again.
- Start hard, soften later. It’s easier to lower thresholds than raise them. Start with promotion at 50 XP and observe.
- Remote Config everything. The day after launch, you’ll want to adjust thresholds. Make it a config change, not a code change.
