> For the complete documentation index, see [llms.txt](https://wiki.playgama.com/playgama/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://wiki.playgama.com/playgama/bridge-sdk/api/achievements.md).

# Achievements

{% hint style="info" %}
You are reading the documentation for Bridge SDK **v2**. If you need the obsolete v1 documentation, see [Documentation (v1)](https://wiki.playgama.com/playgama/bridge-sdk-v1).
{% endhint %}

Use achievements to mark in-game milestones, such as defeating the first boss or collecting 100 coins.

## Configuration

Declare your achievements once in the [config](/playgama/bridge-sdk/config.md). Each entry has a game-level `id` you use in code, optional `name`/`description` for your own UI, and per-platform blocks with the ids the platform dashboard expects:

```json
{
    "achievements": [
        {
            "id": "level_10",
            "name": "Level 10",
            "description": "Reach level 10",
            "y8": { "achievement": "Level 10", "achievementkey": "abc123" },
            "lagged": { "id": "lagged_achievement_id" }
        }
    ]
}
```

* In code you always work with the flat game-level `id` (`level_10`).
* The per-platform blocks are only needed for platforms with native achievements — the SDK maps the game-level id to them automatically.
* On all other platforms the configured list drives the SDK-managed local tracking; `name` and `description` are returned as-is for your UI.

## Unlock achievement

Unlock an achievement after the player meets its in-game condition. Send each achievement only once.

{% tabs %}
{% tab title="Plain JS" %}

```javascript
bridge.achievements.unlock('level_10')
    .then(() => {
        // success
    })
    .catch(error => {
        // error
    })
```

{% endtab %}

{% tab title="Unity" %}

```csharp
Bridge.achievements.Unlock("level_10", success =>
{
    Debug.Log($"Achievement unlocked: {success}");
});
```

{% endtab %}

{% tab title="Construct 3" %}
Call the `Achievements Unlock` action with the game-level achievement id, then handle the `On Achievements Unlock Completed` trigger.

<details>

<summary>Copy This Example</summary>

```
{"is-c3-clipboard-data":true,"type":"events","items":[{"eventType":"block","conditions":[{"id":"on-clicked","objectClass":"Button"}],"actions":[{"id":"achievements-unlock","objectClass":"PlaygamaBridge","parameters":{"id":"\"level_10\""}}]},{"eventType":"block","conditions":[{"id":"on-achievements-unlock-completed","objectClass":"PlaygamaBridge"}],"actions":[],"children":[{"eventType":"block","conditions":[{"id":"is-last-action-completed-successfully","objectClass":"PlaygamaBridge"}],"actions":[{"type":"comment","text":"success"}]}]}]}
```

</details>
{% endtab %}

{% tab title="GDevelop" %}
Call the `Achievements Unlock` action with the game-level achievement id, then handle the `On Achievements Unlock Completed` condition.

<details>

<summary>Copy This Example</summary>

```
{"000kind":"GDEVELOP_EventsAndInstructions_CLIPBOARD_KIND-jsBdHbLy912y8Rc","content":{"eventsList":[{"type":"BuiltinCommonInstructions::Standard","conditions":[{"type":{"value":"PanelSpriteButton::PanelSpriteButton::IsClicked"},"parameters":["Button",""]}],"actions":[{"type":{"value":"PlaygamaBridge::AchievementsUnlock"},"parameters":["","\"level_10\"",""]}]},{"type":"BuiltinCommonInstructions::Standard","conditions":[{"type":{"value":"PlaygamaBridge::OnAchievementsUnlockCompleted"},"parameters":["",""]}],"events":[{"type":"BuiltinCommonInstructions::Standard","conditions":[{"type":{"value":"PlaygamaBridge::IsLastActionCompletedSuccessfully"},"parameters":["",""]}],"actions":[{"type":{"value":"DebuggerTools::ConsoleLog"},"parameters":["\"success\"","\"info\"",""]}]}],"actions":[]}],"eventsCount":2,"actionsList":[],"actionsCount":0,"conditionsList":[],"conditionsCount":0}}
```

</details>
{% endtab %}

{% tab title="Godot" %}
{% tabs %}
{% tab title="Godot 3.x" %}

```gdscript
Bridge.achievements.unlock("level_10", funcref(self, "_on_unlock_completed"))

func _on_unlock_completed(success):
    print(success)
```

{% endtab %}

{% tab title="Godot 4.x" %}

```gdscript
Bridge.achievements.unlock("level_10", Callable(self, "_on_unlock_completed"))

func _on_unlock_completed(success):
    print(success)
```

{% endtab %}
{% endtabs %}
{% endtab %}

{% tab title="GameMaker" %}

```javascript
playgama_bridge_achievements_unlock("level_10")

// callback via Async Social Event
if async_load[? "type"] == "playgama_bridge_achievements_unlock_callback" {
    if async_load[? "success"] {
        // your logic
    }
}
```

{% endtab %}

{% tab title="Defold" %}

```lua
local bridge = require("bridge.bridge")

function init(self)
    bridge.achievements.unlock(
        "level_10",
        function ()
            -- success
        end,
        function ()
            -- error
        end
    )
end
```

{% endtab %}

{% tab title="Cocos Creator" %}

```javascript
bridge.achievements.unlock('level_10')
    .then(() => {
        // success
    })
    .catch(error => {
        // error
    })
```

{% endtab %}
{% endtabs %}

## Get achievements

Returns the full achievements list in a normalized, platform-agnostic shape with the player's unlocked state:

```javascript
[
    {
        id: 'level_10',       // game-level id from the config
        name: 'Level 10',     // optional
        description: '...',   // optional
        unlocked: true
    }
]
```

On native platforms the ids are mapped back to your game-level ids. On other platforms the SDK returns the configured list with the locally tracked `unlocked` flag (an empty array when nothing is configured).

{% tabs %}
{% tab title="Plain JS" %}

```javascript
bridge.achievements.getAchievements()
    .then(achievements => {
        achievements.forEach(achievement => {
            console.log(achievement.id, achievement.unlocked)
        })
    })
    .catch(error => {
        // error
    })
```

{% endtab %}

{% tab title="Unity" %}

```csharp
private void Start()
{
    Bridge.achievements.GetAchievements(OnGetAchievementsCompleted);
}

private void OnGetAchievementsCompleted(bool success, List<Dictionary<string, string>> achievements)
{
    if (success)
    {
        foreach (var achievement in achievements)
        {
            Debug.Log($"{achievement["id"]}: {achievement["unlocked"]}");
        }
    }
}
```

{% endtab %}

{% tab title="Construct 3" %}
Call the `Achievements Get List` action, then handle the `On Achievements Get List Completed` trigger. Read the result with the `AchievementsCount` and `AchievementPropertyValue(achievementIndex, property)` expressions (`property` is a field name like `"id"`, `"name"`, `"description"`, `"unlocked"`).

<details>

<summary>Copy This Example</summary>

```
{"is-c3-clipboard-data":true,"type":"events","items":[{"eventType":"block","conditions":[{"id":"on-clicked","objectClass":"Button"}],"actions":[{"id":"achievements-get-list","objectClass":"PlaygamaBridge"}]},{"eventType":"block","conditions":[{"id":"on-achievements-get-list-completed","objectClass":"PlaygamaBridge"}],"actions":[],"children":[{"eventType":"block","conditions":[{"id":"for","objectClass":"System","parameters":{"name":"\"achievements\"","start-index":"0","end-index":"PlaygamaBridge.AchievementsCount - 1"}}],"actions":[{"id":"log","objectClass":"Browser","parameters":{"type":"log","message":"PlaygamaBridge.AchievementPropertyValue(loopindex(\"achievements\"), \"id\") & \": \" & PlaygamaBridge.AchievementPropertyValue(loopindex(\"achievements\"), \"unlocked\")"}}]}]}]}
```

</details>
{% endtab %}

{% tab title="GDevelop" %}
Call the `Achievements Get List` action, then handle the `On Achievements Get List Completed` condition. Read the result with the `PlaygamaBridge::AchievementsCount()` and `PlaygamaBridge::AchievementPropertyValue(achievementIndex, property)` expressions (`property` is a field name like `"id"`, `"name"`, `"description"`, `"unlocked"`).

<details>

<summary>Copy This Example</summary>

```
{"000kind":"GDEVELOP_EventsAndInstructions_CLIPBOARD_KIND-jsBdHbLy912y8Rc","content":{"eventsList":[{"type":"BuiltinCommonInstructions::Standard","conditions":[{"type":{"value":"PanelSpriteButton::PanelSpriteButton::IsClicked"},"parameters":["Button",""]}],"actions":[{"type":{"value":"PlaygamaBridge::AchievementsGetList"},"parameters":["",""]}]},{"type":"BuiltinCommonInstructions::Standard","conditions":[{"type":{"value":"PlaygamaBridge::OnAchievementsGetListCompleted"},"parameters":["",""]}],"actions":[{"type":{"value":"SetNumberVariable"},"parameters":["CurrentIndex","=","0"]}],"events":[{"type":"BuiltinCommonInstructions::Repeat","repeatExpression":"PlaygamaBridge::AchievementsCount()","conditions":[],"actions":[],"events":[{"type":"BuiltinCommonInstructions::Standard","conditions":[],"actions":[{"type":{"value":"DebuggerTools::ConsoleLog"},"parameters":["PlaygamaBridge::AchievementPropertyValue(CurrentIndex, \"id\") + \": \" + PlaygamaBridge::AchievementPropertyValue(CurrentIndex, \"unlocked\")","\"info\"",""]},{"type":{"value":"SetNumberVariable"},"parameters":["CurrentIndex","+","1"]}]}]}]}],"eventsCount":2,"actionsList":[],"actionsCount":0,"conditionsList":[],"conditionsCount":0}}
```

</details>
{% endtab %}

{% tab title="Godot" %}
{% tabs %}
{% tab title="Godot 3.x" %}

```gdscript
Bridge.achievements.get_achievements(funcref(self, "_on_get_achievements_completed"))

func _on_get_achievements_completed(success, achievements):
    if success:
        for achievement in achievements:
            print(achievement.id, ": ", achievement.unlocked)
```

{% endtab %}

{% tab title="Godot 4.x" %}

```gdscript
Bridge.achievements.get_achievements(Callable(self, "_on_get_achievements_completed"))

func _on_get_achievements_completed(success, achievements):
    if success:
        for achievement in achievements:
            print(achievement.id, ": ", achievement.unlocked)
```

{% endtab %}
{% endtabs %}
{% endtab %}

{% tab title="GameMaker" %}

```javascript
playgama_bridge_achievements_get_achievements()

// callback via Async Social Event
if async_load[? "type"] == "playgama_bridge_achievements_get_achievements_callback" {
    if async_load[? "success"] {
        var achievements = json_parse(async_load[? "data"])
        for (var i = 0; i < array_length(achievements); i += 1) {
            var achievement = achievements[i]
            // achievement.id, achievement.unlocked
        }
    }
}
```

{% endtab %}

{% tab title="Defold" %}

```lua
local bridge = require("bridge.bridge")

function init(self)
    bridge.achievements.get_achievements(
        function (_, achievements_json)
            local achievements = json.decode(achievements_json)
            for _, achievement in ipairs(achievements) do
                print(achievement.id, achievement.unlocked)
            end
        end,
        function ()
            -- error
        end
    )
end
```

{% endtab %}

{% tab title="Cocos Creator" %}

```javascript
bridge.achievements.getAchievements()
    .then(achievements => {
        achievements.forEach(achievement => {
            console.log(achievement.id, achievement.unlocked)
        })
    })
    .catch(error => {
        // error
    })
```

{% endtab %}
{% endtabs %}

<details>

<summary>Native platform achievements · 2 of 26 platforms</summary>

**Native:** `lagged`, `y8`

**SDK-managed local tracking:** `crazy_games`, `discord`, `dlightek`, `facebook`, `game_distribution`, `gamepush`, `gamesnacks`, `huawei`, `jio_games`, `microsoft_store`, `msn`, `ok`, `playdeck`, `playgama`, `poki`, `portal`, `reddit`, `samsung`, `telegram`, `tiktok`, `vk`, `xiaomi`, `yandex`, `youtube`

</details>
