We develop achievement and leaderboard systems that retain players through secondary goals and social pressure. At first, it seems enough to have a flag in the database and a condition check, but in practice, after six months, pitfalls appear: counter desync after game reinstallation, inability to grant retroactive achievements, and conflicts in multithreaded environments. With 10+ years of experience and 50+ implemented projects, we navigate these issues at the architecture stage.
Why achievements are harder than they seem
At project start, achievements look simple: a flag in the database, a condition check, and a record. In practice, after six months of development, you discover:
Counter state desynchronization. An achievement "kill 100 goblins" requires a persistent counter that updates on each kill. If the player reinstalls the game, the counter resets—the achievement becomes unobtainable, even though it's marked as completed in Google Play / Game Center. This is a classic dual-state problem: local state and platform state diverge.
Retroactive achievements. The team adds a new achievement three months after launch. Players who already met the condition don't get it automatically. You need a backfill procedure—recalculating from the player's historical stats. If stats weren't stored, backfill is impossible, and players get angry.
Thread-safe counters. In a multithreaded environment (Unity with Jobs System, server-side logic), simultaneous counter increments without atomic operations yield incorrect values. Several events at once cause the counter to jump values. In 90% of cases, we see this problem during load testing.
Achievement system architecture
The working scheme is event-driven architecture through a central AchievementService. Instead of each game module knowing about achievements and calling AchievementManager.CheckCondition(), modules fire events: GameEvent.EnemyKilled(enemyType, count), GameEvent.LevelCompleted(levelId, stars). The AchievementService subscribes to the needed events and updates counters itself.
Each achievement is described by a config:
- type (
incremental,single,compound) - list of events it reacts to
- completion condition (lambda or ScriptableObject with logic)
- reward
Adding a new achievement means a new config, with no changes to game code.
Platform synchronization. Google Play Games Services and Apple Game Center have their own leaderboards and achievements, but working with them directly is painful. The GPG SDK for Unity works only on Android, Game Center only on iOS. For cross-platform projects, we use an intermediate layer: our own database stores the master state, while platform SDKs are updated as satellites. On conflict (offline session), we merge using the "take max" principle for incremental counters.
Achievement (video games) PlayFab and GameSparks provide ready server-side achievement systems with APIs—for mobile F2P, this is often faster and cheaper than a custom backend.
How to avoid cheaters in leaderboards?
Client-side score submission without validation is a straight path to cheaters at the top. Minimum: score is signed with an HMAC key on the client, server verifies the signature. The proper way: the server calculates the score from game session logs; the client only sends events. We implement anti-cheat on both levels: client-side build integrity checks, server-side anomaly monitoring (e.g., a sudden 300% counter spike in 3 seconds).
Leaderboards: complexity at scale
For a game with 1000 concurrent players, SQLite or PostgreSQL with ORDER BY score DESC LIMIT 100 works fine. At 100k+ records, queries without proper indexes start slowing down. At 1M+, you need Redis Sorted Set.
Redis ZADD leaderboard {score} {userId} + ZREVRANK leaderboard {userId} gives O(log N) insertion and O(log N) rank retrieval. ZREVRANGE leaderboard 0 99 WITHSCORES gives the top 100 in microseconds. This is the standard for mobile games with large audiences.
Weekly and seasonal leaderboards. A separate table (or Redis Sorted Set) per period plus a cron job for rotation. On rotation—snapshot winners to archive, distribute rewards via a queue (not synchronously—with a large audience, synchronous reward distribution kills the server).
What’s included in the work
| deliverable | description |
|---|---|
| API documentation and data schemas | description of events, configs, and endpoints |
| Game designer tool | achievement config editor (web interface or Unity/Unreal plugin) |
| Platform integration | GPG, Game Center, PlayFab—including sync and conflict merge |
| Load testing | leaderboard testing with 1000+ concurrent requests |
| Post-launch support | bug fixing, config tweaks, team consultations |
Development stages
- Schema design—achievement types, events, state storage, platforms.
- Server side—tables/Redis, API endpoints, anti-cheat.
- Client integration—AchievementService, event subscriptions, UI.
- Platform synchronization—GPG / Game Center / PlayFab.
- Game designer tools—achievement config editor.
- QA—retroactive achievement testing, offline scenario testing, leaderboard load testing.
| Scope | Timeline |
|---|---|
| Local achievements without server (mobile/casual) | 1–2 weeks |
| Server-based achievements + leaderboards for one platform | 3–5 weeks |
| Cross-platform system with anti-cheat and seasonal leaderboards | 6–12 weeks |
Cost is determined individually after analyzing your project architecture and scalability requirements. Evaluate your project—contact us, and we'll provide a plan tailored to your budget.





