mcpField
B
bevy-save-load

bevy-save-load

github.com/chrisgliddon開発2662 回インストール9 週間前に更新
リポジトリ

bevy-save-load について

Bevy 0.19のゲーム開発者向けのセーブ・ロード設計ガイドです。実行中のECS構造ではなく、独立したバージョン付きデータモデルを推奨し、移行、安定ID、検証、復旧、ネイティブとブラウザーのストレージを扱います。

主な機能

  1. 01独立したバージョン付きセーブ形式の設計
  2. 02安定IDと二段階ロードの利用
  3. 03明示的な移行とデータ検証
  4. 04ネイティブファイルとブラウザーストレージへの対応
  5. 05スナップショット、差分、復旧の計画

活用シーン

  1. 01ECSやコンテンツの再構成後もセーブ互換性を維持
  2. 02大規模ワールドのスナップショットと差分を管理
  3. 03ネイティブ版とブラウザー版で非同期セーブを実装

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/chrisgliddon/bevy-skills --skill bevy-save-load

インストール後、Claude Code で/bevy-save-loadを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
native-and-browser-io.md
schema-migrations-and-ids.md
snapshots-deltas-and-world-serialization.md

詳細

Bevy 0.19 — 保存と読み込み

このスキルを使う場面

  • ECS/コンテンツ/コードのリファクタリング後も、ゲームプレイの状態を読み込み可能な状態に保つ必要がある場合。
  • 大規模なワールドで、ベーススナップショット、スパースな差分、圧縮、復旧が必要な場合。
  • ネイティブ版とブラウザー版で、共通の非同期セーブサービス契約が必要な場合。
  • リフレクションを使ったワールドのシリアライズを、永続的なセーブ形式として検討している場合。

セーブファイルは長期にわたって使われる製品 API です。明示的にバージョン管理したデータモデルをシリアライズし、実行中の ECS との相互変換を行ってください。実行時の Entity 値、密なパレットインデックス、クエリ順序、Rust の列挙型判別子、リフレクションによるコンポーネントのレイアウトは、永続化する識別子として安定していません。

標準的なパターン

use serde::{Deserialize, Serialize};

#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
#[serde(transparent)]
struct SaveId(String);

#[derive(Debug, Deserialize, Serialize)]
struct SaveV3 {
    world_seed: u64,
    player: SaveId,
    actors: Vec<ActorV3>,
}

#[derive(Debug, Deserialize, Serialize)]
struct ActorV3 {
    id: SaveId,
    archetype: String,
    position: [f32; 3],
}
live Bevy World
  -> validate/capture one logical revision
  -> current Save DTO with stable IDs
  -> encode + checksum envelope
  -> platform storage transaction

platform bytes
  -> size/magic/checksum validation
  -> decode declared old DTO
  -> migrate one version at a time
  -> validate current DTO
  -> allocate entities, then resolve stable-ID references
  -> rebuild derived/runtime-only state

バイト列のデコードや移行が完了する前に、アクティブなワールドを部分的に変更してはいけません。ステージング領域に読み込み、検証してから、ゲームプレイのワールドをコミットするか置き換えてください。

エンベロープとペイロードをバージョン管理する

エンコードしたペイロードのバイト列を、マジック値、フォーマットバージョン、スキーマ/コンテンツバージョン、ペイロード長、コーデック/圧縮の識別子、チェックサムでラップしてください。チェックサムは偶発的な破損の検出に使えますが、悪意ある改ざんは防げません。信頼性の確保が要件に含まれる場合は、認証または署名を使用してください。

移行は、明示的な純粋関数 V1 -> V2 -> V3 として維持してください。破損、切り詰め、ID の重複、未知の ID、将来のバージョンのファイルなど、サポートするすべてのバージョンについてゴールデンフィクスチャをテストしてください。古いバージョンを現在の構造体に直接デシリアライズし、Serde のデフォルト値で古いセマンティクスが再現されると期待してはいけません。

安定した ID と二段階の読み込み

保存するオブジェクト、コンテンツ、クエスト、アイテム、ボクセルのブロックタイプには、不変のドメイン ID を使用してください。読み込み時は次の手順に従います。

  1. ID の一意性と、すべてのサイズ/件数上限を検証します。
  2. オブジェクトを生成/割り当て、SaveId -> Entity または安定 ID -> 密なパレットのマップを構築します。
  3. 2 回目のパスで関係性を解決します。
  4. ポリシーに従い、未知のコンテンツを拒否するか、明示的に保持します。
  5. キャッシュ、ハンドル、物理状態、タスク、診断情報、プレゼンテーションを再構築します。

ストレージはプラットフォームごとに異なります

ネイティブ版での書き込みでは、保存先ディレクトリに一時ファイルを作成し、必要に応じてフラッシュして同期した後、確定済みのスロットをアトミックに置換または名前変更してください。復旧が重要な場合は、検証済みのバックアップを保持するか、2 スロット世代方式を使用してください。ブロッキングするファイル I/O は IoTaskPool で行い、結果をメインワールドに返してください。

ブラウザーには、通常のセーブファイルパスがありません。ゲームのセーブデータや大容量データには IndexedDB を使用し、小さな設定には local storage を使用できます。非同期処理の完了、容量制限、データ削除、プライベートモード、タブ間の競合、エクスポート/インポート、ページの終了に対応してください。「セーブ完了」という UI 状態にするには、ストレージへの確定を確認する必要があります。

Bevy 0.19 の SettingsPlugin は、ネイティブ/local storage のバックエンドを使うユーザー設定を対象としています。汎用的なキャンペーン/ワールドセーブ用スキーマではありません。

注意点:ワールドシリアライズの境界

bevy_world_serialization と DynamicWorldBuilder は、コンポーネント/リソースの許可/拒否フィルターを使って、リフレクション対応のエンティティとリソースを抽出できます。これは、作成済みのワールドアセット、エディターツール、制御されたスナップショット、短期間だけ使用する内部形式に便利です。ただし、安定したゲームプレイ ID、スキーマ移行、破損からの復旧、トランザクション対応のストレージ、コンポーネントのリファクタリングをまたいだ互換性が自動的に作られるわけではありません。

長期保存するプレイヤーセーブには、明示的な DTO を使用してください。フィルター済みの DynamicWorld をその形式に含める場合は、外側の契約をバージョン管理して移行し、リフレクション対象の型を一つずつ意図的に監査してください。

関連する詳細ガイドを選ぶ

問題読む項目
DTO のバージョン、移行、安定 ID、検証、ゴールデンフィクスチャスキーマ、移行、ID
アトミックなネイティブ書き込み、ブラウザーストレージ、非同期状態、復旧ネイティブとブラウザーの I/O
フルスナップショット、スパースな差分、圧縮、ワールドシリアライズの境界スナップショット、差分、ワールドシリアライズ

レビューチェックリスト

  • セーブデータ用の型は、実行中の ECS/ランタイムコンポーネントとは分離されています。
  • 永続化される参照にはすべて、文書化された安定 ID が使われています。
  • 古いバージョンは順番にマイグレーションされ、フィクスチャがコミットされています。
  • デコーダーは、割り当て/展開の前に、信頼できない長さや件数を制限します。
  • ネイティブ環境での電源喪失や、ブラウザーのクォータ超過/終了が発生しても、復旧可能なスロットが残ります。
  • 成功は、プラットフォームのコミットが完了した後にのみ報告されます。
  • スナップショットと差分の世代が、誤って混在することはありません。
  • 未知の将来バージョンは、元のデータを上書きせず、安全に失敗します。

関連項目

コメント