Overview of the Xbox Achievements Manager API

The Xbox Achievements Manager API simplifies keeping track of, and updating the state of an Xbox Live user's achievements.

Xbox provides a way to keep track of a user's progress and accomplishments in their games by awarding Achievements at certain points. Using the achievements APIs in the Xbox Services API (XSAPI) to keep each local user's Achievement information up to date can be complicated. Not doing this correctly can result in performance issues, stale data, or being throttled due to calling the Xbox achievement services more frequently than necessary.

The Social Manager solves this problem by:

  • Creating a simple API to call.
  • Creating up to date information using the real time activity service behind the scenes.
  • Developers can call the Achievements Manager API synchronously without any extra strain on the service.

The Achievements Manager masks the complexity of dealing with multiple RTA subscriptions, refreshing data for users, and reducing the number of calls to the achievements service and allows developers to easily get the up to date achievement data.

Features

The Achievements Manager provides the following features:

  • Simplified Achievements API
  • Up-to-date achievement state and progress for each user
  • Reduce number of calls to Xbox services
    • This directly correlates to overall latency reduction in data acquisition
  • Thread safe
  • Efficiently keeping data up to date

Core Concepts

Achievements: An Achievement includes Gamerscore and other rewards such as digital artwork, new maps, characters, and stat boosts, as well as the current progress towards completion.

To keep the state of a user's achievements up to date, the function XblAchievementsManagerDoWork must be called every frame.

Note

On Windows there can only be one local user

API Overview

You will most frequently use the following key APIs.

You can find a complete description of the Achievements Manager APIs in the Xbox Live API reference. You can also find the APIs in the XblAchievementsManager prefix documentation.

Adding local users to Achievements Manager

Adding a local user to Achievements Manager causes the state of all achievements for that user for the current title to be fetched from the service and saved locally.

The Achievements Manager will keep each of that user's achievements for the current title up to date.

Getting the state of achievements for a user

Calling this function returns a handle to achievement(s) that match specified criteria.

Achievements pointed to by the handle are thread-safe copies of the matching achievements. The data pointed to by the handle will exist until the handle is closed, but may become out of date if the title holds the handle past the next call to XblAchievementsManagerDoWork.

Usage

Using Achievements Manager events

Achievements Manager tells you what happened, in the form of events. You can use those events to update your UI or perform other logic.

C API

// some update loop in the game
while(true) 
{ 
    size_t eventsCount{}; 
    const XblAchievementsManagerEvent* events{}; 
    HRESULT hr = XblAchievementsManagerDoWork(&events, &eventsCount); 
    if (FAILED(hr))
    {
        // handle the error
    }

    for (uint32_t i = 0; i < eventsCount; ++i) 
    { 
        // act on the event
        switch (events[i].eventType) 
        { 
        case XblAchievementsManagerEventType::LocalUserInitialStateSynced: 
            // ...
            break; 
        case XblAchievementsManagerEventType::AchievementProgressUpdated: 
            // ...
            break; 
        case XblAchievementsManagerEventType::AchievementUnlocked: 
            // ...
            break; 
        default: 
            break; 
        } 
    } 
} 

Reference

Events returned

Local User Initial State Synced: Triggers when the achievements manager has completed fetching the current state of all of the current title's achievements for the user.

Achievement Progress Updated: Triggers when a user's progress for an achievement of the current title has been updated.

Achievement Unlocked: Triggers when a user completes all requirements for an achievement of the current title.

Additional details

Instead of fetching the state of achievements from the service frequently during the game loop, the Achievements Manager fetches the state of all of a user's achievements when the user is registered with the Achievements Manager. Then the Achievements Manager receives events from the service detailing updates to a user's achievements, which are then forwarded to the title as events returned by the * XblAchievementsManagerDoWork function.

events is a list of XblAchievementsManagerEvent, and each XblAchievementsManagerEvent contains a change to an achievement that occurred during the last frame.

More information can be found in the XblAchievementsManagerEvent API documentation.

Register a user for whom to track achievements

In this scenario, you want to register a user to the achievements manager to begin tracking updates to that user's achievements, and cache the state of all of those user's achievements locally.

C API

HRESULT hr = XblAchievementsManagerAddLocalUser(userHandle, nullptr);

if (!SUCCEEDED(hr))
{
    return;
}

// some update loop in the game 
while(true)
{
    const XblAchievementsManagerEvent* events{ nullptr };
    size_t eventCount{ 0 };
    HRESULT hr = XblAchievementsManagerDoWork(&events, &eventCount);
    if (SUCCEEDED(hr))
    {
        return;   
    }
    for (size_t i = 0; i < eventCount; i++)
    {
        // Act on the event
    }
}

Reference

Events returned

Local User Initial State Synced: Triggers when the achievements manager has completed fetching the current state of all of the current title's achievements for the user.

Additional details

The above example shows how to initialize the Achievements Manager for a user, and keep it up to date.

In the game loop, the XblAchievementsManagerDoWork function processes and applies any updates made to users' achievements.

Retrieving a single achievement for a user

In this scenario you want to get the state of a single achievement for a user.

C API

HRESULT hr = XblAchievementsManagerAddLocalUser(userHandle, nullptr);

if (!XblAchievementsManagerIsUserInitialized(xboxUserId))
{
    return;
}

const XblAchievement* achievement = nullptr; 
uint64_t size; 
XblAchievementsManagerResultHandle resultHandle; 

HRESULT hr = XblAchievementsManagerGetAchievement( 
    xboxUserId, 
    achievementId, 
    &resultHandle 
); 

if(FAILED(hr)) 
{ 
    return; 
} 

hr = XblAchievementsManagerResultGetAchievements( 
    resultHandle, 
    &achievement, 
    &size 
); 
if(FAILED(hr)) 
{ 
    return; 
} 

// make use of achievement struct

XblAchievementsManagerResultCloseHandle(resultHandle); 

Reference

Events returned

Local User Initial State Synced: Triggers when the achievements manager has completed fetching the current state of all of the current title's achievements for the user.

Retrieving all achievements for a user

In this scenario you want to get the state all achievement for a user.

C API

HRESULT hr = XblAchievementsManagerAddLocalUser(userHandle, nullptr);

if (!XblAchievementsManagerIsUserInitialized(xboxUserId))
{
    return;
}

XblAchievementsManagerResultHandle resultHandle; 
const XblAchievement* achievements; 
uint64_t achievementsCount; 

hr = XblAchievementsManagerGetAchievements( 
    xboxUserId, 
    XblAchievementOrderBy::DefaultOrder, 
    XblAchievementsManagerSortOrder::Unsorted, 
    &resultHandle 
); 

if(FAILED(hr)) 
{ 
    return; 
} 

hr = XblAchievementsManagerResultGetAchievements( 
    resultHandle, 
    &achievements, 
    &achievementsCount 
); 

if(FAILED(hr)) 
{ 
    return; 
} 
 
for (uint32_t i = 0; i < achievementsCount; ++i) 
{ 
    // ... 
} 
XblAchievementsManagerResultCloseHandle(resultHandle); 

Reference

Events returned

Local User Initial State Synced: Triggers when the achievements manager has completed fetching the current state of all of the current title's achievements for the user.

Retrieving a subset of achievements for a user

In this scenario you want to get the state a subset of achievements for a user.

C API

HRESULT hr = XblAchievementsManagerAddLocalUser(userHandle, nullptr);

if (!XblAchievementsManagerIsUserInitialized(xboxUserId))
{
    return;
}

XblAchievementsManagerResultHandle resultHandle; 
const XblAchievement* achievements; 
uint64_t achievementsCount; 

hr = XblAchievementsManagerGetAchievements( 
    xboxUserId, 
    XblAchievementOrderBy::UnlockTime, 
    XblAchievementsManagerSortOrder::Descending, 
    &resultHandle 
); 

if(FAILED(hr)) 
{ 
    return; 
} 

hr = XblAchievementsManagerResultGetAchievements( 
    resultHandle, 
    &achievements, 
    &achievementsCount 
); 

if(FAILED(hr)) 
{ 
    return; 
} 
 
for (uint32_t i = 0; i < achievementsCount; ++i) 
{ 
    // ... 
} 
XblAchievementsManagerResultCloseHandle(resultHandle); 

Reference

Events returned

Local User Initial State Synced: Triggers when the achievements manager has completed fetching the current state of all of the current title's achievements for the user.

Retrieving a subset of achievements in a specific state for a user

In this scenario you want to get the state a subset of achievements in a specific progress state for a user.

C API

HRESULT hr = XblAchievementsManagerAddLocalUser(userHandle, nullptr);

if (!XblAchievementsManagerIsUserInitialized(xboxUserId))
{
    return;
}

XblAchievementsManagerResultHandle resultHandle; 
const XblAchievement* achievements; 
uint64_t achievementsCount; 

hr = XblAchievementsManagerGetAchievementsByState( 
    xboxUserId, 
    XblAchievementOrderBy::DefaultOrder, 
    XblAchievementsManagerSortOrder::Unsorted, 
    XblAchievementProgressState::NotStarted, 
    &resultHandle 
); 

if(FAILED(hr)) 
{ 
    return; 
} 

hr = XblAchievementsManagerResultGetAchievements( 
    resultHandle, 
    &achievements, 
    &achievementsCount 
); 

if(FAILED(hr)) 
{ 
    return; 
} 
 
for (uint32_t i = 0; i < achievementsCount; ++i) 
{ 
    // ... 
} 
XblAchievementsManagerResultCloseHandle(resultHandle); 

Reference

Events returned

Local User Initial State Synced: Triggers when the achievements manager has completed fetching the current state of all of the current title's achievements for the user.

Updating an achievement for a user

Updates the progress of an achievement for a user.

C API

HRESULT hr = XblAchievementsManagerAddLocalUser(userHandle, nullptr);

if (!XblAchievementsManagerIsUserInitialized(xboxUserId))
{
    return;
}

XblAchievementsManagerUpdateAchievement(xboxUserId, achievementId.c_str(), progress);

Reference

Events returned

Local User Initial State Synced: Triggers when the achievements manager has completed fetching the current state of all of the current title's achievements for the user.

Additional details

Only Title Managed achievements can be updated using XblAchievementsManagerUpdateAchievement. Refer to Writing an event to power an event-based achievement for updating event based achievements.

Cleaning up the Achievements Manager

Removing a user from the Achievements Manager removes the user's cached achievements from the Achievements Manager. No further events should be received for the removed user.

C API

HRESULT hr = XblAchievementsManagerRemoveLocalUser(userHandle);

Reference