Stats are numbers that track progress per player — total kills, distance run, games played. Achievements are milestones players unlock, like "First Blood" or "Centurion." You define both in the Developer Portal and interact with them from your game through the SDK.
Setting up achievements
Go to Developer Portal → your game → Achievements to create and manage achievements. You can add them one at a time or bulk import via JSON.
Each achievement has:
| Field | Required | Description |
|---|---|---|
| ID | Yes | A unique identifier like FIRST_BLOOD |
| Title | Yes | The display name players see, like "First Blood" |
| Description | Yes | What the player did to earn it |
| Image | No | A custom icon shown in the achievement list |
| Trigger rule | No | Automatically unlock when a stat reaches a threshold |
Achievements can be unlocked in two ways:
- Manually — your game calls the SDK to unlock it
- Automatically — you set a trigger rule (e.g. "Total Kills is at least 100") and Wavedash unlocks it when the stat threshold is reached
Bulk import
Click Add achievement → Import JSON to import multiple achievements and stats at once. The expected format:
{
"achievements": [
{
"identifier": "FIRST_KILL",
"display_name": "First Blood",
"description": "Get your first kill",
"stat_requirement": null
},
{
"identifier": "GOLD_100K",
"display_name": "Rich!",
"description": "Collect 100,000 gold",
"stat_requirement": {
"stat": "GOLD_COLLECTED",
"threshold": 100000
}
}
],
"stats": [
{
"identifier": "GOLD_COLLECTED",
"display_name": "Gold Collected"
}
]
}
Existing items (matched by identifier) are skipped.
Setting up stats
Go to Developer Portal → your game → In-Game Stats to define stats. Each stat has an ID and a display name. Stats are integers that persist across sessions.
Working with stats
func _ready():
WavedashSDK.got_stats.connect(_on_got_stats)
func load_stats():
WavedashSDK.request_stats()
func _on_got_stats(response):
if response.get("success", false):
var kills = WavedashSDK.get_stat_int("total_kills")
print("total_kills: ", kills)
func add_kill():
var kills = WavedashSDK.get_stat_int("total_kills") + 1
WavedashSDK.set_stat_int("total_kills", kills, true)
All platforms support a storeNow parameter: setStat("id", value, true) and setAchievement("id", true). When storeNow is true, the SDK schedules a persist immediately (debounced over 1 second). For an immediate flush, call storeStats() explicitly. The platform also flushes pending stats when the session ends.
Unlocking achievements
WavedashSDK.set_achievement("first_win")
func has_first_win() -> bool:
return WavedashSDK.get_achievement("first_win")
Storing stats and achievements together
Batch stat updates and achievement unlocks, then send them in one call:
WavedashSDK.set_stat_int("total_kills", 200, false)
WavedashSDK.set_achievement("first_blood")
WavedashSDK.store_stats()
Example: kill tracking
var session_kills: int = 0
func on_enemy_killed() -> void:
var kills = WavedashSDK.get_stat_int("total_kills") + 1
WavedashSDK.set_stat_int("total_kills", kills, true)
session_kills += 1
if kills == 1:
WavedashSDK.set_achievement("first_blood")