2024年5月29日水曜日

【ウディタ】亡霊セクション

こわいバグにはいくつか種類があって
・再現性のないバグ
・いつの間にか直っているバグ
・原因が絞れないバグ
等があると思いますが、今回はなかなか不可解なバグに遭遇してしまったので記事を書いてます。
(執筆時点では直ってます)

なにがあったのかを話す前に環境を話しておきましょう。
ウディタ本体Ver3.302、テキスト編集はVSCode
OSはwin11 home
テキスト表示、マップのEv配置データ、マップ移動イベント等をすべてテキスト管理しています。

バグの舞台となったコモンは、約7年手を入れながら使っている古代兵器、「テキスト表示コモン」。自作です。

今まで通っていなかったルートの通しテスト中、とある場面で「イベントテキストを表示した後マップ移動イベントを呼ぶ」イベントを起動したところ、マップ移動イベントを呼んでマップ移動の暗転が表示されたところで操作不能に陥る不具合に遭遇。

ははあ、もしや呼び出すテキストの指定を間違えたな?
まれによく呼び出すテキスト指定を間違えて変なことになるので、確認してみるとこれは違う。
テキスト本体に異常があることはあまりないですが、一応見てみるとやはり変わったところはなく……。

こうなるとたぶんコモンにバグがあるのだろう、となると思いますが、「イベントテキストを表示した後マップ移動イベントを呼ぶ」なんて動作、ここまでアホほどやっていて、あきれるくらい通過してきたのにバグは一切起きず、ここにきて初めて起きるというのは謎です。

とりあえずデバッグ文を差し込みまくって調査をしていくと
テキストでマップ移動処理を呼んだ直後に謎のコマンドが追加で発生しているようです。デバッグウィンドウ上では完全に「無」。無のコマンドをコモンが読もうとしています。

ただ、これ自体は実は同じ事象が他のイベントでも起きています。
ごくまれに何も文章が表示されないウィンドウが表れる不具合が起きており、おそらくはこれと同じことが起こっています。場所移動ではなく普通のテキストのみですが……。
既知の不具合リストに入れていましたが「キー入力を受け付けるので、気にはなるが進行には支障ないバグ」として後回しになっていました。
ただ今回は暗転したまま操作不能になる重度のバグなので、直さないと先に進めません。

個々は使い古された「枯れた処理」ですが、組み合わせの問題でバグが起きていそうです。こういうバグはかなりやっかいで、下手すると1週間以上消えます。

今回はあんまり時間がないので時間を浪費するのを嫌って、対症療法的な処理を追加することに決定。
「無のコマンドが出るなら無のコマンドが来た場合飛ばすようにすればいいじゃない」
ということで、「無」「改行」「半角スペース」「全角スペース」を文字列分岐に仕込んで判定させたところ、全て不一致。
「無が無と同じならいけるんちゃうんか????」
と頭を抱えながらその日は寝ました。

翌日。
バグを駆逐する心意気で臨んだ2日目の作戦は
「全テキスト中に存在するキャラ名をリスト化して、そこに含まれない名前はすべて飛ばせばいいじゃない」(要はホワイトリスト方式)
全テキスト中に存在するキャラ名をリスト化するコモンと、現在表示しようとしているキャラ名がリストに存在するか判定するコモンを用意。
仕事から帰った後の疲れた頭で作ったので苦戦しましたが動作は完璧。いざ組み込んで動かしてみると、なぜかすべてテキストが飛ばされる。
変数条件は間違っていない、返り値も間違っていない、デバッグウィンドウには、見た目一致しているのになぜか不一致を告げるテキストが表示される始末。
疲れ果てたのでその日は寝ました。

翌日。
3日目の作戦は
「文字列が信用ならないから数値変数で攻める」
テキスト表示コモンですが、処理の流れとしては
指定されたテキストドキュメントの内容を文字列変数に代入し、これを1コマンドずつ分割してCDBへ書き込んで、これをテキスト表示コモンで読み込んで表示しています。
回りくどいですが、このへんの設計理由は忘れました。

なんにせよこのCDBに書き込む処理は最上流にいるので、文字列も(テキストドキュメントでおかしくなっていなければ)変ではないはず。
ここでは、CDBに1コマンドずつ書き込んでいく際に使う変数を使うことにしました。
現在読んでいるコマンドの位置もわかっているので、CDBに書き込んだ回数を上回れば不正なコマンドということになります。

実装前、ためしに現在のコマンド位置をデバッグウィンドウに出してみると、2コマンドしかないマップ移動イベントを呼んでいるのに3コマンド目の表示が……。
実装してみると今回は予定通りに動作して、暗転したまま操作不能になることもなく進行できました。
やはり謎の3コマンド目は出現していましたが、根本原因がわからないので、とりあえず置いておくことにします。

0 件のコメント:

コメントを投稿