保存済みゲームをゲームに追加する

このガイドでは、C++ アプリで保存済みゲームサービスを使用してプレーヤーのゲームの進行状況データを保存および読み込む方法について説明します。このサービスを使用すると、ゲームプレイ中の任意の時点でプレーヤーのゲームの進行状況を自動的に読み込み、保存できます。このサービスを使用すると、プレーヤーはユーザー インターフェースをトリガーして、既存のセーブゲームを更新または復元したり、新しいセーブゲームを作成したりすることもできます。

始める前に

セーブ ゲームに関するコンセプトをまだ確認されていない場合は、確認することをおすすめします。

Saved Games API を使用してコーディングを開始する前に:

データ形式とクロス プラットフォームの互換性

Google のサーバーに保存する保存済みゲームデータは、std::vector<uint8_t> 形式にする必要があります。保存済みゲーム サービスは、クロスプラットフォームの互換性を確保するためにデータをエンコードします。Android アプリケーションは、クロスプラットフォームの互換性の問題なしに、この同じデータをバイト配列として読み取ることができます。

保存済みゲームデータのデータ形式を選択する際は、プラットフォーム固有の形式を使用しないでください。複数のプラットフォームで強力なライブラリ サポートが提供されているデータ形式(XML や JSON など)を使用することを強くおすすめします。

保存済みゲーム サービスを有効にする

保存済みゲーム サービスを使用するには、まずアクセスを有効にする必要があります。これを行うには、gpg::GameServices::Builder でサービスを作成するときに EnableSnapshots() を呼び出します。これにより、次回の認証イベントで、セーブしたゲームに必要な追加の認証スコープが有効になります。

保存済みゲームを表示する

ゲーム内で、プレーヤーがトリガーして保存済みゲームを保存または復元できるオプションを用意できます。プレーヤーがこのオプションを選択すると、既存の保存スロットが表示される画面がゲームに表示され、プレーヤーはこれらのスロットのいずれかに保存または読み込みを行うか、新しい保存済みゲームを作成できます。そのためには、次のメソッドを使用します。

  SnapshotManager::ShowSelectUIOperation(...)

保存済みゲーム選択 UI により、プレーヤーは、新しい保存済みゲームの作成、既存の保存済みゲームの詳細表示、以前の保存済みゲームの読み込みを行えます。

  SnapshotManager::SnapshotSelectUIResponse response;
  if (IsSuccess(response.status)) {
  if (response.data.Valid()) {
    LogI("Description: %s", response.data.Description().c_str());
    LogI("FileName %s", response.data.FileName().c_str());
    //Opening the snapshot data
    
  } else {
    LogI("Creating new snapshot");
    
  }
} else {
  LogI("ShowSelectUIOperation returns an error %d", response.status);
}

次の例は、デフォルトの保存済みゲーム UI を表示し、プレーヤーの UI 選択を処理する方法を示しています。

  service_->Snapshots().ShowSelectUIOperation(
  ALLOW_CREATE_SNAPSHOT,
  ALLOW_DELETE_SNAPSHOT,
  MAX_SNAPSHOTS,
  SNAPSHOT_UI_TITLE,
  [this](gpg::SnapshotManager::SnapshotSelectUIResponse const & response) {
  
      }

上記の例で、ALLOW_CREATE_SNAPSHOTtrue で、MAX_SNAPSHOTS がユーザーが現在作成した実際のスナップショット数より大きい場合、デフォルトのスナップショット UI には、既存のゲームを選択するのではなく、新しいセーブ ゲームを作成するボタンが表示されます。(表示されている場合、ボタンは UI の下部にあります)。プレーヤーがこのボタンをクリックすると、SnapshotSelectUIResponse レスポンスは有効ですが、データはありません。

保存済みゲームを開いて読み取る

保存済みゲームにアクセスしてその内容を読み取ったり変更したりするには、まず、その保存済みゲームを表す SnapshotMetadata オブジェクトを開きます。次に、SnapshotManager::Read*() メソッドを呼び出します。

次の例は、保存済みゲームを開く方法を示しています。

  LogI("Opening file");
  service_->Snapshots()
  .Open(current_snapshot_.FileName(),
               gpg::SnapshotConflictPolicy::BASE_WINS,
        [this](gpg::SnapshotManager::OpenResponse const & response) {
           LogI("Reading file");
           gpg::SnapshotManager::ReadResponse responseRead =
           service_->Snapshots().ReadBlocking(response.data);
          
        }

データの競合を検出して解決する

SnapshotMetadata オブジェクトを開くと、保存済みゲームサービスは競合する保存済みゲームが存在するかどうかを検出します。プレーヤーのローカル デバイスに保存されている保存済みゲームが、Google のサーバーに保存されているリモート バージョンと同期していないと、データ競合が発生することがあります。

保存済みゲームを開くときに指定する競合ポリシーは、データ競合を自動的に解決する方法を保存済みゲームサービスに指示します。ポリシーは次のいずれかです。

紛争に関するポリシー 説明
SnapshotConflictPolicy::MANUAL 保存済みゲーム サービスが解決アクションを実行しないことを示します。代わりに、ゲームはカスタム マージを実行します。
SnapshotConflictPolicy::LONGEST_PLAYTIME 保存済みゲームサービスが、プレイ時間の値が最も大きい保存済みゲームを選択することを示します。
SnapshotConflictPolicy::BASE_WINS 保存済みゲームサービスがベースの保存済みゲームを選択することを示します。
SnapshotConflictPolicy::REMOTE_WINS 保存済みゲームサービスがリモートの保存済みゲームを選択することを示します。リモート バージョンは、プレーヤーのデバイスのいずれかで検出された、ベース バージョンよりも新しいタイムスタンプを持つ保存済みゲームのバージョンです。

GPGSnapshotConflictPolicyManual 以外の競合ポリシーを指定した場合、保存済みゲーム サービスは保存済みゲームを統合し、結果の SnapshotManager::OpenResponse 値を介して更新されたバージョンを返します。ゲームは保存済みゲームを開いて書き込みを行い、SnapshotManager::Commit(...) メソッドを呼び出して保存済みゲームを Google のサーバーに commit できます。

カスタム結合を実行する

競合ポリシーとして SnapshotConflictPolicy::MANUAL を指定した場合、ゲームは、保存済みゲームに対してさらに読み取りまたは書き込みオペレーションを実行する前に、検出されたデータ競合を解決する必要があります。

この場合、データ競合が検出されると、サービスは SnapshotManager::OpenResponse を介して次のパラメータを返します。

  • この競合を一意に識別する conflict_id(この値は、保存済みゲームの最終バージョンを commit するときに使用します)。
  • 競合する保存済みゲームのベース バージョン。
  • 競合する保存済みゲームのリモート バージョン。

ゲームは、保存するデータを決定し、SnapshotManager::ResolveConflictBlocking() メソッドを呼び出して、最終バージョンを Google のサーバーに commit または解決する必要があります。

    //Resolve conflict
    gpg::SnapshotManager::OpenResponse resolveResponse =
        manager.ResolveConflictBlocking(openResponse.conflict_base, metadata_change,
                                  openResponse.conflict_id);

保存済みゲームを作成する

保存済みゲームを書き込むには、まずその保存済みゲームを表す SnapshotMetadata オブジェクトを開き、検出されたデータ競合を解決してから、SnapshotManager::Commit() メソッドを呼び出して保存済みゲームの変更を commit します。

次の例は、変更を作成し、保存済みゲームを commit する方法を示しています。

  1. まず、編集するスナップショットを開き、ベースを選択してすべての競合が解決されていることを確認します。

    service_->Snapshots().Open(
          file_name,
          gpg::SnapshotConflictPolicy::BASE_WINS,
          [this](gpg::SnapshotManager::OpenResponse const &response) {
            if (IsSuccess(response.status)) {
              // metadata : gpg::SnapshotMetadata
              metadata = response.data;
            } else {
              // Handle snapshot open error here
            }
          });
    
  2. 次に、カバー画像に使用される画像データを含む保存済みゲームの変更を作成します。

    gpg::SnapshotMetadataChange::Builder builder;
    gpg::SnapshotMetadataChange metadata_change =
        builder.SetDescription("CollectAllTheStar savedata")
                 .SetCoverImageFromPngData(pngData).Create();
    
  3. 最後に、保存したゲームの変更を commit します。

    gpg::SnapshotManager::CommitResponse commitResponse =
        service_->Snapshots().CommitBlocking(metadata, metadata_change, SetupSnapshotData());
    

    data パラメータには、保存するセーブゲーム データがすべて含まれます。この変更には、プレイ時間や保存済みゲームの説明など、保存済みゲームの追加メタデータも含まれています。

コミット オペレーションが正常に完了すると、保存済みゲーム選択 UI に保存済みゲームが表示されます。