게임에 저장된 게임 추가

이 가이드에서는 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 서버에 커밋할 수 있습니다.

커스텀 병합 수행

SnapshotConflictPolicy::MANUAL를 충돌 정책으로 지정한 경우 게임은 저장된 게임에서 추가 읽기 또는 쓰기 작업을 실행하기 전에 감지된 데이터 충돌을 해결해야 합니다.

이 경우 데이터 충돌이 감지되면 서비스는 SnapshotManager::OpenResponse를 통해 다음 매개변수를 반환합니다.

  • 이 충돌을 고유하게 식별하는 conflict_id (저장된 게임의 최종 버전을 커밋할 때 이 값 사용)
  • 저장된 게임의 기본 버전 충돌
  • 저장된 게임의 충돌되는 원격 버전입니다.

게임에서 저장할 데이터를 결정한 다음 SnapshotManager::ResolveConflictBlocking() 메서드를 호출하여 Google 서버에 최종 버전을 커밋/확인해야 합니다.

    //Resolve conflict
    gpg::SnapshotManager::OpenResponse resolveResponse =
        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에서 저장된 게임을 볼 수 있습니다.