Achievements and Leaderboard System Development
Achievements and leaderboards are not decorative. Properly structured achievement system retains player through side goals, and leaderboard creates social pressure working better than most push-notifications. But technically both systems have non-obvious pitfalls even experienced teams stumble on.
Why achievements are harder than they seem
At project start achievements look simple: flag in database, condition check, write record. In practice after half-year development discover:
Counter state desynchronized. Achievement "kill 100 goblins" requires persistent counter updating on each kill. If player reinstalled game, counter reset — achievement already can't be obtained, though on Google Play / Game Center marked as completed. Classic dual-state problem: local state and platform state diverge.
Retroactive achievements. Team adds new achievement three months after launch. Players who already met condition don't get it automatically. Need backfill procedure — recalculate from player's historical stats. If stats weren't stored — backfill impossible, players angry.
Thread-safety of counters. In multi-threaded environment (Unity with Jobs System, server logic) simultaneous counter increment without atomic operations gives wrong values. Several events at once — counter jumps over values.
Achievement system architecture
Working scheme — event-driven architecture via central AchievementService. Instead of every game module knowing about achievements and calling AchievementManager.CheckCondition(), modules throw events: GameEvent.EnemyKilled(enemyType, count), GameEvent.LevelCompleted(levelId, stars). AchievementService subscribed to needed events and updates counters itself.
Each achievement described by config:
- type (
incremental,single,compound) - list of events it reacts to
- completion condition (lambda or ScriptableObject with logic)
- reward
Adding new achievement — new config, no game code changes.
Sync with platforms. Google Play Games Services and Apple Game Center have own leaderboards and achievements, but working with them directly is pain. GPG SDK for Unity works only on Android, Game Center — only on iOS. For cross-platform projects use intermediary layer: own database holds master-state, platform SDKs update as satellites. On conflict (offline session) — merge by "take max" principle for incremental counters.
PlayFab and GameSparks provide ready server achievement systems with API — for mobile F2P often faster and cheaper than own backend.
Leaderboards: complexity at scale
For game with 1000 simultaneous players SQLite or Postgres with ORDER BY score DESC LIMIT 100 work fine. At 100k+ records query without proper indexes starts lagging. At 1M+ need Redis Sorted Set.
Redis ZADD leaderboard {score} {userId} + ZREVRANK leaderboard {userId} gives O(log N) insert and O(log N) rank get. ZREVRANGE leaderboard 0 99 WITHSCORES — top-100 in microseconds. Standard for mobile games with large audience.
Leaderboard anti-cheat. Client score submit without validation — straight road to cheaters on first place. Minimum: score signed with HMAC-key on client, server verifies signature. Normal: server calculates score from game session logs, client only sends events.
Weekly and seasonal leaderboards. Separate table (or separate Redis Sorted Set) per period + cron-job for rotation. On rotation — snapshot winners to archive, reward distribution via queue (not synchronously — large audience sync distribution kills server).
Development stages
- Design scheme — achievement types, events, state storage, platforms
- Server part — tables/Redis, API endpoints, anti-cheat
- Client integration — AchievementService, event subscriptions, UI
- Platform sync — GPG / Game Center / PlayFab
- Designer tools — achievement config editor
- QA — test retroactive achievements, offline scenarios, leaderboard load-test
| Scale | Duration |
|---|---|
| Local achievements no server (mobile/casual) | 1–2 weeks |
| Server achievements + leaderboards one platform | 3–5 weeks |
| Cross-platform with anti-cheat and seasonal leaderboards | 6–12 weeks |
Cost determined individually after project architecture analysis and scalability requirements.





