save-load について
Godot 4.3以降でセーブ・ロード機能を設計する開発者向けのスキルです。シリアライズ方式を比較し、設定、ゲームセーブ、保存構成、保存先、バージョン移行をGDScriptとC#の例で解説します。
主な機能
- 01ConfigFile、JSON、Resourceの比較
- 02設定とゲームセーブのシリアライズ指針
- 03SaveableComponentによる構成パターン
- 04保存先とバージョン移行
- 05Resourceファイルのセキュリティ上の注意
活用シーン
- 01音声、映像、操作設定の保存
- 02読みやすいファイルへのゲーム状態の保存
- 03ゲーム内ノードにまたがる永続データの整理
- 04データ形式の変更に伴うセーブの移行
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ jame581/ godotprompter --skill save-loadインストール後、Claude Code で/save-loadを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/configfile.mdjson-saves.mdsave-architecture.mdversion-migration.md詳細
Godot 4.3+ のセーブ/ロードシステム
データ型に適したシリアライズ方式を選びましょう。すべての例は、非推奨 API を使わずに Godot 4.3+ を対象としています。
関連スキル: カスタム Resource データコンテナーには resource-pattern、インベントリのシリアライズパターンには inventory-system、SaveManager の自動読み込み設定には godot-project-setup、アドベンチャーフレームワークのセーブには popochiu を参照してください。
1. 方式の比較
| 方式 | 最適な用途 | 読みやすさ | エディター対応 | 備考 |
|---|---|---|---|---|
| ConfigFile | 設定、シンプルなキーと値のデータ | はい | いいえ | 組み込みの INI 形式、追加の依存関係なし |
| JSON | ゲームのセーブ、柔軟な構造 | はい | いいえ | クロスプラットフォーム、バージョン移行可能 |
| Resource .tres | エディターと統合されたデータ | はい | はい | 安全ではありません — 信頼できないファイルは絶対に読み込まないでください |
| Resource .res | 高速なバイナリデータ | いいえ | はい | 安全ではありません — 信頼できないファイルは絶対に読み込まないでください |
方式を推奨するときは、採用しなかった方式と、決め手となった要因を明示してください。「セーブデータはユーザーが書き換え可能で、Resource を読み込むとコードが実行されるため、Resource ファイルではなく JSON」のように説明します。代替案が明示されていない形式の選択は、覆すことができません。
セキュリティ警告:
.tresまたは.resファイルを読み込むと、リソースに埋め込まれた任意の GDScript が実行されます。信頼できないソース(ユーザーがアップロードしたファイルやダウンロードした MOD など)から Resource ファイルを読み込まないでください。ユーザー生成のセーブデータには ConfigFile または JSON を使用してください。
2. ConfigFile — 設定
ConfigFile は INI 形式のセクションを書き出します。オーディオ/ビデオ/操作設定など、小規模でデザイナーがデバッグしやすい設定に最適です。set_value(section, key, value) で値を設定し、save(path) で保存します。load(path) で読み込み、get_value(section, key, default) で値を取得します。
GDScript と C# の設定保存/読み込み、および一般的な設定メニューとの連携については、references/configfile.md を参照してください。
3. JSON — ゲームのセーブ
JSON.stringify(dict) でシリアライズし、JSON.parse_string(text) でデシリアライズします。FileAccess を通じて読み書きします。人が読めるファイルにしたいゲームのセーブデータに最適です。ゲームの状態(プレイヤーの位置、インベントリ、ワールドのフラグなど)をすべて格納した Dictionary を作成してシリアライズし、user://save_<slot>.json に書き込みます。
FileAccessによるラップやエラー処理を含む、GDScript と C# の完全な保存/読み込み実装については、references/json-saves.md を参照してください。
⚠️ Godot 4.7 での変更:
JSON.stringify(data, indent = "", sort_keys = true, full_precision = false)は、indentを指定しても空のDictionaryを{}としてコンパクトにシリアライズするようになりました(GH-115883)。アップグレード後は、インデント付きで書き出されるセーブファイルの空の Dictionary フィールドの形式が変わります。セーブ出力をバイト単位で差分比較またはハッシュ化する処理では、新しい形式を許容する必要があります。解析への影響はありません。
4. セーブのアーキテクチャパターン
規模の大きなゲームでは、永続化する各ノードに SaveableComponent を追加します。各コンポーネントは、安定した save_id と、serialize および deserialize の 2 つの callable を持ち、saveable グループに加わります。セーブマネージャーはそのグループを走査し、各 serialize を呼び出して、save_id をキーとするマスター Dictionary を作成します。
SaveableComponentとセーブマネージャーの完全な実装については、references/save-architecture.md を参照してください。
5. セーブファイルの保存場所
user:// は、プロジェクトフォルダーの外にある、プラットフォーム固有の書き込み可能なディレクトリを指します。
| プラットフォーム | パス |
|---|---|
| Windows | %APPDATA%\Godot\app_userdata\<project-name>\ |
| macOS | ~/Library/Application Support/Godot/app_userdata/<project-name>/ |
| Linux | ~/.local/share/godot/app_userdata/<project-name>/ |
セーブデータには必ず
user://を使用し、res://は使用しないでください。エクスポートしたビルドでは、res://パスは読み取り専用です。
6. バージョン移行
セーブファイルは、書き込みに使用されたスキーマよりも長く存続します。保存する Dictionary の先頭には必ず "version": <int> を含めてください。読み込み時にはバージョンに応じて処理を切り替え、古いセーブを段階的に新しい形式へ移行します(v1 → v2 → v3 → current)。古いセーブを使えなくすることは避け、必ず移行してください。
移行ヘルパーのパターン全体については、references/version-migration.md を参照してください。
7. 実装チェックリスト
- 設定には ConfigFile、ゲームのセーブには JSON を使用します(Resources は使用しません)
- すべてのセーブファイルに
versionの整数フィールドが含まれています - セーブパスには
user://を使用し、res://は使用しません - セーブを書き込む前に
DirAccess.make_dir_recursive_absolute()を呼び出します - Vector2/Vector3 は個別の
x/y/zの浮動小数点数としてシリアライズします(JSON には Vector 型がありません) - すべてのファイル操作で戻り値コードを確認し、失敗時には
push_error()を呼び出します -
_migrate()はバージョン 0 から現在のバージョンまでのすべてに対応し、段階的に適用します - リソースファイル(.tres/.res)は、プレイヤーが管理するセーブデータには使用しません
- UI のスロット管理用に
get_save_slots()とdelete_save()のヘルパーが存在します - セーブ可能なノードには、セッション間で変わらない安定した ID を使用します