アコニック・ランド:メモ:ツクール関連

ツクール関連

ツクールMVのプラグインを触る機会がありまして、
そこで特に要注意点に思った事をまとめてます。
(ツクールXP等の追加スクリプトについても同様かもしれません)

セーブ引継ぎエラー
上書きだけが競合じゃない!
セーブデータの不必要な肥大
MBS_FPLEのメモリ系不具合
関数の細分化
ツクール2003で落ちる不具合
名前被り回避


セーブ引継ぎエラー

新しいプラグインを有効にしただけで、それ以前のセーブデータをロードしようとした際に
エラーが発生してしまう事例が多数見られます。
初期化されていない無効なデータをロードし、それを参照してしまっているためです。

対策は簡単。
DataManager.extractSaveContents
に対してエイリアスして再定義するアレを行い、そこで該当するデータが無効か否かを判定し、
無効ならば適切な初期化を行うだけです。

他に似た問題で、とあるプラグインが有効になってる状態でセーブしたデータを、
プラグインを無効にした状態でロードしセーブ、再び有効にしてロードすると、
ロードしたオブジェクトのメンバ関数が存在しない事になっているという感じのエラーが
起こる場合があります。
セーブに保存するデータを作成する場合は、これにも留意した方が良さそうです。

2019.10.2-12.8


上書きだけが競合じゃない!

コアスクリプトで明示的に定義されてないメンバ関数を使う事による
一種の競合がしばしば見られます。
例えば、Game_BattlerBaseにはdieというメンバが定義されていますが、
その派生のGame_Battlerでは定義されていません。
ここで、Game_Battlerのdieをエイリアスするアレの形で再定義し、
元のGame_Battlerのdieを呼び出す形にすると、今後dieを呼び出そうとした際に、
エイリアスを作った時点でのGame_BattlerBaseのdieが呼び出されるようになってしまいます。
つまり、その後にGame_BattlerBaseのdieに対して他のプラグインが追加した処理が
無視されてしまいます。

ただ対処は簡単で、呼び出されている未定義の派生クラスのメンバを事前に定義しておき、
そこから基底クラスのメンバを呼び出してやればOKです。
この例の場合は、Game_Battelrのdieも定義して、そこからGame_BattlerBaseのdieを
呼び出しておけば、最新のGame_BattlerBaseのdieが呼び出されます。

注意点として、派生クラスのメンバは、未定義の状態でもundefinedにはなっておらず、
メンバ名だけでは偽判定になりません。
定義されてるか否かの判断は「クラス名.hasOwnProperty("メンバ名")」とする事でできるようです。
未定義の派生関数はなるべく使わないようにし、使う必要がある場合は、
これを利用して「未定義なら初期版を定義する」とするのが妥当そうです。

2019.11.24-26


セーブデータの不必要な肥大

Game〜で始まるクラスの内容(Game_Temp以外)は、どうもメンバ変数の参照先が丸々保存されているようです。
画像オブジェクトを参照するメンバを作ってエラーが出て気付いたのですが、
ここではアイテムやスキルなどのデータを直に参照するメンバは作らない方が良さそうです。
参照にはIDを利用するようにしたり、保存する必要のない情報は別の方法で扱った方が無難そうです。
また、メンバ関数で間接的に参照するのなら問題無いようで、コアスクリプトにおいてもそういう方法が用いられています。

2019.11.30-2020.6.18


MBS_FPLEのメモリ系不具合

3Dダンジョンを作成する際に便利なプラグイン「MBS_FPLE」(配布元はこちら)ですが、
2018/12/27の版においては「長時間ゲームをプレイしてると重くなったり落ちたりする」という問題があります。
特に、マップ切り替えの機会が多く、なおかつ数多くの種類のキャラが出現するマップがある作品との相性が悪いようです。

原因は、マップチェンジ、戦闘、メニューから復帰などの際に、BABYLON.Sceneを解放する事なく際限なく取得している事と、
addLoadListener周りの問題により、spriteManagerが余分に作成される場合がある事の相乗効果にあるようです。
これらの問題を解消したプラグインをこちらにアップしましたので、
上記のような不具合に悩まされてられる場合は、よろしければご利用ください。
(ブラウザで見ると文字化けしてるかもしれませんが、ダウンロードすると正常になってると思います)
(本当は不具合の報告を伝えた方が良いとは思うのですが、英語がわからない…)
(改造再配布については、大御所のかたもされてるので大丈夫かなと思うのですが、怒られたら消す予定です)

他にも、以下の機能なども追加してます。
・ブロック表面のテクスチャのアニメーション機能
・ブロックの半透明化機能
・ブロックの内側面を表示する機能
・ブロックの全ての面を別グラフィックにする機能
・ブロックの形を少し変更(面を傾けたり薄くしたりピラミッド型にしたり)する機能
・ブロックのグラフィックを変数で切り替える機能
・天井の上と床の下にもブロックを設置する機能
・段差を設ける機能
・遠景・タイルセット変更への対応
・デフォルトの天候の効果を表示する機能(場合によっては別プラグインの改造が必要。ヘルプを参照。なお、MOG_Weather_EX.jsを導入する用の追加プラグインはこちらになります)
・キャラのページ変更や動的生成による画像の変化・出現への対応
・キャラのジャンプ、透明度変更の反映
・乗り物の表示に対応
・CharacterLight時の、キャラが距離によって暗くなる効果を自然にする機能
・キャラのスプライト画像の幅・高さ変更機能
・カメラの高度・仰角を変更する機能
(※エフェクトアニメーションには未対応のままです)

2019.12.7-2020.10.27


関数の細分化

一人でプログラムを作ってる時はあまり気にならないのですが、
プラグインの場合は、各プラグインの作者さん達との一種の共同作業で、
こういう場合、関数は細分化されてた方が有難く感じます。

「同名の関数を新しく定義し、そこから元の関数を呼び出す事で、
元の関数に機能を追加して行く」という手法が、
ツクールXP等でもよく用いられていますが、この時に機能を追加できるのは、
元の関数の処理の前か後だけです。
例えば、元の関数で処理Aと処理Bがなされてて、その間に新しい処理を設ける
必要がある場合、関数を上書きする以外にはなくなって来ます。

プラグインを直接いじれば早いのですが、元のプラグインに欠陥が発覚したり、
機能が強化されたりなどして更新する必要があった際に、
修正もその都度行わなくてはならなくなりますので、なるべくなら避けたい所です。

ここで、処理Aと処理Bがそれぞれ別の関数として定義されていれば、
処理Aの後か処理Bの前に処理を追加する処理を設ける事で解決します。
何かまとまった処理や、部分的に拡張のしようがある処理などは、
関数として分けておいた方が良さそうです。

関数に新しく機能を追加する際も、「追加する機能をまるごと関数化して、
その関数の呼び出しのみを追加する」という形にするのが理想的かもしれません。
面倒臭いですが(笑)。

2019.11.24


ツクール2003で落ちる不具合

ツクール2003辺りでは、長時間ぶっ続けでプレイをしてるとセーブ時などに落ちる不具合があります。
しかも、セーブしようとしたデータが飛んでしまうので、
一つのセーブ枠をずっと使ってた場合は悲劇となります。
兆候として「BGMが鳴らなくなる」という現象が起こりますので、
これが起こったら違うセーブ枠にセーブするようにします。
これはツクールの不具合なので、クリエイターに報告しても仕方がありません。
こういう現象が存在する事が、少しでも広く知られればと思います。

2019.12.23


名前被り回避

プラグインのパラメータの名前は、異なるプラグイン同士で被っても問題がありませんが、
以下については、他のプラグインと被るとまずいので、それなりに特徴を持たせた方が良いと思います。

●プラグインのファイル名
●プラグインコマンドの名前
●メモ欄のタグの名前
●制御文字の名前
●グローバル変数あるいは関数、およびそのメンバの名前

プラグインのファイル名については、先頭に作者の名前を3文字に略したようなものを、
アンダースコアを挟んで付けておく例をよく見ますが、それが案外良いと思います。

プラグインのファイル名以外については、プラグインパラメータによって変更できるようにするのが良さそうです。

2020.1.2-9.24


ゲームシステム関連の考察とか
プログラミング(VC++)メモ
メモに戻る
自作プラグイン置き場(niftyスペースへ飛びます)
トップに戻る