Xbox Achievements Manager API の概要
Xbox Achievements Manager API により、Xbox Live ユーザーの実績の状態の追跡と更新が簡素化されます。
Xbox では、特定の時点で実績を付与することで、ゲームでのユーザーの進行状況と実績を追跡できます。 Xbox Services API (XSAPI) の Achievements API を使用して、各ローカル ユーザーの実績情報を最新の状態に保つことは複雑になる可能性があります。 間違った方法でこれを行うと、Xbox 実績サービスの呼び出しが必要以上に多いことが原因で、パフォーマンスの問題、古いデータの使用、またはスロットリングが発生する可能性があります。
Social Manager は、以下の方法でこの問題を解決します。
- 呼び出しがシンプルな API を作成する。
- バックグラウンドでリアルタイム アクティビティ サービスを使用して最新の情報を作成する。
- 開発者は、サービスに余計な負荷をかけずに、Achievements Manager API を同期的に呼び出すことができます。
Achievements Manager は、複数の RTA サブスクリプションの処理、ユーザー用データの更新、実績サービスの呼び出し回数の削減の複雑さを隠し、開発者が最新の実績データを簡単に取得できるようにします。
機能
Achievements Manager は次の機能を提供します。
- 簡素化された Achievements API
- 各ユーザーの最新の実績の状態と進行状況
- Xbox サービスの呼び出し回数を減らす
- これはデータ取得における全体的な遅延低減に直接関係する
- スレッド セーフ
- データを効率良く最新の状態に保つ
核となる概念
実績: 実績には、完了に向けた現在の進行状況に加え、ゲーマースコアとその他のリワード (デジタル アートワーク、新しいマップ、キャラクター、ステータス ブーストなど) が含まれます。
ユーザーの実績の状態を最新の状態に保つには、XblAchievementsManagerDoWork 関数をフレームごとに呼び出す必要があります。
注意
Windows ではローカル ユーザーは 1 人しか存在できません。
API の概要
最も頻繁に使用されるのは、次の主要な API です。
Achievements Manager API の詳細については、「Xbox Live API リファレンス」をご覧ください。 XblAchievementsManager プレフィックスのドキュメントでも API を確認できます。
Achievements Manager にローカル ユーザーを追加する
- C API 関数: XblAchievementsManagerAddLocalUser
Achievements Manager にローカル ユーザーを追加すると、現在のタイトルでのそのユーザーの全実績の状態がサービスから取得され、ローカルに保存されます。
Achievements Manager は、現在のタイトルでのそのユーザーの各実績を最新の状態に保ちます。
ユーザーの実績の状態を取得する
- C API 関数: XblAchievementsManagerGetAchievements
この関数を呼び出すと、指定された条件に一致する実績のハンドルが返されます。
ハンドルが指す実績は、一致する実績のスレッドセーフなコピーです。 ハンドルが指すデータはハンドルが閉じられるまで存在しますが、XblAchievementsManagerDoWork の次の呼び出し後もタイトルがハンドルを保持している場合、データが古くなる可能性があります。
使用方法
Achievements Manager のイベントを使用する
Achievements Manager では、発生したことがイベントの形で通知されます。 これらのイベントを使用して、UI を更新したり、他のロジックを実行したりできます。
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;
}
}
}
リファレンス
返されるイベント
ローカル ユーザーの初期状態の同期: Achievements Manager が、現在のタイトルでのユーザーの全実績の現在の状態の取得を完了したときにトリガーされます。
- C API: XblAchievementsManagerEventType::LocalUserInitialStateSynced
実績の進行状況の更新: 現在のタイトルの実績でユーザーの進行状況が更新されたときにトリガーされます。
- C API: XblAchievementsManagerEventType::AchievementProgressUpdated
実績のロック解除: ユーザーが現在のタイトルの実績を獲得するためのすべての要件を完了したときにトリガーされます。
- C API: XblAchievementsManagerEventType::AchievementUnlocked
その他の詳細
Achievements Manager は、ゲーム ループ中に実績の状態をサービスから頻繁に取得するのではなく、ユーザーが Achievements Manager に登録されたときに、そのユーザーの全実績の状態を取得します。 次に、Achievements Manager は、ユーザーの実績の更新の詳細を示すイベントをサービスから受け取ります。これらのイベントは、*XblAchievementsManagerDoWork 関数によって返される events としてタイトルに転送されます。
events は XblAchievementsManagerEvent のリストです。各 XblAchievementsManagerEvent には、最後のフレームで発生した実績の変更が含まれます。
詳細については、XblAchievementsManagerEvent API ドキュメントをご覧ください。
実績の追跡対象となるユーザーを登録する
このシナリオでは、ユーザーを Achievements Manager に登録して、そのユーザーの実績の更新の追跡を開始し、ユーザーの全実績の状態をローカルにキャッシュします。
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
}
}
リファレンス
返されるイベント
ローカル ユーザーの初期状態の同期: Achievements Manager が、現在のタイトルでのユーザーの全実績の現在の状態の取得を完了したときにトリガーされます。
- C API: XblAchievementsManagerEventType::LocalUserInitialStateSynced
その他の詳細
上記の例は、ユーザーに対して Achievements Manager を初期化し、最新の状態に保つ方法を示しています。
ゲーム ループでは、XblAchievementsManagerDoWork 関数によって、ユーザーの実績に加えられた更新が処理され、適用されます。
ユーザーの 1 つの実績を取得する
このシナリオでは、ユーザーの 1 つの実績の状態を取得します。
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);
リファレンス
- XblAchievement
- XblAchievementsManagerAddLocalUser
- XblAchievementsManagerIsUserInitialized
- XblAchievementsManagerGetAchievement
- XblAchievementsManagerResultGetAchievements
- XblAchievementsManagerResultCloseHandle
返されるイベント
ローカル ユーザーの初期状態の同期: Achievements Manager が、現在のタイトルでのユーザーの全実績の現在の状態の取得を完了したときにトリガーされます。
- C API: XblAchievementsManagerEventType::LocalUserInitialStateSynced
ユーザーの全実績を取得する
このシナリオでは、ユーザーの全実績の状態を取得します。
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);
リファレンス
- XblAchievement
- XblAchievementOrderBy
- XblAchievementsManagerSortOrder
- XblAchievementsManagerAddLocalUser
- XblAchievementsManagerIsUserInitialized
- XblAchievementsManagerGetAchievements
- XblAchievementsManagerResultGetAchievements
- XblAchievementsManagerResultCloseHandle
返されるイベント
ローカル ユーザーの初期状態の同期: Achievements Manager が、現在のタイトルでのユーザーの全実績の現在の状態の取得を完了したときにトリガーされます。
- C API: XblAchievementsManagerEventType::LocalUserInitialStateSynced
ユーザーの実績のサブセットを取得する
このシナリオでは、ユーザーの実績のサブセットの状態を取得します。
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);
リファレンス
- XblAchievement
- XblAchievementOrderBy
- XblAchievementsManagerSortOrder
- XblAchievementsManagerAddLocalUser
- XblAchievementsManagerIsUserInitialized
- XblAchievementsManagerGetAchievements
- XblAchievementsManagerResultGetAchievements
- XblAchievementsManagerResultCloseHandle
返されるイベント
ローカル ユーザーの初期状態の同期: Achievements Manager が、現在のタイトルでのユーザーの全実績の現在の状態の取得を完了したときにトリガーされます。
- C API: XblAchievementsManagerEventType::LocalUserInitialStateSynced
ユーザーの特定の状態の実績のサブセットを取得する
このシナリオでは、ユーザーの、特定の進行状況にある実績のサブセットの状態を取得します。
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);
リファレンス
- XblAchievement
- XblAchievementOrderBy
- XblAchievementProgressState
- XblAchievementsManagerSortOrder
- XblAchievementsManagerAddLocalUser
- XblAchievementsManagerIsUserInitialized
- XblAchievementsManagerGetAchievementsByState
- XblAchievementsManagerResultGetAchievements
- XblAchievementsManagerResultCloseHandle
返されるイベント
ローカル ユーザーの初期状態の同期: Achievements Manager が、現在のタイトルでのユーザーの全実績の現在の状態の取得を完了したときにトリガーされます。
- C API: XblAchievementsManagerEventType::LocalUserInitialStateSynced
ユーザーの実績を更新する
ユーザーの実績の進行状況を更新します。
C API
HRESULT hr = XblAchievementsManagerAddLocalUser(userHandle, nullptr);
if (!XblAchievementsManagerIsUserInitialized(xboxUserId))
{
return;
}
XblAchievementsManagerUpdateAchievement(xboxUserId, achievementId.c_str(), progress);
リファレンス
- XblAchievementsManagerAddLocalUser
- XblAchievementsManagerIsUserInitialized
- XblAchievementsManagerUpdateAchievement
返されるイベント
ローカル ユーザーの初期状態の同期: Achievements Manager が、現在のタイトルでのユーザーの全実績の現在の状態の取得を完了したときにトリガーされます。
- C API: XblAchievementsManagerEventType::LocalUserInitialStateSynced
その他の詳細
XblAchievementsManagerUpdateAchievement を使用して更新できるのは、タイトルによって管理される実績だけです。 イベントベースの実績の更新については、「イベントに基づく実績を利用するイベントを書く」をご覧ください。
Achievements Manager をクリーンアップする
Achievements Manager からユーザーを削除すると、そのユーザーのキャッシュされた実績が Achievements Manager から削除されます。 削除されたユーザーについては、それ以上イベントを受け取ることはなくなります。
C API
HRESULT hr = XblAchievementsManagerRemoveLocalUser(userHandle);
リファレンス