いつの間にかセーブデータが肥大化する問題について(「Save data too big!」になる条件)

メルサイア
記事: 127
登録日時: 2016年2月22日(月) 10:35
お住まい: 大阪府
連絡を取る:

いつの間にかセーブデータが肥大化する問題について(「Save data too big!」になる条件)

投稿記事by メルサイア » 2016年11月20日(日) 22:12

はじめまして、メルサイアと申します。

現在作成中のゲームで、ある特定の条件を満たすと、セーブデータが肥大化する問題が出ているので、
その解決策をお尋ねしたく、ここに投稿させていただきます。

CxWGvuEVIAAfpJh.jpg

詳細は、ツイッターの方を見ていただけると、わかりやすいかもです。
https://twitter.com/merusaia/status/798691787632087040

参考までに、セーブデータが圧縮される前のJSONファイルを、
肥大化・肥大化前に分けて、以下でダウンロードできるようにしました。

A:肥大化前(ゲーム開始時)のセーブデータ(非圧縮のjsonファイル35KB。圧縮後13KB)
https://t.co/zdDULJChxg
B:肥大化したセーブデータ       (非圧縮のjsonファイル307KB。圧縮後62KB)
https://t.co/i8bUwgv9lk
Aをロードして、しばらくゲームをして、セーブすると、Bで10倍近く膨れ上がっています。

Bの中身を見ると、
不必要な「{…"@":Game_Actor}」や、 「{…"@":Game_ActionResult}」という情報とが120個位
入っているように見受けられるのですが、何のことだかわかっていません。
また、発生条件も不明です。

なお、このゲームでは、
・スイッチ・変数の最大数は共に5000個
・アクター数の最大数は150個
使用しているのですが、
これらはこの不必要な情報よりも上の行に、既に追加されているように見えます。

また、暗号のされ方は不明なため、この不必要な情報が容量の肥大化に関係しているかも不明です。

検証したところ、以下の条件での発生を確認しました。
・一度戦闘を行っただけで肥大化する(32KB→267KB)
いろいろ場合分けをしてみているのですが、今のところ手詰まりで、
セーブデータ肥大化のため、このままではクロスセーブは容量制限のため出来ず、
オートセーブは1ファイル毎に2~4秒ほど待たされ、利用が難しくなっています。

「こういう条件でのセーブを試してみてはどうか」とか、
「もっと具体的に様子を教えてほしい」など、
どんな些細な事でも結構ですので、ご助力をいただけると大変助かります。

以下、B(肥大化した方)の画像です。
添付ファイル
CxWEdBjUkAAjEb3.jpg
最後に編集したユーザー メルサイア on 2016年12月24日(土) 09:47 [ 編集 2 回目 ]

メルサイア
記事: 127
登録日時: 2016年2月22日(月) 10:35
お住まい: 大阪府
連絡を取る:

Re: いつの間にかセーブデータが肥大化する問題について(「Save data too big!」になる条件)

投稿記事by メルサイア » 2016年11月20日(日) 22:55

すみません。
一旦、大きな原因については、自己解決しました。

以下、検証結果です。
・アクター数の最大数を1000個にすると、大きく肥大化する     (13KB→50KB。圧縮前JSON: 35KB→266KB)
・アクター数の最大数を50個に減らすと、やや肥大化が抑えられる (13KB→29KB。圧縮前JSON: 35KB→112KB)
・アクター数の最大数を20個に減らすと、大きく肥大化が抑えられる(13KB→21KB。圧縮前JSON: 35KB→ 66KB)

どうやら、アクター数の最大数が大きな原因だったようです。

以下に、検証方法と、発生要件をまとめます。
・アクター数の最大数を1000にする
 → 新規でゲームを始め、セーブ①する(35KB。圧縮前JSON:13KB)
 → セーブ①でロードした後、一回だけ戦闘をして、セーブ②する
 → セーブ②データの容量が、セーブ①の数倍に増えている(13KB→50KB。圧縮前JSON: 35KB→266KB)

おそらく、戦闘時に、仲間にしていない空のアクターの
永続ステートや現在HP・MP・TP、その他情報を保存しているため、と考えられます。

ただ、何故かわたしのゲームはゲームをするほど、戦闘をすればするほどセーブデータの容量が増えていき、
いずれは圧縮後でも50KBを超えてしまうことが多いので、まだ根本的な解決には至っていません。
引き続き、調査を続けます。

他にも何かわかりましたら、適時追記したいと思います。
アバター
剣崎 宗二
記事: 686
登録日時: 2016年11月12日(土) 20:36
連絡を取る:

Re: いつの間にかセーブデータが肥大化する問題について(「Save data too big!」になる条件)

投稿記事by 剣崎 宗二 » 2016年11月21日(月) 01:44

お疲れ様です。こちらでデータ内部を解析してみましたが、1点、現象についての質問を。

「戦闘をすればするほど容量が爆増する」と言う理解で宜しいでしょうか。
その場合、「1度戦闘した後のセーブデータ」と、「その後さらに一度戦闘した後のセーブデータ」を比較して見るべきかと。(現在掲載されているデータにはこの「2戦闘後のデータ」がない為、こちらで比較が出来ません)

逆に、大幅な容量増加が初期の一戦闘後のみならば、仰るとおり空っぽのGameActorを一通り製造しているせいである可能性が高いです。その場合Actor最大数を減らすしかないかと。
(現在「1戦闘後のセーブデータ」を観察する限りでは、空のActor関係が理由である可能性が高いです。データの約1/2)

他に多少なりとも可能性があるのは各MAPのEvent辺りでしょうか。デフォルトのセーブデータの仕様を私は存じていないのでどういう感じかは知りませんが、イベントの現在出現状況、移動速度までセーブデータに詰込まれているのは少し違和感があります…
(データの約1/4)
----
-出先に居る場合回答が未テスト状態である事が多い為、テストは重々にお願いいたします。
-基本自分や友人の問題解決は自分で1からプラグインを書いているので、「こういうプラグインはありますか」に対しては助けになれません。ご了承ください。
メルサイア
記事: 127
登録日時: 2016年2月22日(月) 10:35
お住まい: 大阪府
連絡を取る:

Re: いつの間にかセーブデータが肥大化する問題について(「Save data too big!」になる条件)

投稿記事by メルサイア » 2016年11月21日(月) 11:24

質問ありがとうございます。

>「戦闘をすればするほど容量が爆増する」と言う理解で宜しいでしょうか。
>その場合、「1度戦闘した後のセーブデータ」と、「その後さらに一度戦闘した後のセーブデータ」を比較して見るべきかと。
おっしゃるとおりですね。
今まで用意できず、申し訳なかったです。

作成中のゲームで、アクター数の最大数を50個にして、以下を試してみました。
・戦闘0回でセーブ ①。    12KB。圧縮前JSON: 32KB (初期状態)
・戦闘1回(敵A)でセーブ② 。 30KB。圧縮前JSON: 113KB (かなり増加)
・戦闘2回(敵B)でセーブ③。 30KB。圧縮前JSON: 113KB (変化なし)
・戦闘3回(敵B)でセーブ④。 30KB。圧縮前JSON: 113KB (変化なし)
・戦闘4回(敵C)でセーブ⑤。 41KB。圧縮前JSON: 155KB (少し増加)
・戦闘5回(敵B)でセーブ⑥。 30KB。圧縮前JSON: 113KB (減った! →おそらく、敵Cのリトライ情報が敵Bに更新された)
・戦闘6回(敵C)でセーブ⑦。 41KB。圧縮前JSON: 155KB (前回の敵Cと同じ容量)

セーブ①~⑦の生データを以下に置きます。
https://www.dropbox.com/s/lyu5z989kzmbt ... 6.zip?dl=1

また、pluginフォルダ内を「makeSaveContents」で全文検索したところ、以下のプラグインが引っかかりました。
・RTK1_Core.js : セーブデータを圧縮前にJSON化して保存する機能を持つプラグイン
・CrossSave.js  : クロスセーブを実現するプラグイン (今回の検証ではネットワークセーブを利用していないので除外)
・RetryBattle.js : 戦闘リトライ情報を保存し、いつでも再挑戦を可能にするプラグイン

以上のことから推測するに、
・戦闘1回目によるセーブデータ容量の増加は、アクター数の最大数によるもの
 → 仲間にしていないアクターの情報もセーブデータには記載される (空のアクターも含む)
 → 仲間にしていないアクターのHP・MP・TPなどの更新を、
   どこかのスクリプトかプラグイン、もしくはコモンイベントでやっていると、更に肥大化する可能性がある?

・戦闘回数による容量の変動は、最初の一回限り?
 → リトライ情報を保存するプラグイン RetryBattle.js によるものもある?(ON/OFFどちらにしても容量変化はアリ)
 → 最後に闘った敵キャラの情報に更新されるので、回数を重ねても蓄積はされない

と考えられます。


その他のコメントも、大変参考になります。

>逆に、大幅な容量増加が初期の一戦闘後のみならば、仰るとおり空っぽのGameActorを一通り製造しているせいである
>可能性が高いです。その場合Actor最大数を減らすしかないかと。
>(現在「1戦闘後のセーブデータ」を観察する限りでは、空のActor関係が理由である可能性が高いです。データの約1/2)
おっしゃるとおりですね…。
アクター数の最大数は、使うだけにしておこうと思います。

>他に多少なりとも可能性があるのは各MAPのEvent辺りでしょうか。デフォルトのセーブデータの仕様を私は存じていないのでどういう感じかは知りませんが、
>イベントの現在出現状況、移動速度までセーブデータに詰込まれているのは少し違和感があります…
>(データの約1/4)
どこでもセーブ可能にするために、イベント部分もかなりの情報をセーブデータに含めないといけないのかもです。
例えば、
イベント中に変更があった、「イベントの消去」実行前か実行後か、イベントの移動速度、主人公の移動速度なども、
セーブデータに入れておかないと、途中でセーブ→ロードしたら、予期しない状況になってしまうのかもしれないですね。
難しいところです。

その他、何かわかりましたら、適時報告いたします。
最後に編集したユーザー メルサイア on 2016年11月21日(月) 13:15 [ 編集 2 回目 ]
メルサイア
記事: 127
登録日時: 2016年2月22日(月) 10:35
お住まい: 大阪府
連絡を取る:

Re: いつの間にかセーブデータが肥大化する問題について(「Save data too big!」になる条件)

投稿記事by メルサイア » 2016年11月21日(月) 12:04

気づいた点があったので、ご報告です。

以前の検証で、
>・戦闘0回でセーブ ①。    12KB。圧縮前JSON: 32KB (初期状態)
>・戦闘1回(敵A)でセーブ② 。 30KB。圧縮前JSON: 113KB (かなり増加)

ですが、もしかすると、ここで新しいマップに移動しているので、
この増加はアクターの最大数ものだけでなく、
新しいマップへの移動による影響もあるのかもしれません。
(セーブデータ①と②をWinMergeで見比べていて、マップイベント関連のデータの追加が多いことで、気づきました)

現在マップがどこであれ、全て(?)のマップの変更情報を格納しないといけないのだとしたら、たしかに厳しいですね。
作り方によるのかもしれませんが、イベントの位置や移動速度などを変えている場合が、容量を圧迫するのでしょうか……。
もうしばらく調査を続けてみます。
メルサイア
記事: 127
登録日時: 2016年2月22日(月) 10:35
お住まい: 大阪府
連絡を取る:

Re: いつの間にかセーブデータが肥大化する問題について(「Save data too big!」になる条件)

投稿記事by メルサイア » 2016年11月21日(月) 12:38

・・・申し訳ありません。調査不足でした。
アクター数を50個にした場合、容量が増えるトリガーは、戦闘ではなく、マップ移動のようです。

>以前の検証で、
>>・戦闘0回でセーブ ①。    12KB。圧縮前JSON: 32KB (初期状態)
>>・戦闘1回(敵A)でセーブ② 。 30KB。圧縮前JSON: 113KB (かなり増加)

で、セーブ①と②の間に新しいマップ移動を挟んでいたので、マップ移動だけで検証しました。
すると、
・戦闘0回でセーブ ⑨。       12KB。圧縮前JSON: 32KB (①と全く同じ初期状態)
・戦闘0回(マップ移動)でセーブ⑩ 。 33KB。圧縮前JSON: 111KB (かなり増加)
となり、マップ移動時に②と同程度の増加を確認しました。
2e4b4cf4dfcde4e69b7db1d6ea675f27.png
上記のセーブデータ⑨と⑩を以下に置きます。
https://www.dropbox.com/s/hy4d0akzoaccl ... 6.zip?dl=1

中身をWinMergeで比較すると、マップ移動時に、なぜか
仲間にしていないアクターのデータや、マップイベント情報(位置情報、移動速度など)が追記されていました。
アクターの最大数や、マップイベント情報が、セーブデータ肥大化の主な要因であることには変わりないようです。

更に詳しく調査するには、リアルタイムで圧縮前JSONのデータの長さを調べて、変化があった時にデバッグ出力したり、
マップイベントの変更情報に関係ありそうなイベントを削除したりして、比較してみるといいかもしれませんが、
かなり骨の折れる作業なので……、ちょっとどういう風にしようか、検討中です。

もし何かアイディアなどありましたら、いただけると幸いです。
アバター
トリアコンタン
記事: 2311
登録日時: 2015年11月10日(火) 21:13
お住まい: きのこ王国
連絡を取る:

Re: いつの間にかセーブデータが肥大化する問題について(「Save data too big!」になる条件)

投稿記事by トリアコンタン » 2016年11月21日(月) 22:19

こんにちは。
アクター情報が肥大化の主な原因と言うことで、実験的なプラグインを作成してみました。

「セーブデータ軽量化プラグイン」
アクター情報を保持することによって肥大化したセーブデータの容量を削減します。
セーブ実行時に、アクター情報の中から「今まで一度もパーティに加わっていない」
アクターの情報を削除することでセーブデータの容量を減らします。

基本的にパーティに加わったことのないアクター情報はセーブデータに含める必要がないとの判断で
試験的に作成してましたが、当然のことながら利用するプラグインによっては問題が発生する可能性があります。
利用する場合は、注意してご利用ください。

なお、データベースのアクター情報を消すわけではないのでアクター名称の取得などは普通にできます。

・ダウンロード
https://raw.githubusercontent.com/triacontane/RPGMakerMV/master/LightSaveData.js

・利用規約
当プラグインはMITライセンスのもとで公開されています。作者に無断で改変、再配布が可能で、利用形態(商用、18禁利用等)についても制限はありません。このプラグインはもうあなたのものです。

画像
画像
画像
画像
画像
画像

・これまでに制作したプラグイン一覧
https://docs.google.com/spreadsheets/d/1BnTyJr3Z1WoW4FMKtvKaICl4SQ5ehL5RxTDSV81oVQc/edit#gid=30581402
プラグイン関連のトラブルが発生した際の切り分けと報告の方法です。
http://qiita.com/triacontane/items/2e227e5b5ce9503a2c30

[Blog] : http://triacontane.blogspot.jp/
[Twitter]: https://twitter.com/triacontane/
[GitHub] : https://github.com/triacontane/
アバター
剣崎 宗二
記事: 686
登録日時: 2016年11月12日(土) 20:36
連絡を取る:

Re: いつの間にかセーブデータが肥大化する問題について(「Save data too big!」になる条件)

投稿記事by 剣崎 宗二 » 2016年11月21日(月) 22:36

すでにトリアコンタン様がプラグインを作成してくれているとの事でそれで解決できるかも知れませんが、とりあえず理由に繋がりそうな調査ポイントを提示しておきます。

actorsブロックのデータは$gameActorsをそのままセーブしているので、$gameActorsへの追加を行うプラグインの有無をご確認ください。
特に$gameActors.actor()を大量のIDに対して呼んでいる所がないかご確認ください。
----
-出先に居る場合回答が未テスト状態である事が多い為、テストは重々にお願いいたします。
-基本自分や友人の問題解決は自分で1からプラグインを書いているので、「こういうプラグインはありますか」に対しては助けになれません。ご了承ください。
メルサイア
記事: 127
登録日時: 2016年2月22日(月) 10:35
お住まい: 大阪府
連絡を取る:

Re: いつの間にかセーブデータが肥大化する問題について(「Save data too big!」になる条件)

投稿記事by メルサイア » 2016年11月21日(月) 23:03

トリアコンタンさん、起死回生の一手を、ありがとうございます!

す、素晴らしいプラグインです! 早速導入させていただきました!
これでアクターの最大数に縛られずに済むのですね……。
しかもアクター名はきちんと取得できるとは……感激です><。。

参考までに、LightSaveData.jsプラグインON時、
ゲーム開始直後にオートセーブしたセーブデータ⑳と、それからマップ移動しただけのセーブ⑲を比較しました。
5531d1364643b405e986309b7c790d33.png
⑳→⑲(圧縮前: 60KB→69KB、 圧縮後: 21KB→20KB)
ほとんど増えていません。といより、圧縮後は1KB減ってます。
…ほんとにびっくりです。
デバッグ出力にも、消されるアクターの配列を書いていただいていたので、非常にわかりやすく、助かりました。

一つお願いなのですが、「特定のアクターIDのデータを削除しないようにする」配列パラメータを追加することは可能でしょうか?
例えば、仲間に入れていないアクター名を、プレイヤー入力用テキストとして使用している場合(例: 村の名前など)、
そのアクターのデータが消えてしまうと、ユーザが名前をつけたものが初期化されてしまいます。
ですので、ツクラーさんが別途、消したくないアクターIDをパラメータで指定できるようにしておけば、
初期化を事前に回避できると思います。

【セーブデータに含まれるマップ関連データの仕様について】 (これはプラグインとは別の話です)
なお、WinMergeで文字列比較して気付いたのですが、
イベント途中にセーブファイルを開いてセーブしたり、オートセーブプラグインでセーブした場合、
その直前や直後のイベントのJSONが、そのままセーブデータにコピーされるようです。
参考までに、ゲーム開始直後にオートセーブしたセーブデータ⑳(左)と、マップ移動しただけのセーブデータ⑲の比較結果を画像にします。
d276ec9a90ff88e348ab983278972287.png

このことから、セーブデータを少なくするには、
オートセーブは長いイベントの後には行わず、
マップチップに触れた時などの単発のイベントにしたほうがいいのかもしれません。

とにかく、特にアクター数が多い長編物を作っているツクラーさんにとっては、
セーブデータの肥大化は深刻なので、本当に助かるプラグインです。
機会を見つけて、このプラグインの恩恵をもっと広めたいと思います。
最後に編集したユーザー メルサイア on 2016年12月24日(土) 10:24 [ 編集 4 回目 ]
メルサイア
記事: 127
登録日時: 2016年2月22日(月) 10:35
お住まい: 大阪府
連絡を取る:

Re: いつの間にかセーブデータが肥大化する問題について(「Save data too big!」になる条件)

投稿記事by メルサイア » 2016年11月21日(月) 23:17

>剣崎 宗二さん
調査ポイントをわかりやすく整理してくださり、ありがとうございます!

>actorsブロックのデータは$gameActorsをそのままセーブしているので、$gameActorsへの追加を行うプラグインの有無をご確認ください。
これの記述は個々のプラグインによって実装方法が異なりそうなので、検索は難しそうです。
しかし、重要な視点だと思います。

>特に$gameActors.actor()を大量のIDに対して呼んでいる所がないかご確認ください。
プロジェクトファイルのフォルダをキーワード
「$gameActors.actor(i」や
「$gameActors.actor(($gameVariables.value(」で検索すると
変数idやi、ゲーム内変数を使ったスクリプトが検出できたので、
これでループ処理やfor文・while文を回している箇所がないか、特定して調べてみます。

“MV:質問” へ戻る