【こぼれ話】完全偶発バグの話
『天翔のマーキナリエ』開発時に悩まされたひとつのバグ。
普通バグはある条件と条件が重なって症状が現れるもので、敵の行動に依存したりなどランダム性はあっても条件が合えば必ず起こる=再現性があるというのがほとんど。
しかしこのとき遭遇したのはシステム依存の完全偶発バグでした。
本作UIのひとつ、右上のボタンガイド表示。
ツクラー諸兄ならご存知のDTextPictureプラグインを使って実装してますが、中身の文字列の長さはキーコンフィグやキーボードorゲームパッドによって可変で、さらにこれが右寄せであると。
イベントコマンド「ピクチャの表示」および「ピクチャの移動」においてピクチャの表示基準点は「左上」か「中央」のいずれかしか選べません。横幅が不定のピクチャを右寄せにするなら、表示位置のX座標は基準点「左上」を選択し、値は
画面横幅-ピクチャの横幅
を指定するのが正攻法。
ピクチャの座標の値には変数が使えるので上記式を用いてあらかじめ計算。
ピクチャの横幅は画面に表示されたものならスクリプトで取得できるので、処理順としては以下のようになります。
- DTextPictureで文字列を予約
- 「ピクチャの表示」で文字列を不透明度0で適当な位置に表示
- スクリプトで文字列ピクチャの横幅を取得
- 画面横幅-文字列ピクチャの横幅を計算して変数に代入
- 「ピクチャの移動」でX座標を変数で指定、不透明度を上げて可視化
これでいけると思ったんです。というかいけたんです。
でも失敗するときもあるんです。
…どういうこと?
この処理が行われるタイミングは、セーブデータロード時であったりメニュー閉じた時であったりマップ移動時であったり何箇所かあります。
でもいずれでも成功したり失敗したりするんです。
ダメな時はエラーメッセージを吐いて落ちるので、まあスクリプト絡みなんだろうとは推測できます。でも発生条件がさっぱりで再現性が捉えられない。また下手にうまく表示できることもあるものだからどうやら実装方法自体は間違ってないのがかえって始末が悪いという。
やはり右寄せは無理なのか…と半ば諦めも入りつつしばらく途方に暮れていましたが、ここでエラーメッセージの「無いものを参照している」ことを示す内容が引っかかります。
つまり文字列ピクチャの横幅取得をしくじっている。すなわちピクチャが表示できていないんじゃないかと。
結果的にこの推測は合ってました。透明な文字列ピクチャの表示から横幅取得の間にウェイトを挟むと成功率が上がりました。
なんだい確率でおこる落ちバグって…
そうしてなんやかんやありつつ、最終的には指定IDのピクチャに中身が入るまでは処理をループするという方法で確実に参照できるようになり機能実装は無事に完了と相成りました。
結局エラーは文字列ピクチャのレンダーが処理落ちなどで間に合わず参照が先行してしまった場合に起きていたということだったようで、今考えると恐らくこれはMV特有のフレームスキップ・カクつきも要因のひとつだったのではないかと。
その時処理落ちするかしないかは動作環境とその瞬間の挙動次第なのでこのケースは本当に偶発的だったと言っても良いと思っています。今後はあまりこういう目には遭いたくないもんです。
それにしても左寄せと右寄せで実装難度の差がありすぎてどうなのこれ。