プライマリ リンク ID
任意のクロス プログレッション戦略の最初の要件は、ゲーム プラットフォームをまたがるプレイヤー ID を決定することです。プレイヤーは、ゲームが利用可能な任意のデバイスでこの ID でサインインできる必要があります。ファースト パーティ タイトルでは、これはしばしば Microsoft アカウント (MSA)/XBOX アカウントです。多くのサード パーティでは、これは OpenID Connect 実装を通じて公開されるパブリッシャー ID である可能性が高いです。このプレイヤー ID の 2 つの要件は次のとおりです。- プレイヤーがゲームをプレイできるすべてのプラットフォームで利用可能であること
LoginWithXboxまたはLoginWithOpenIdConnectなどの既存の PlayFab Login 呼び出しでサポートされていること
プラットフォーム ネイティブ ID
プラットフォーム ネイティブ ID は、プレイヤーがゲームを実行しているプラットフォームによって提供されるアカウント システムです。例:- Steam: Steam アカウントおよび認証チケット (
ISteamUser::GetAuthTicketForWebApi) - XBOX (PC/コンソール): MSA/XBOX の
XUserHandleおよび XSTS トークン - PlayStation: PSN オンライン ID / アカウント
- Nintendo: Nintendo サービス アカウント / デバイス ID
PFLocalUserHandle を作成および再利用するために使用されます (たとえば、PFLocalUserCreateHandleWithSteamUser や XUserHandle のラップ)。適切な場合には、プロバイダー固有の PlayFab Login API (たとえば、LoginWithSteam、LoginWithXbox) を通じて認証するためにも使用できます。
クロス プログレッションのシナリオでは、プラットフォーム ネイティブ ID はプライマリ リンク ID にリンクされ、プログレスと権利がプラットフォーム間でプレイヤーに従うようにします。このドキュメントの推奨ワークフローでは、プラットフォーム ネイティブ ID をローカル ユーザー コンテキストとして使用し、プライマリ リンク ID をクロス プラットフォームのアンカーとして使用します。
リンク戦略の選択肢
このドキュメントでは、2 つの関連する戦略を検討します。- すべてのプレイヤーは、プレイする前にプラットフォーム ネイティブ ID とプライマリ リンク ID をリンクする 必要 があります。
- プラットフォーム ネイティブ ID とプライマリ リンク ID の間のリンクは 任意 ですが、プレイ前に強く推奨されます。
望ましい状態
戦略に関係なく、最終的な目標は、すべてのプレイヤーを同じ状態に置くことです。プレイヤーのプライマリ リンク ID は、プレイするすべてのデバイスでプラットフォーム ネイティブ ID にリンクされている必要があります。その状態では、進行状況はプライマリ リンク ID に一貫して関連付けられ、プラットフォーム ネイティブ ID をすべてのプラットフォームで有効なプロキシ ID として使用できます。 一部のプラットフォームでは、プライマリ リンク ID がプラットフォーム ネイティブ ID である 可能性があります (XBOX 上で動作するファースト パーティ ゲーム)。それらの場合、望ましい状態を達成することは自明です。既存のサインインおよびリンクのガイダンスで十分であるため、このドキュメントではそれらについて詳しく取り上げません。LocalUser とログインの比較
PlayFab SDK に存在する 2 つの関連しているが別々の概念を区別することが重要です。 LocalUserCreate 呼び出しは、認証を実行せずにローカル ユーザー オブジェクトを構築し、PFLocalUserHandle を返します。これは、プラットフォーム固有または永続化されたローカル ID (たとえば、XUserHandle のラップ) によってユーザーを識別してキャッシュし、操作やゲーム インスタンス間で同じローカル コンテキストを再利用できるようにします。この操作は純粋にローカルで、ネットワーク リクエストの実行、エンティティ トークンの取得、PlayFab アカウントの作成は行いません。 対照的に、Login 呼び出しは PlayFab でローカル ユーザーを認証し、トークンや ID を含む認証済みエンティティを確立します。Login 呼び出しはネットワーク リクエスト (/Client/LoginWithXbox など) を実行し、createAccount のようなフラグを尊重します。成功すると結果がキャッシュされ、後続の呼び出しは認証済みの状態を再利用できます。 要するに、ローカル ユーザーの作成は、PlayFab Game Saves に必要なローカル ID とハンドル管理を設定するのに対し、サインインは PlayFab に接続してエンティティを必要とする API を認証および有効化するステップです。戦略 1 - プライマリ ID リンクが必須
この戦略を説明するため、Steam でリリースする XBOX ファースト パーティ ゲームを取り上げます。ゲームは XBOX/MSA をプライマリ リンク ID として使用します。ゲームプレイの前にすべてのプレイヤーが XBOX/MSA にサインインすることを要求します。ゲームは引き続き Steam ID に基づく LocalUserHandle を使用しますが、プレイヤーが XBOX ID を作成してリンクするまで、実際のサインインをブロックします。その後の起動では、リンク済みとして検証されているため、Steam ID を直接使用できます。概要のサマリー
- プレイヤーはプレイ前にクロス プラットフォーム ID (XBOX/MSA) でサインインする必要があります。
- プラットフォーム アカウント (Steam) からローカル プレイヤーを作成しますが、XBOX/MSA サインインが完了するまでオンライン プレイを保留します。
- XBOX/MSA サインインの後、プラットフォーム アカウントをクロス プラットフォーム アカウントにリンクします。
- クロス プラットフォーム アカウントに接続されるようにローカル プラットフォーム プロファイルを更新します。
- リンクが確立されているため、将来の起動はシームレスです: プレイヤーはすぐにプレイに進めます。
詳細ウォークスルー
Steam ローカル ユーザー ハンドルを作成するPFLocalUserCreateHandleWithSteamUser(serviceConfigHandle, customContext, outLocalUserHandle)を呼び出します。- 結果:
PFLocalUserHandle; まだ認証されていません。
PFLocalUserLoginAsync(localUserHandle, /*createAccount*/ false, async)を呼び出します。- 完了時、
PFLocalUserLoginGetResultがE_PF_ACCOUNT_NOT_FOUNDで失敗した場合、アカウントをブートストラップするために XBOX サインインをトリガーします。 PFLocalUserLoginGetResultが成功した場合、既に望ましい状態のアカウントを持っており、オンラインになっています。ワークフローは完了です。
タイトルがクロス プラットフォーム ID を現在のユーザーとリンクした状態を維持する必要がある場合 (たとえば、ゲームが XBOX サインインを必要とし、エンティティの XBOX リンクが現在サインインしている XBOX アカウントと一致することを期待する場合)、プラットフォーム ログインの成功だけでは不十分です。ログイン後に
PFAccountManagementClientGetAccountInfoAsync を呼び出して、クロス プラットフォーム リンクが現在のユーザーと一致するかどうかを検証してください。一致しない場合、エンティティは古いクロス プラットフォーム ID に結びついている可能性があります。以下の XBOX 経由でサインイン および Steam をリンク 手順に従って再調整してください。PFAuthenticationLoginWithXUserRequestを構築します:- 必要に応じて PlayFab アカウントを作成するために
createAccount=trueを設定します。 - PC にサインインしている XBOX ユーザーから
XUserHandleを提供します。
- 必要に応じて PlayFab アカウントを作成するために
PFAuthenticationLoginWithXUserAsync(serviceConfigHandle, request, async)を呼び出します。PFAuthenticationLoginWithXUserGetResultSize(...)とPFAuthenticationLoginWithXUserGetResult(...)で完了し、PFEntityHandleを取得します。- 注: LoginWithXUser バリアントが利用できない場合は、
PFAuthenticationLoginWithXboxを使用します。これには、XUserHandleから XSTS トークンを自分で抽出する必要があります。
- 現在の Steam 認証チケット (
ISteamUser::GetAuthTicketForWebApiまたは統合内の同等物から。コード内の正確な関数名を確認してください) を使用してクライアント リンク リクエストを構築します。 PFAccountManagementClientLinkSteamAccountAsync(entityHandle, linkRequest, async)を呼び出します。- 注: 「LinkSteamAccount」は Authentication ではなく Account Management の下にあります。
- 成功すると、プレイヤーの Steam ID が XBOX ベースの PlayFab アカウントにリンクされます。
PFLocalUserLoginAsync(steamLocalUserHandle, /*createAccount*/ false, async)を再度呼び出します。PFLocalUserLoginGetResultが成功するようになり、得られるPFEntityHandleは Steam ローカル ユーザーにバインドされます。
- Game Save やその他のオンライン API は認証済みの
PFEntityHandleを使用します。 - その後のゲーム起動は、すべてのリンクが整っているため、プレイに直接移行できます。
PFLocalUserCreateHandleWithSteamUserは単独ではサインインしませんが、PFGameSaveFilesAddUserWithUiAsyncを呼び出そうとするとサインイン試行が発生します。その呼び出しの前にアカウント リンク フローを経ていることを確認してください。
リンク競合の処理
Steam を XBOX ベースのエンティティにリンクする際に、2 つの異なる競合が発生する可能性があります。それぞれ異なる修復方法が必要です。
推奨フロー:
- XBOX サインインの後、
PFAccountManagementClientGetAccountInfoAsync(xboxEntity, getInfoRequest, async)を呼び出してアカウント情報を取得し、リンクされた ID を確認します。 - エンティティに既に 異なる Steam アカウント がリンクされている場合:
- 続行するとこのエンティティから古い Steam 関連付けが削除されることをプレイヤーに警告します。同意を得ます。
PFAccountManagementClientUnlinkSteamAccountAsync(xboxEntity, unlinkRequest, async)を呼び出して既存の Steam リンクを削除します。- 次に、現在の Steam チケットで
PFAccountManagementClientLinkSteamAccountAsyncを呼び出します。
- リンク呼び出しが
E_PF_LINKED_ACCOUNT_ALREADY_CLAIMEDを返す場合 (Steam アカウントが別のエンティティに属する):- この Steam アカウントは別の PlayFab アカウントに関連付けられており、ここでリンクすると関連付けが削除されることをプレイヤーに警告します。
- 同意の後、
forceLink=trueで再試行します。
サンプル C++ フロー (Steam ファースト ゲート、XBOX ブートストラップ、Steam リンク、Steam で再サインイン):
このサンプルではライフタイム管理を簡素化するために
static XAsyncBlock 変数を使用しています。本番コードでは、同時実行または再入呼び出しをサポートするために、非同期ブロックを動的に (たとえば、コンテキスト構造体の一部として) 割り当てる必要があります。E_PF_ACCOUNT_NOT_FOUNDを使用して XBOX ブートストラップ パスを決定します。他のエラーは別途処理します。- Steam
PFLocalUserHandleを引き続き使用します。プロバイダー固有の XBOX サインインは、Steam のリンクのみに使用されるentityHandleを返します。 - リンク後、Steam で再度サインインしてエンティティを LocalUser にバインドします。
- リンク用に新しい Steam チケットを取得することを確認してください。
- 不要になったハンドルは閉じてください (
PFLocalUserCloseHandle、PFEntityCloseHandle)。
戦略 2 - プライマリ ID リンクが任意
このシナリオでは、ゲームは Steam 上で動作し、XBOX/MSA をプライマリ リンク ID として使用します。プレイヤーは、XBOX/MSA にすぐにサインインすることなくプレイを開始できます。ゲームは明確な利点と警告を示して早期のリンクを推奨しますが、初期のゲームプレイはブロックされません。概要のサマリー
- プラットフォーム アカウント (Steam) を使用してローカル プレイヤーを作成し、新しいアカウントを作成せずにオンラインでプレイを試みます。
- オンラインが機能する場合は続行します。そうでない場合は選択肢を提示します:
- クロス プラットフォーム ID (XBOX/MSA) でサインインして統合アカウントを作成する、または
- プラットフォームのみのアカウントを今すぐ作成してすぐにプレイを開始する。
- 利点とリスクを説明することで、XBOX/MSA への早期リンクを推奨します。
- プレイヤーがリンクを選択した場合:
- リンクが直接成功した場合、統合アカウントでプレイを続行します。
- XBOX/MSA アカウントが他の場所で既に進行状況を持っている場合、一時停止して、どの進行状況を保持するかを尋ねます (調整):
- XBOX/MSA の進行状況を保持し、現在のプラットフォーム アカウントをアタッチする。
- 現在のプラットフォームの進行状況を保持し、リンクを延期する。
- リンク後、ローカル プラットフォーム プロファイルを更新して統合アカウントに接続されるようにします。
- 将来の起動はシームレスです: プレイヤーは (リンクが延期されなかった場合) 直接プレイに移行できます。
詳細ウォークスルー
Steam ローカル ユーザー ハンドルを作成するPFLocalUserCreateHandleWithSteamUser(serviceConfigHandle, customContext, outLocalUserHandle)を呼び出します。- 結果:
PFLocalUserHandle; まだ認証されていません。
PFLocalUserLoginAsync(localUserHandle, /*createAccount*/ false, async)を呼び出します。- 完了時:
PFLocalUserLoginGetResultが成功した場合、得られたPFEntityHandleを使用してオンラインで進めます。- Steam ベースのアカウントが既に XBOX/MSA にリンクされているかどうかを確認します。
PFAccountManagementClientGetAccountInfoAsync(entityHandle, getInfoRequest, async)を呼び出してリンクされた ID を確認してください。リンクされていない場合、以下のフロー (非ブロッキング) を使用して XBOX をリンクするようプレイヤーに促し、将来のクロス プログレッションがシームレスに機能するようにします。
- Steam ベースのアカウントが既に XBOX/MSA にリンクされているかどうかを確認します。
PFLocalUserLoginGetResultがE_PF_ACCOUNT_NOT_FOUNDで失敗する場合、アカウントが作成されるまでプレイヤーはオフラインのままです。2 つの選択肢を提示します:- XBOX ベースの PlayFab アカウントを今すぐ作成: XBOX/MSA でサインイン (たとえば、
PFAuthenticationLoginWithXUserAsync)。 - Steam で今すぐサインインしてプレイを開始:
PFLocalUserLoginAsync(localUserHandle, /*createAccount*/ true, async)を呼び出して、ローカル ハンドルにバインドされた Steam ベースの PlayFab アカウントを作成します。成功時、得られたPFEntityHandleを使用してすぐにオンラインで進めます。
- XBOX ベースの PlayFab アカウントを今すぐ作成: XBOX/MSA でサインイン (たとえば、
- その他のエラーについては、優雅に処理します (再試行/バックオフ)。
- リンクの利点 (クロス プログレッション、権利の移植性) を提示します。
- XBOX/MSA サインインを提供します。
- プレイヤーが後で XBOX リンクを開始する場合 (現在のセッションから既に Steam ベースの
PFEntityHandleがある場合):- 新しい XBOX ベースのアカウントを作成しない。
- 適切なリンク API を呼び出して XBOX ID を現在の Steam ベースのアカウントに直接リンクする (たとえば、
PFAccountManagementClientLinkXboxAccountAsync(currentSteamEntity, linkRequest, async))。 - リンクが成功した場合、XBOX/MSA ID がリンクされました。通常の操作を続行します。
- リンクがプレエグジスティングなリンク/競合エラー (XBOX ID が別の場所で既にリンクされている) で失敗した場合、アカウント調整モードに入ります。すぐに
createAccount=falseで XBOX/MSA サインインを実行し (たとえば、PFAuthenticationLoginWithXUserAsync)、XBOX ベースのPFEntityHandleを取得します。次に、プレイヤーに促す前にコンテキストとしてプロファイル メタデータを取得します。同意の後、リンクの決定に進みます。
- プレイヤーが XBOX の既存のアカウントを持たない場合 (ブートストラップ パス):
- まず
PFAuthenticationLoginWithXUserAsync(またはLoginWithXUserが利用できない場合はPFAuthenticationLoginWithXboxAsync) を使用してcreateAccount=falseで XBOX/MSA サインインを試みる。- サインインが成功した場合: XBOX/MSA アカウントには既に PlayFab アカウントがあり、既存の進行状況を持っている可能性が高い。アカウント調整モードに入り、どの進行状況を保持するかを選択する。
- サインインが
E_PF_ACCOUNT_NOT_FOUNDで失敗した場合:createAccount=trueで再度サインインして PlayFab アカウントを作成する。
PFAuthenticationLoginWithXUserGetResultSize(...)およびPFAuthenticationLoginWithXUserGetResult(...)で完了し、PFEntityHandleを取得します。
- まず
- 新しい XBOX ベースの PlayFab アカウントを作成したばかりの場合 (既存の Steam リンクがない場合) に適用されます。
- 以前にアカウント調整に入った場合、リンクの決定と必要な
forceLinkアクションはそこで処理されます。この手順はスキップします。 - 現在の Steam 認証チケット (
ISteamUser::GetAuthTicketForWebApiまたは統合から) を使用してクライアント リンク リクエストを構築します。 forceLink=false(デフォルト) でPFAccountManagementClientLinkSteamAccountAsync(entityHandle, linkRequest, async)を呼び出します。新しいアカウントであれば成功するはずです。- リンクが失敗した場合、エラー条件として扱います (予期しない競合または認証失敗)。プレイヤーにエラーを提示し、再試行する前に再サインインを促すことを検討します。
- 成功すると、プレイヤーの Steam ID が XBOX ベースの PlayFab アカウントにリンクされます。
PFLocalUserLoginAsync(steamLocalUserHandle, /*createAccount*/ false, async)を再度呼び出します。PFLocalUserLoginGetResultが成功するようになり、得られるPFEntityHandleは Steam ローカル ユーザーにバインドされます。
- Game Save やその他のオンライン API は認証済みの
PFEntityHandleを使用します。 - その後のゲーム起動は、すべてのリンクが整っているため、プレイに直接移行できます。
- 初期のゲームプレイを XBOX/MSA サインインでブロックしないでください。早期に促しつつ、プレイヤーが延期できるようにしてください。
PFLocalUserCreateHandleWithSteamUserは単独でサインインしません。PFGameSaveFilesAddUserWithUiAsyncのようにサインインをトリガーする API を呼び出す前に、リンク フローが完了していることを確認してください。
アカウント調整 (XBOX/MSA の既存の進行状況)
プレイヤーが (たとえば、コンソールや別のプラットフォームからの) 既存の進行状況を持つ XBOX/MSA アカウントでサインインする場合、盲目的に新しいアカウントを作成したり既存のリンクを上書きしたりすることを避ける必要があります。慎重な 2 段階アプローチで検出および調整を行います。検出フェーズ
- 調整には 2 つのパスから入ることができます:
- 既存の XBOX/MSA アカウントが検出された場合:
createAccount=falseで XBOX/MSA サインインを試みる。- サインインが成功した場合、XBOX/MSA ID には既に PlayFab アカウントがあり、既存の進行状況を持っている可能性が高い。調整に入る。
- サインインが
E_PF_ACCOUNT_NOT_FOUNDで失敗した場合、ブートストラップに進む (createAccount=true)。調整に入る必要はありません。
- 後付けリンク競合が検出された場合: XBOX/MSA を現在の Steam ベースのアカウントにリンクする際、リンクがプレエグジスティング リンク/競合エラー (XBOX ID が別の Steam ID と既にリンクされている) で失敗する。
- すぐに
createAccount=falseで XBOX/MSA サインインを実行し (たとえば、PFAuthenticationLoginWithXUserAsync)、XBOX ベースのPFEntityHandleを取得します。 - コンテキストを提示するためにプロファイル メタデータ (たとえば、最近の進行状況、セーブ スロット、タイム スタンプ) を取得します。
- どの進行状況を保持するかを決定するために調整に入る。
- すぐに
- 既存の XBOX/MSA アカウントが検出された場合:
調整フェーズ
- 分かりやすい選択肢を推奨します: XBOX/MSA (プライマリ リンク ID) の進行状況を保持し、ローカル Steam の進行状況を破棄します。これによりクロス プラットフォームのアンカーが保持され、複雑なマージを避けられます。
- プレイヤーには実質的に 3 つの選択肢があります (ゲームはこれらのうち 1〜2 のみを提供することを選択できます):
- XBOX/MSA の進行状況を保持 (推奨): 現在の Steam アカウントを既存の XBOX ベースの PlayFab アカウントにリンクする。
- 現在の Steam の進行状況を保持しリンクをキャンセル: 今のところ Steam ベースのアカウントで続行する。XBOX/MSA データをリンクまたは上書きしない。次回リンクを再度提案する。
- 現在の Steam の進行状況を保持し XBOX の進行状況を破棄: Steam ベースのアカウントに切り替え、意図的に XBOX/MSA の進行状況を破棄する。このパスは明示的なゲーム設計上の考慮が必要で、特に他のプラットフォーム ネイティブ ID が既に XBOX アカウントに接続されている場合は、軽々しく試みるべきではありません。このドキュメントでは、このシナリオの実装詳細は取り上げません。
- コミット前:
- XBOX エンティティに対して
PFAccountManagementClientGetAccountInfoAsyncを呼び出して既存のプロバイダー リンクを確認し、Steam リンクが既に存在するかどうかを確認します。 - エンティティに 異なる Steam アカウント がリンクされている場合、新しいものが追加される前にこの既存の Steam 関連付けがエンティティから削除されることをプレイヤーに警告します。これには、現在の Steam アカウントをリンクする前に
PFAccountManagementClientUnlinkSteamAccountAsyncを呼び出す必要があります。forceLinkはこのシナリオを解決しません。 - 現在の Steam アカウント が 別のエンティティ にリンクされている場合、
PFAccountManagementClientLinkSteamAccountAsyncを呼び出すとE_PF_LINKED_ACCOUNT_ALREADY_CLAIMEDが返されます。リンクによって Steam ID が別のエンティティから移動することを警告し、同意の後forceLink=trueで再試行します。
- XBOX エンティティに対して
コミット アクション (プレイヤーの選択に基づく)
- プレイヤーが XBOX/MSA の進行状況を選択する場合:
- XBOX サインインのエンティティが取得されていることを確認します (検出時にまだ行っていない場合は、
createAccount=falseでPFAuthenticationLoginWithXUserAsyncを実行します)。 - XBOX エンティティに既に異なる Steam アカウントがリンクされている場合、
PFAccountManagementClientUnlinkSteamAccountAsyncを呼び出して最初に削除します。 - 現在の Steam を XBOX ベースのアカウントにリンクします。呼び出しが
E_PF_LINKED_ACCOUNT_ALREADY_CLAIMED(Steam が別のエンティティにある) を返す場合、同意の後forceLink=trueで再試行します。 - Steam ローカル ユーザーで再度サインインして (
PFLocalUserLoginAsync(..., /*createAccount*/ false, ...)) エンティティをバインドします。
- XBOX サインインのエンティティが取得されていることを確認します (検出時にまだ行っていない場合は、
- プレイヤーが Steam の進行状況を選択する場合:
- Steam の PlayFab アカウントがまだ存在しない場合は、
PFLocalUserLoginAsync(..., /*createAccount*/ true, ...)で作成/バインドします。 - XBOX リンクを延期します。すぐにゲームプレイを許可します。次回リンクを再度提案します。
- Steam の PlayFab アカウントがまだ存在しない場合は、
注記
- プレイヤーの決定に情報を提供するために、常に十分なコンテキストを取得して表示してください。
- プロンプトとデフォルトを時間の経過とともに改善するために、調整結果のテレメトリを記録してください。
