既存のプロジェクト(セーブデータ)に$gameSystemを利用するプラグインを導入した場合のエラー

アリクイマン
記事: 44
登録日時: 2018年5月06日(日) 12:30

既存のプロジェクト(セーブデータ)に$gameSystemを利用するプラグインを導入した場合のエラー

投稿記事by アリクイマン » 2019年7月29日(月) 00:34

お世話になっております。

現在制作中の既存プロジェクトに、MOG_WeatherEXを導入しました。
新規ゲーム開始では、問題なく動作するのですが、
既存のセーブデータにてテストプレイを行おうとすると、
cannnot read property 'length'
のエラーが出てしまいます。

該当箇所はMOG_WeatherEX内377行目の$gameSystem._weatherEX_Data.lengthだと思うのですが、
MOG_WeatherEXに限らず、変数$gameSystemを使用するプラグインを、
既存セーブデータへ導入するためには、どのような処理を行えばよいでしょうか。

ひとまず、エラーが発生する該当行の直前に、

コード: 全て選択

  if($gameSystem._weatherEX_Data === void 0){
    Game_System.prototype.weatherEX_initialize(false);
  }

と書き加えることで、既存のセーブデータでの起動は可能になり、
一見正しく動作しているようには見えましたが、この対応が適切かどうかを教えていただきたいです。

よろしくお願いします。

アバター
ツミオ
記事: 83
登録日時: 2017年4月02日(日) 13:46
連絡を取る:

Re: 既存のプロジェクト(セーブデータ)に$gameSystemを利用するプラグインを導入した場合のエラー

投稿記事by ツミオ » 2019年7月29日(月) 09:44

こんにちは。
以下は単に僕の考えであり、ベストプラクティスかどうかはわからない、ということを念頭に置いて読んでいただければなと思います。
また、プログラミングの知識があることを前提に書いています。その点もご了承ください。


まず、ご提示された方法では問題が発生する場合があるかと思われます(ただしMOG_WeatherEXのコードは確認していないため、このプラグインで問題が発生するかどうかは未確認)。

ご提示の方法は
・$gameSystem._weatherEX_Dataの値が未定義ならば、初期化処理を再度やり直す
というものになるかと思います。

この方法が問題なのは「チェックしているのは$gameSystem._weatherEX_Dataなのに、別の値まで一緒に初期化されてしまう」という現象が発生するためです(最初にも述べた通り、この挙動がMOG_WeatherEXにおいて問題となるかどうか僕は知りません。たまたま他の値を初期化していないなら(あるいはしていても)うまく行くかもしれませんし、行かないかもしれません)。

上記が最も問題となる部分ですが、次に「$gameSystem._weatherEX_Dataが未定義であるかどうかを$gameSystem._weatherEX_Dataを使用するあらゆる箇所でチェックしなければならなくなる」という問題が発生します。
これは$gameSystem._weatherEX_Dataを使用する箇所が増えるたびにコードが汚れていくことを意味します。

そこで僕が好んで使用する方法の一つは
・getterを用意して、そこで初期化がなされているかどうかのチェックをおこなう
というものです。
これはGame_System(や他のセーブデータに保存するGame_XXX系のクラス)に対する処理として結構いい感じなのではないかなと思っています(他にもっといい案があれば教えて下さい)。

具体的には以下の通りとなります(length云々でエラーが発生しているということなので、配列として初期化しています。もし生成した配列に対する初期化処理が必要なら、ここでその処理を実行してください)。

コード: 全て選択

    Game_System.prototype.weatherExData = function() {
        return this._weatherEX_Data || [];
    };


あとは$gameSystem._weatherEX_Dataとして直接プロパティにアクセスしていた場所をgetterに置き換えます($gameSystem.weatherEX_Data())。
こうすると、実行時に初期化されているかどうかをチェックしてから$gameSystem._weatherEX_Dataを返すようになるため、エラーは発生しなくなるかと思われます。

なお当たり前ですが、未定義でも動作するような書き方をしていない限り、上記のgetter作成は_weatherEX_Dataだけではなく、全てのメンバに対しておこなう必要が出てきます。

以上となります。
なにか参考になりましたら幸いです。
【Twitter】https://twitter.com/TsumioNtGame/
【GitHub】https://github.com/Tsumio/rmmv-plugins

有償の依頼も募集中。
今まで有償で制作したものは実績をご覧ください。
アリクイマン
記事: 44
登録日時: 2018年5月06日(日) 12:30

Re: 既存のプロジェクト(セーブデータ)に$gameSystemを利用するプラグインを導入した場合のエラー

投稿記事by アリクイマン » 2019年7月29日(月) 20:39

ツミオさん

ありがとうございます。
初期化処理を参考に、配列に関する処理のみをゲッターとして作成し、
対応することにしました。
また、他のlengthを使用してforループを動かしている箇所も
同様に追記することにしました。

ありがとうございます。

“MV:質問” へ戻る