あなたのゲームにセーブドゲームを追加する



  • この記事は、Google Playゲームサービスに関する記事を和訳したものです。
  • 原文: Adding Saved Games to Your Game
  • 元記事のライセンスは CC-BYで、この和訳記事のライセンスは CC-BYです。
  • 自己責任でご利用ください。
  • 和訳した時期は 2019年7月ころです。

このガイドは、C++アプリケーションにてセーブドゲームサービスを使用してプレイヤーのゲームの進行状況のデータをセーブし、ロードする方法を示しています。 ゲームプレイ中の任意の時点で、プレイヤーのゲームの進行状況を自動的にロードし。セーブするために、このサービスを使用することができます。 さらには、このサービスは、プレイヤーが既存のセーブドゲームを更新あるいは復元するための、あるいは新しいものを作成するためのユーザインタフェースをトリガすることを有効にすることができます。

始める前に

もしまだそうしていなければ、セーブドゲームのゲームコンセプトをレビューすることは役立つかもしれません。

セーブドゲーム 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の値を通して更新されたバージョンを返すでしょう。 あなたのゲームはセーブドゲームを開き、それに書き込み、それから、Googleのサーバにセーブドゲームをコミットするために SnapshotManager::Commit(...)メソッドを呼び出します。

カスタムマージを実行する

もし競合ポリシーとして SnapshotConflictPolicy::MANUALを指定したならば、あなたのゲームは、セーブドゲーム上で読み込みあるいは書き込みの操作を実行する前に検出されたすべてのデータの競合を解決しなければなりません。

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

  • A conflict_id to uniquely identify this conflict (you will use this value when committing the final version of the saved game); この競合をユニークに識別するための conflict_id(セーブドゲームの最後のバージョンをコミットするときにこの値を使用するでしょう);
  • 競合するセーブドゲームのベースのバージョン; そして、
  • 競合するセーブドゲームのリモートのバージョン。

あなたのゲームはどのデータをセーブするか決定しなければならず、それから、Googleのサーバに最後のバージョンをコミット/解決するために SnapshotManager::ResolveConflictBlocking()メソッドを呼び出さなければなりません。

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

セーブドゲームを書き込む

セーブドゲームを書き込むには、まず、そのセーブドゲームを表す SnapshotMetadataオブジェクトを開き、検出されたすべてのデータの競合を解決し、それから、あなたのセーブドゲームの変更をコミットするために SnapshotManager::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. 最後に、セーブドゲームの変更をコミットします。

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

    データパラメータは、あなたが格納しているセーブドゲームのデータすべてを含んでいます。 さらには、その変更は、プレイ時間やセーブドゲームの説明といった追加的なセーブドゲームのメタデータを含んでいます。

もしコミット操作が正常に完了したならば、プレイヤーはセーブドゲーム選択 UIにてセーブドゲームを見ることができます。