Achievements
Track achievement unlocks for your players. Define achievements in the dashboard, unlock them from GDScript, and the SDK handles caching and offline access.
Functions
Section titled “Functions”unlock_achievement()
Section titled “unlock_achievement()”QuestData.unlock_achievement(achievement_key: String, callback: Callable = Callable())| Parameter | Type | Default | Description |
|---|---|---|---|
achievement_key | String | required | Unique key matching the achievement defined in the dashboard |
callback | Callable | Callable() | Called with a response Dictionary |
Callback response:
| Key | Type | Description |
|---|---|---|
success | bool | Whether the unlock succeeded |
already_unlocked | bool | true if achievement was already unlocked |
achievement | Dictionary | Achievement details (name, description, points) |
total_points | int | Player’s total achievement points after unlock |
If the achievement was already unlocked, success is still true but already_unlocked is true.
get_achievements()
Section titled “get_achievements()”QuestData.get_achievements(callback: Callable = Callable())Fetches all achievements with the current player’s unlock status.
Callback signature: func(achievements: Array, total_points: int, unlocked_points: int)
Each achievement in the Array is a Dictionary with: key, name, description, points, hidden, unlocked, unlocked_at.
get_achievements_cached()
Section titled “get_achievements_cached()”QuestData.get_achievements_cached() -> DictionaryReturns cached achievement data synchronously. The Dictionary contains:
achievements: Array of achievement Dictionariestotal_points: Total available pointsunlocked_points: Player’s earned points
Returns an empty Dictionary if no data has been fetched yet.
clear_achievement_cache()
Section titled “clear_achievement_cache()”QuestData.clear_achievement_cache()Clears the local achievement cache, forcing a re-fetch on next get_achievements() call.
Example
Section titled “Example”# Unlock on boss defeatfunc _on_boss_defeated(boss_id: String): if boss_id == "final_boss": QuestData.unlock_achievement("beat_final_boss", func(response: Dictionary): if response.get("success") and not response.get("already_unlocked"): show_achievement_popup(response["achievement"]) )
# Display achievement listfunc show_achievements(): QuestData.get_achievements(func(achievements: Array, total: int, unlocked: int): progress_label.text = "%d / %d points" % [unlocked, total] for ach in achievements: if ach["hidden"] and not ach["unlocked"]: add_hidden_entry() else: add_achievement_entry(ach) )
# Quick check from cache (no network)func has_achievement(key: String) -> bool: var cached = QuestData.get_achievements_cached() for ach in cached.get("achievements", []): if ach["key"] == key and ach["unlocked"]: return true return falseHow It Works
Section titled “How It Works”- Define achievements in the dashboard under Players > Achievements (key, name, description, points, hidden)
unlock_achievement()sends a POST to/v1/achievements/unlock- The server records the unlock and returns the achievement details
- The local cache is updated immediately (no re-fetch needed)
get_achievements()fetches the full list with unlock status from the server- Achievement data is cached to disk and available offline
Dashboard
Section titled “Dashboard”Manage achievements under Players > Achievements:
- Create/Edit — Define achievements with key, name, description, points
- Hidden achievements — Mark achievements as hidden (shown as ”???” until unlocked)
- Global unlock rates — See what percentage of players have each achievement
- Player lookup — Check which achievements a specific player has unlocked
Best Practices
Section titled “Best Practices”- Use stable keys — Achievement keys can’t be changed after creation; use descriptive ones like
"beat_level_10"not"ach_1" - Check
already_unlocked— Don’t show the popup again if the player already has it - Cache for UI — Use
get_achievements_cached()in menus to avoid network calls on every open - Hidden achievements — Great for spoiler-sensitive content; players see ”???” until they unlock it
- Fetch on game start — Call
get_achievements()early so the cache is warm