Achievements
Declare a handful of achievements and unlock them from your game when the player earns one.
Platform achievements are a curated set of accomplishments worth showing outside your game and sharing with other players. The platform lists them on the game page and shows a popup the moment one is earned. Your game decides when each one is earned. Earned once, for good.
Choosing Milestones
Your game can have a much larger internal achievement system. Keep its full checklist, and the numbers behind it, in cloud saves, and select a handful of memorable accomplishments for Remix: a major milestone, a difficult challenge, or a surprising feat. A clicker with hundreds of internal badges does not need to publish every badge, upgrade or repeated milestone.
Each kind of player data has one home:
- Lifetime counters, content unlocks and settings live in the save.
- Anything players compete on, such as a best combo or a fastest lap, is a leaderboard.
- Anything worth showing off is an achievement your game unlocks.
The declaration limit is a ceiling, not a target. Keep existing published achievements and earned progress when updating a game.
Declaring Achievements
{
"achievements": [
{
"key": "first-blood",
"name": "First Blood",
"description": "Land your first kill.",
"icon": "assets/achievements/first-blood.png"
},
{
"key": "centurion",
"name": "Centurion",
"description": "One hundred kills.",
"hidden": true
}
]
}
| Field | Meaning |
|---|---|
key | Stable slug. Your game unlocks the achievement by this key. |
name | A short, catchy title of at most 24 characters, like "Harbor Sprint" or "Untouchable". Shown on the game page and in the popup. |
description | What the player did to earn it. Shown under the name. |
icon | A square PNG or WebP under assets/. Publish hosts it with the game and the platform shows it instead of the default badge. Subfolders are fine. |
hidden | Keeps the achievement off the game page until earned. |
Unlocking from the Game
Keep the numbers behind an achievement in your save, and call unlock when they cross the line:
await sdk.ready()
save.totalKills += 1
sdk.singlePlayer.actions.saveGameState({ gameState: save })
if (save.totalKills >= 1) sdk.achievements.unlock('first-blood')
if (save.totalKills >= 100) sdk.achievements.unlock('centurion')
sdk.achievements.isUnlocked('first-blood') // synchronous cached state
sdk.achievements.onUnlocked((keys) => celebrate(keys)) // newly earned while the game runs
Remix shows each achievement as locked or earned. To show progress toward one, such as 37 of 100 kills, read the counter from your save and draw it in your game.
unlock(key) resolves one of:
{ ok: true, key, unlocked, unlockedAt }.unlockedisfalsewhen the player had already earned it, so callingunlockagain is harmless. Unlocking on boot for a save that already qualifies is fine.{ ok: false, code, reason }when refused:not_foundfor a key yourremix.jsondoes not declare,throttledfor too many unlocks, orunavailablewhen the platform cannot record it now (retry later).nullfor guests and hosts without achievements. Never block play on the answer.
onUnlocked receives each key newly earned while the game runs, once: from an unlock call that earned it, or a refresh() that finds one earned on another device. Achievements the player already had at boot are never announced. The host already shows the platform popup; use the callback for in-game celebration, not a second popup.
An In-Game Achievements Screen
Draw your own screen from the same reads. list() answers every declared achievement, hidden ones included, and unlocked() answers the earned keys with their unlock time:
const earned = sdk.achievements.unlocked() // { [key]: ISO time }
for (const achievement of sdk.achievements.list()) {
const at = earned[achievement.key]
if (achievement.hidden && !at) {
addRow({ name: 'Secret', locked: true })
} else {
addRow({
name: achievement.name,
description: achievement.description,
icon: achievement.icon, // hosted URL, or null for your own default badge
locked: !at,
})
}
}
Call sdk.achievements.refresh() when the screen opens if the player may have earned one on another device; it resolves the latest snapshot, or null.
Icons
Icons make achievements feel earned. Keep them square, at least 256 by 256, on a background that reads at 44 pixels. In Remix Desktop, the agent can propose a matching icon set for every declared achievement in the game's art style; you generate and save each one from the review card. Saved icons land under assets/achievements/ and are picked up on the next publish.
Where Players See Them
- The game page on the mobile app, remix.gg and Remix Desktop lists every visible achievement with its icon and earned state.
- Library cards on Remix Desktop summarise earned counts.
- A popup appears on the surface the player is on the moment an achievement is earned.
Game achievements carry no XP and no trophy tier; they are the game's own.
Limits
Each game can declare a limited number of achievements, and never more than 64. Remix Desktop shows your game's limit on its Details page, and a declaration past it is refused at publish with a warning. See Limits.