# PlayDrop の独自アセット形式とプレイヤーの作品

アセット仕様で独自のアセット形式を定義し、ゲームが読み書きする形式を宣言して、プレイヤーがレベルやキャラクターなどの作品を sdk.assets.custom で保存・公開できるようにします。

Source: https://www.playdrop.ai/ja/create/learn/custom-assets

アセット仕様を使うと、レベル、キャラクター、デッキなど、ゲーム独自の種類のアセットを、ファイルの取り決めとして定義できます。プレイヤーはその形式で作品を作って保存・公開でき、その形式に対応したほかのゲームでも作品を開けます。

## アセット仕様を定義する

アセット仕様は、catalogue.json の `apps` と並ぶ `assetSpecs` リストで宣言します。

```json
{
  "assetSpecs": [{
    "name": "moon-level",
    "version": "1.0.0",
    "displayName": "Moon Jump level",
    "symbol": "specs/moon-level.svg",
    "contract": "specs/moon-level.contract.json"
  }]
}
```

コントラクトには、各アセットのファイルとその検証方法を記述します。

```json
{
  "primaryRole": "level",
  "roles": [
    { "name": "level", "required": true, "contentTypes": ["application/json"], "mode": "TEXT",
      "jsonSchema": { "type": "object", "required": ["tiles"], "properties": { "tiles": { "type": "array" } } } },
    { "name": "thumbnail", "required": false, "contentTypes": ["image/png"], "mode": "BINARY" }
  ]
}
```

ロールには JSON Schema を付けられ、PlayDrop は保存のたびにそれを検証します。形式を変更するときは、新しいバージョンの仕様を公開してください。既存のアセットは元のバージョンのまま残ります。

## ゲームが対応する形式を宣言する

```json
{
  "assetSpecSupport": [
    { "assetSpec": "asset-spec:your-name/moon-level", "versionRange": "^1.0.0", "capabilities": ["READ", "WRITE"] }
  ]
}
```

指定できる機能は `READ`、`WRITE`、`EDIT`、`PREVIEW`、`IMPORT` です。

## プレイヤーの作品を保存・読み込む

```js
const levels = sdk.assets.custom.forSpec("asset-spec:your-name/moon-level");

await levels.saveDraft({ assetName: "crater-run", displayName: "Crater run",
  files: { level: new Blob([JSON.stringify(level)], { type: "application/json" }) } });
await levels.publish({ assetName: "crater-run", displayName: "Crater run", files: { level: levelBlob, thumbnail: pngBlob } });

const mine = await levels.listMine();
const latest = mine[0]?.latestPublicVersion;
if (latest) startLevel(await levels.loadJson({ assetRef: latest.assetRef, role: "level" }));

const community = await levels.listPublic({ limit: 20 }); // { assets, pagination }
```

- `saveDraft` は非公開の下書きとして保存し、`publish` は作品を公開します。どちらもファイル一式がすべて必要です。
- アセットの参照は `asset:creator/name@r2` のような形式です。`loadJson`、`loadText`、`downloadFile` は公開済みのアセットを読み込み、`loadOwned`、`loadOwnedJson`、`loadOwnedFile` は下書きを含むプレイヤー自身のアセットを読み込みます。
- `supports(versionRef, capability)` を使うと、別のバージョンのアセットを開く前に対応しているか確認できます。
- エラーには `custom_asset_capability_unsupported` や `custom_asset_role_type_mismatch` などのコードが使われます。

保存するには、プレイヤーがサインインしている必要があります。プレイヤーが公開する作品は、ほかのユーザーコンテンツと同じように確認してください。PlayDrop のコンテンツポリシーが適用されます。

## コネクタが受け付けるもの

データのみの独自アセットと仕様は、ほかのファイルと同じようにアップロードできます。実行可能なモデル、つまり `procedural` サブカテゴリーまたは `CUSTOM` 形式の `MODEL_3D` アセットは、API がクリエイターのコードを実行しないため、コネクタでは拒否されます。ベイクするか、公開済みのバージョンを参照してください。[ゲームアセット](https://www.playdrop.ai/ja/create/learn/game-assets)をご覧ください。

## 関連ガイド

- [ゲームアセット](https://www.playdrop.ai/ja/create/learn/game-assets): PlayDrop ゲームに画像、サウンド、動画、3D を含める方法：同梱ファイル、catalogue.json で宣言するゲーム所有アセット、公開アセットとパック、sdk.assets による実行時の参照。
- [catalogue.json](https://www.playdrop.ai/ja/create/learn/catalogue-json): PlayDrop ゲームが使う catalogue.json のフィールド：識別情報、掲載情報、遊び方、表示環境、サインイン、インスタント、事前読み込み、メディア、翻訳、スコア、サーバー。
- [クライアント SDK](https://www.playdrop.ai/ja/create/learn/sdk): PlayDrop ブラウザ SDK のリファレンス：初期化、ホストのライフサイクル、プレイヤー情報とセーブ、デバイスとコントローラー、ソーシャル、マルチプレイヤー、ショップ、広告、ランキング、実績、アセット、AI。
