# PlayDrop ゲームのクラウドセーブ

sdk.me.appData と sdk.me.updateAppData でプレイヤーの進行状況を保存・読み込みます。ゲストとサインイン中のプレイヤーへの対応、書き込み、プレビュー、オフラインのルールも説明します。

Source: https://www.playdrop.ai/ja/create/learn/cloud-saves

クラウドセーブは、プレイヤーごとのゲームの進行状況を PlayDrop に保存し、ウェブサイトからアプリまでどこでも引き継げるようにします。保存されるのは、プレイヤーとゲームの組み合わせごとに JSON オブジェクト1つです。サーバーやマルチプレイヤーのルームは必要ありません。

## 読み込みと書き込み

`init()` のあと、`sdk.me.appData` は保存済みのスナップショット `{ data, seq, ts_event, ts_arrival }` になります。最初の保存前は `null` です。自分のオブジェクトは `data` から読み取ります。書き込みは `updateAppData` でオブジェクト全体を送ります。保存されたスナップショットが返され、`sdk.me.appData` も更新されます。

```js
const sdk = await playdrop.init();
let progress = { level: 1, coins: 0, ...(sdk.me.appData?.data ?? {}) };
let queue = Promise.resolve();

// Resolves with the saved snapshot; rejects when the save failed.
function save(changes) {
  progress = { ...progress, ...changes };
  const snapshot = { ...progress };
  const attempt = queue.then(() => sdk.me.updateAppData(snapshot));
  queue = attempt.catch(() => {}); // a failed save must not block the next one
  return attempt;
}

try {
  await save({ level: 2 });
  showSaved();
} catch (error) {
  showSaveError(); // progress stays in memory; the next save sends it again
}
```

- 書き込みのたびに、保存済みのオブジェクト全体が置き換わります。必要なフィールドはすべて残してください。
- 上の例のように書き込みを順番に実行し、古いセーブが新しいセーブのあとに届かないようにします。失敗したあともキューを止めないでください。
- 「保存しました」と表示するのは、Promise が正常終了してからにします。メモリ上の `appData.data` を変更しても、何も保存されません。
- `appData` には `get`、`set`、`save` メソッドはありません。

## 保存するタイミング

毎フレームではなく、チェックポイント、レベルの終了時、購入時に保存しましょう。プレビューやキャプチャ中は絶対に保存しないでください。書き込むのは `sdk.host.phase` が `play` のときだけです。セーブは小さく保ち、`saveVersion: 2` のような独自のフィールドでバージョンを付けておくと、のちのゲームのバージョンで移行できます。

## ゲストとサインイン中のプレイヤー

保存する前に `sdk.me.isLoggedIn` を確認する必要はありません。PlayDrop のゲストもセーブを保持できます。セッションがまったくないプレイヤーは、その訪問の間だけメモリ上にセーブを保持します。そのため、書き込みが正常終了しても、セーブがクラウドに届いた証明にはなりません。`isLoggedIn` は、購入やホスト型マルチプレイヤーなど、実際のアカウントが必要な機能にだけ使ってください。

## オフライン

ブラウザでは、セーブにネットワーク接続が必要で、オフライン用のキューはありません。失敗してもプレイを続けられるようにし、次のチェックポイントで再試行してください。オフライン対応の PlayDrop アプリなど、デバイスデータへの対応を示すホストは、セーブをデバイスに保存し、オンラインになったときに同期します。

## セーブではできないこと

セーブは、1人のプレイヤーと1つのゲームに限定された非公開のデータです。[ランキング](https://www.playdrop.ai/ja/create/learn/leaderboards)や[実績](https://www.playdrop.ai/ja/create/learn/achievements)とは別物で、これらには専用の API があり、PlayDrop 上に表示されます。対戦やワールドなど、プレイヤー間で共有する状態は、[ゲームサーバー](https://www.playdrop.ai/ja/create/learn/game-servers)上のゲーム専用の MongoDB コレクションに置きます。

## テスト

セーブはアップロード済みのゲームに紐づきます。非公開バージョンを少なくとも1回アップロードしてから、アップロード結果の `url` か、[AI アプリからの公開](https://www.playdrop.ai/ja/create/learn/mcp-publishing)で説明しているローカルの Dev フレームからテストしてください。

## 関連ガイド

- [ランキング](https://www.playdrop.ai/ja/create/learn/leaderboards): catalogue.json でランキングを宣言し、sdk.leaderboards でスコアを送信して、上位とプレイヤー周辺の順位を表示します。スコアの種類、制限、更新のルールも説明します。
- [実績](https://www.playdrop.ai/ja/create/learn/achievements): catalogue.json でアイコン付きの通常実績と段階実績を宣言し、sdk.achievements で実績の解除と進行状況の報告を行います。
- [リアルタイムゲームサーバー](https://www.playdrop.ai/ja/create/learn/game-servers): MongoDB データベース付きのホスト型 Colyseus 0.17 サーバーでゲームを動かし、ブラウザから SDK で接続し、2人のプレイヤーでテストする方法と制限を説明します。
