🏠 なおしや
🎮
ゲーム開発の困った

Unityで体験版配布後にセーブ形式を変えても旧データを守る方法

2026-08-17 ・ Unityセーブ互換化箱(SaveCompat)
12,800円

こんなことで困っていませんか

長編RPGを個人開発していると、開発途中で何度もセーブの構造を変えることになります。主人公1人の平らな構造からパーティ配列へ、所持金をひとつの数値から財布オブジェクトへ、といった変更は実際に起きます。すでに体験版や早期アクセス版を配ってしまっている場合、後から形式を変えるとプレイヤーが持っている旧セーブを壊しかねません。「移行が成功したのに中身が減っていた」という事故を目視レビューだけに頼らず出荷前に機械で止めたい、電源断やSSDの機嫌でセーブが壊れる事故を実際に検査した状態で防ぎたい、という開発者向けのライブラリです。

これで解決します

Unityで作ったゲームのセーブ形式を変えても、旧バージョンで保存されたデータがそのまま読めるようにするC#のクラスライブラリです。世代スキーマ、移行の鎖、原子的書き換え、世代バックアップ、旧セーブfixturesの一括回帰試験、ゲーム内復旧UI、サンプルRPGが一式に入っています。

移行は1世代ずつしか繋げず、v1→v3のような飛び越しは登録時に例外で弾かれます。鎖に穴があれば「旧セーブを読んだ瞬間」ではなく開発中の最初の起動で気づけます。移行が値を捨てたかどうかは機械が検出し、1段ごとに入ってきた木と出ていった木を突き合わせて、台帳の言葉で宣言していない欠落が1件でもあれば移行を止めます。台帳は13種類あり(field-removed〈重〉、enum-value-unknown〈重〉など)、宣言できるのは台帳に載っているcodeだけです。

書き込みは.tmp書き込み→fsync→バックアップ世代のずらし→確定renameという手順で、11個の注入点すべてで電源断・途中切断・ビット化けを自動検査済みです(自動試験182件、実装をわざと壊した複製で試験が落ちることを確認する変異試験41本)。セーブの見出しは1行のASCIIで、中身がバイナリでも見出しだけは読めます。


USVC1 codec=json1 schema=1 len=254 crc=938f3ac1 hcrc=dd4d4e74

無料でどこまで試せるか

無料版は機能を隠さず、量だけを制限しています。

| | 無料版 | 製品版 |

|---|---|---|

| スキーマの世代数 | 2世代まで(v1→v2の1段) | 上限なし |

| 原子的書き換え・世代バックアップ・障害注入 | 全機能 | 同じ |

| 破損検知・自動復旧 / codec両方 / fixturesランナー | 全機能・制限なし | 同じ |

| 3世代以上の移行の鎖・ゲーム内復旧UI・サンプルRPG | × | ○ |

上限を超えると次の1行で止まります(スタックトレースなし)。


error: 無料版はスキーマ2世代までです(この鎖はv4まであります)。

無料版・製品版のzipをdiffすると、違う.csファイルはSaveCompatEdition.csの1本だけで、差分は先頭の#define SAVECOMPAT_FREEという1行のみです。DLL単体検証でも無料版はmax_schema_versions=2、製品版は2147483647と確認できます。ライセンスキーもオンライン認証も無く、技術的には外せますが、対価は継続的な更新と問い合わせ対応に対して支払う形です。

既存の無料・安価な代替手段との違い

先に正直に書きます。この製品より安い代替があります。

TypedMigrate.NET(無料・OSS)で足りるなら、それで十分です。 型付き・serializer非依存の世代移行を無料で提供しており、「移行の鎖そのもの」が欲しいだけなら本製品は要りません。

ChronoSave – Secure & Scalable Save System($24.99、約3,700円)のほうが安いです。 schema version・migration pipeline・破損検知・.bak自動復旧を1製品で持ち、セーブシステムそのものが欲しいだけならこちらのほうが安く、価格差は3倍以上あります。

本製品が引き受けているのはその先の運用部分です。どちらも「移行を実行する」道具であって、過去に出荷した全ての版の実データが今のビルドで今も読めるかを確かめる仕組みは持っていません。本製品はfixtures/vN/*.save(凍結した旧セーブ)と*.expected.json(期待値)の組を1コマンドで一括回帰試験でき、欠落台帳と合わせて「移行が成功したのに中身が減っている」を実装上できなくしています。またTypedMigrate.NETは型付きのため出荷した全版のDTOクラスを残し続けますが、本製品の移行は型無しの木(SaveNode)を書き換えるので旧版のクラスを削除でき、失敗時にプレイヤーが世代を選んで戻せる復旧UIも付属します。ここに9,000円ほどの差を払う価値が無いなら、買わないほうがよい製品です。

なお、クラウドセーブ・暗号化やチート対策・Unity以外のエンジンへのサポート・マイグレーションの自動生成は対応しません。CRC32は破損検知のためだけで、改造対策には一切なりません。

実際に使うには

ゲーム側の動作環境はUnity 2021.3 LTS以降(.NET Standard 2.1)で、外部パッケージは不要です(NuGetパッケージの追加は要りません)。付属のCLIを使うときだけ.NET SDK 8.0以降が必要です。なお、開発環境にUnity Editorが無かったため、コア部分は自動試験182件で検証済みですが、MonoBehaviourや復旧UIの描画、サンプルRPGはUnity Editor上で動かしておらず、UnityEngineの最小スタブへのコンパイル確認のみです。

購入前でも検査は実行できます(.NET SDK 8.0以降、NuGet依存ゼロ)。


bash verify.sh

移行の鎖はこのように書きます。


chain.Add(1, (node, ctx) => {
    ctx.Drop("field-renamed", "name", "party/0/displayName へ移した");
    ctx.Drop("field-renamed", "hp",   "party/0/hp へ移した");
    SaveNode hero = SaveNode.NewObject();
    hero.Set("displayName", node["name"].AsString);
    hero.Set("hp", node["hp"].AsInt);
    SaveNode party = SaveNode.NewArray();
    party.Add(hero);
    SaveNode next = SaveNode.NewObject();
    next.Set("party", party);
    return next;
});
chain.Validate();   // 鎖に穴が無いことを起動時に確かめる

ctx.Drop(...)を書き忘れると、宣言されていない欠落として開発中にその場で止まります。Unity側はsave.Configure(chain, MiniRpgSchema.Summarize)で起動時に設定し、save.Save(slot: 0, data: state)で原子的に書き、save.Load(0)で必要なら移行して読み込みます。

版を上げる直前に代表的なセーブを凍結し、期待値を作り直してgit diffで目視確認する運用です。


dotnet run --project tests/SaveCompat.Tests -- capture-fixtures fixtures
dotnet run --project tests/SaveCompat.Tests -- fixtures fixtures

まずは無料版で自分のゲームの移行の鎖(2世代まで)を実際に組み、電源を落としても壊れないか、旧セーブが読めるかを買う前に確かめられます。

価格

単品買い切り12,800円で、BOOTHで販売されます。月額でも従量課金でもなく、ライセンスキーもオンライン認証もありません。解析も移行も端末内だけで完結し、外部サーバには何も送りません。無料版(unity-save-free-1.0.0.zip)は別ページで配布されます。

Unityセーブデータマイグレーション後方互換個人開発
← 他のお悩みも見る