Game Saves のエラー処理に関する FAQ
この記事では、Game Saves が障害をどのように報告するかについてのよくある質問に回答します。どのエラーが一時的なもの (再試行する価値がある) か、どのエラーが誤った値を渡したことを意味する (呼び出しを修正する) か、そしてエラーを返す代わりにシステムがオフライン モードに入るのはどのような場合かを説明します。 Game Saves はプラットフォームに応じて 2 つの方法のいずれかで実行され、エラー処理は両者の間でわずかに異なります:- アウトオブプロセス: プラットフォームの組み込みサービスが同期を実行し、独自のシステム UI を表示します。XBOX および Windows では、Game Saves は常にこの方法で実行されます。
- インプロセス: プラットフォーム サービスが利用できないプラットフォーム (たとえば Steam Deck) では、SDK 自体がクラウド同期を実行します。ゲームはコールバックを通じて UI を制御します。
Game Saves がエラーを返す代わりにオフラインになるのはどのような場合ですか?
オフライン モードはエラーではなく、成功の結果です。初期同期 (PFGameSaveFilesAddUserWithUiAsync) がオフライン モードに入るのは、プレイヤーが同期失敗のプロンプトで明示的に Use Offline / Play offline を選択した場合 (または別のデバイスがアクティブ デバイスになった場合) のみです。この場合、非同期操作は S_OK で完了し、PFGameSaveFilesIsConnectedToCloud() は false を返します。使用可能なローカル セーブ フォルダーは引き続き取得できます。
一方、プレイヤーが意図的に Cancel した場合は E_PF_GAMESAVE_USER_CANCELLED で完了し、セーブ フォルダーは提供されません。これは「プレイを許可しない」として扱ってください。ゲーム自体が XAsyncCancel で非同期操作をキャンセルした場合は、代わりに E_ABORT で完了し、この場合もセーブ フォルダーは提供されません。E_ABORT はゲーム自身によるキャンセルとして扱ってください。
完全な判定表とエラー コードのリファレンスについては、Game Saves のオフライン モードを参照してください。
PFGameSaveFilesInitialize は一時的に失敗することがありますか?
いいえ。 PFGameSaveFilesInitialize は引数を検証して状態を設定するだけで、ネットワークにはアクセスしません。返されるすべての失敗は決定論的です:
E_INVALIDARG: 必須の引数が欠落しているか無効です。インプロセスの場合、これにはsaveFolderの欠落または無効が含まれます (これらのプラットフォームでは有効なフォルダーが必要です。XBOX/GDK では場所が固定されており、この引数は無視されます)。E_PF_GAMESAVE_ALREADY_INITIALIZED: 間にPFGameSaveFilesUninitializeAsyncを挟まずに 2 回呼び出しました。
Initialize が失敗した場合、再試行しても解決しません。入力を修正してください。特定の構成で一度成功すれば、後になって勝手に失敗し始めることはありません。
PFGameSaveFilesAddUserWithUiAsync は一時的に失敗することがありますか?
はい。 これはネットワーク同期を実行する呼び出しであるため、一時的な障害 (ネットワークのダウン、サービス エラー、トークンの更新、ディスク領域の不足) が発生する可能性があります。HTTP 呼び出しはタイトルの HTTP 再試行設定 (PFHttpRetrySettings) に従って再試行されますが、ゲームが一時的な障害を検知する前にそれが解決される保証はありません。
これらの再試行で一時的な障害が解決されない場合、その障害は同期失敗 UI を通じて通知され、プレイヤーは Retry、Use Offline、または Cancel を選択します。または、インプロセスで同期失敗コールバックが登録されていない場合は、生の HRESULT として返されます。そのため、一時的な障害は通常、生のエラーではなくオンライン、オフライン、またはキャンセルのいずれかに解決されますが、2 つのパスの間には重要な違いが 1 つあります (次の質問を参照してください)。
PFGameSaveFilesAddUserWithUiAsync は、一時的ではなく再試行できない決定論的なエラーを返すこともあります:
E_INVALIDARG: ハンドル/非同期が null であるか、オプションが競合しています。E_PF_GAMESAVE_NOT_INITIALIZED:Initializeの前に呼び出されました。E_PF_GAMESAVE_USER_ALREADY_ADDED: ユーザーは既に追加されています (かつ、まだ接続されています)。
オフライン オプションを利用するには UI コールバックを登録する必要がありますか?
これが 2 つのパスの主な違いです:- インプロセス: はい。 一時的な同期失敗に対するオフライン フォールバックは、
PFGameSaveFilesAddUserWithUiAsyncを呼び出す前に (PFGameSaveFilesSetUiCallbacksを介して) 同期失敗コールバックを登録した場合にのみ発生します。コールバックが登録されていない場合、一時的な障害が発生すると操作は生のエラー HRESULT で完了し、Retry も Use Offline もありません。 組み込みの Game Saves UI がないプラットフォームでは、コールバックの登録が必須です。 - アウトオブプロセス: 通常の同期失敗では不要です。 プラットフォームの組み込みシステム UI が Try again / Play offline の選択肢を自動的に提供するため、同期中の通常のネットワーク障害では、ゲーム側のコールバックがなくてもプレイヤーにオフライン オプションが提示されます。独自の UI を提供するためにコールバックを登録することもできます。
UI が表示される前に発生する障害はありますか?
アウトオブプロセスのみです。 同期 UI が表示される前に、PFGameSaveFilesAddUserWithUiAsync はサービス構成を収集し、(必要に応じて) ユーザーをサインインさせます。初期セットアップの障害 (たとえば、プラットフォーム サービスが一時的に利用できない場合や、タイトルが Game Saves 用に構成されていない場合) により、ダイアログが表示される前に生の HRESULT で呼び出しが完了することがあります。これらの一部は一時的なもの (少し後で PFGameSaveFilesAddUserWithUiAsync 全体を再試行します) であり、その他は構成の問題 (決定論的) を示しています。サインイン/トークンの障害は適切に処理され、それ自体で呼び出しが失敗することはありません。
インプロセスの場合、AddUserWithUiAsync にはこの初期セットアップのカテゴリはありません。障害は同期中に発生し、同期失敗 UI を経由します (上記のコールバックの要件が適用されます)。
アップロードはキャンセルできますか?
はい。PFGameSaveFilesUploadWithUiAsync は UI (進行状況インジケーター、およびエラーが発生した場合は同期失敗のプロンプト) を表示し、プレイヤーはどちらからでも中止できます。中止すると、操作は E_PF_GAMESAVE_USER_CANCELLED (0x800704C7) で完了し、セーブはアップロードされません。
初期同期とは異なり、アップロードには Use Offline という成功の結果はありません。最終的な結果は次のとおりです:
- 成功 (
S_OK): クラウドに保存されました。 - キャンセル (
E_PF_GAMESAVE_USER_CANCELLED): プレイヤーが中止しました。 - ゲームによるキャンセル (
E_ABORT): ゲームがアップロードに対してXAsyncCancelを呼び出しました。 - 失敗: その他すべて (たとえば
E_PF_GAMESAVE_NETWORK_FAILUREやE_PF_GAMESAVE_DEVICE_NO_LONGER_ACTIVE)。
E_PF_GAMESAVE_DISCONNECTED_FROM_CLOUD で完了し、その後 PFGameSaveFilesIsConnectedToCloud() は false を返します。アップロードによってセッションがオフラインになる場合を参照してください。
「プレイヤーがキャンセルした」ことと「アップロードでエラーが発生した」ことを区別できるように、E_PF_GAMESAVE_USER_CANCELLED は他の障害とは別に処理してください。これは初期同期で使用されるのと同じキャンセル コードであるため、1 つのチェックで両方の操作に対応できます。
どのエラーが「誤った値を渡した」ことを示し、どのエラーが一時的な問題を示しますか?
完全な HRESULT リファレンスについては、Game Saves のオフライン モードを参照してください。
推奨事項
PFGameSaveFilesInitializeの失敗は、再試行すべき実行時の状態ではなく、修正すべきバグ (不正な引数/構成) として扱ってください。- インプロセス: 一時的な障害が発生したときにハード エラーではなく Retry/Use Offline をプレイヤーに提示できるように、
PFGameSaveFilesAddUserWithUiAsyncの前に必ず UI コールバック (少なくとも同期失敗コールバック) を登録してください。 - アウトオブプロセス: UI が表示される前に
PFGameSaveFilesAddUserWithUiAsyncから生の失敗 (サービス/構成) が返される可能性に備えてください。一時的なものは再試行し、構成の問題はエラーとして通知してください。 - 最終的な結果に基づいてプレイを制御してください:
S_OK+ 接続済み → オンラインでプレイ、S_OK+ 未接続 → オフラインでプレイ (セーブが同期されないことをプレイヤーに警告します)、フォルダーなしのキャンセル/失敗 → プレイをブロック。
