毒バグ解析 (GB版SaGa2秘宝伝説)
毒バグとは
毒ダメージで気絶した時、敵を倒した時に表示されるメッセージがおかしくなる。
例えば毒で倒れたときのメッセージは以下のようになる。
○○○ はどくで ××ダメージ
△△△ はたおれた
本来、「△△△」には実際に倒れたキャラ名「○○○」が入るべきであるが、
なぜか、「そのターンの最後に行動したキャラのターゲット」の名前が入る。
敵全体攻撃や味方全体回復の場合は最後にダメージを受けたり、回復したキャラの名前が入る。
これが広義の毒バグである。これだけなら毒殺名前バグといってもいいかもしれない。
しかし、最後の行動がターゲットを必要としない場合、おかしなことが起こる場合がある。
具体的には以下の場合で起こる事を確認している。
・各種防御(「みをまもっている」と表示されるもの)
・各種カウンター(「こうげきをまちかまえている」と表示されるもの)
・女神の心臓
・なにもしない(ただし、そのときの状況に依存する)
「おかしなこと」の例としては、グラフィック変化、いきなりボス戦に突入したり、サブキャラが消失したり、
アイテムが能力に変化したりとさまざまであり、主に「そのターンの最初の行動者の所属するグループのメンバー数」に依存する。
これが一般に言う(狭義の)毒バグである。防御毒殺バグというとわかりやすい。
毒バグの原理
以下は各種解析情報を元にした推測した原理であり、必ずしも正しいという保障はない。
戦闘時は敵味方のグループにそれぞれ番号を振っており、行動者や対象者は番号で管理されている。
そして、戦闘時メッセージ表示の際、行動者の番号と、対象者の番号を元に名前を表示している。
また、対象が全体の場合などは特別な番号で管理されており、行動時に各対象の番号に読み替える。
しかし、毒ダメージの場合、行動者はダメージを受けるキャラとみなされるが、対象者が未定義で、
前の行動者(毒ダメージはターン終わりなので必然的に最終行動者)の対象データがそのまま残った状態になっている。
そして、HPが0になったときのメッセージ「△△△ はたおれた」においては対象者の名前を表示するので、
最終行動の対象の名前が表示されることになる。
また、最終行動が対象不要の行動の場合は、特定のキャラの番号ではない番号をキャラの番号とみなし、
それに応じた番号の位置にあるデータ(最大8バイト=8文字分)を、名前としてメッセージ処理をしようとしてしまう。
ところで、メッセージデータに存在するのは文字データだけではない。
テキストデータには改行コード、html文書にはタグが存在するように、
メッセージやイベント処理のためのコードが存在する。
(むしろ、イベント処理の一環としてメッセージが入っていると考えてよい)
もし、名前にイベント処理用のコードが含まれているとそれに対応する処理を行ってしまうことになる。
戦闘中を想定していない処理コードも多数あり、それが呼び出された場合、フリーズ等の壊滅的な現象が起きることがある。
防御毒殺時に読み込んでしまうデータは、行動順を制御するデータである。
そこには、行動済みの行動者の数、最初の行動者のグループ内番号とグループ番号、
2番目の行動者のグループ内番号とグループ番号…、といったようにデータが並んでいる。
行動順にはすでに倒した敵や気絶した味方も含まれているが、そのターン中に増殖した分は含まれない。
ターン終了時点では行動済みの行動者の数は出現時の敵味方の総数+前ターンまでの増殖した数となる。
このため、まず、敵味方の総数に相当するコードが実行されることになる。
また、処理コードには続くデータを引数とみなす処理があり、最初の行動者のグループ内番号やグループ番号が処理に影響することがある。
行動は同一グループ内での行動順はグループ内番号が大きいもの(一番奥)から順番なので、
最初の行動者の番号は、 [そのグループのメンバー数]-1 になる。
ただし、最終行動が「なにもしなかった」の場合は、そのキャラがその戦闘中に最後に選択した対象になる。
その対象が全体攻撃の場合は
戦闘開始時から何もしていない場合は、何が起きるかは戦闘場所に依存すると考えられる。
これは対象設定データが戦闘開始時にリセットされないが、戦闘終了時にはマップ情報に依存して変化すると考えられるため。
防御毒殺バグでおきること
先に述べた原因により、主に総数(=味方の数+出現時の敵数+前ターンまでに増殖で増えた数)で決まる。
また、グループ内番号は0から8、グループ番号は0から7までの値しか取れないので、
後で紹介する「名前変化」よりも限られた現象しか起こせない。
文字表示位置が変化したり、何かのグラフィックが表示されるものがほとんどだが、
特に目立った効果のあるものを紹介する。
・戦闘突入(総数9)
戦闘中にもかかわらず戦闘が起こる
ターン最初の行動者のグループのメンバー数(=グループ内番号+1)よって以下のように決まる。
1 ぼうえいシステム
2 アポロンのしもべ
3 オーディン
4 ビーナス
5 しょうぐん
6以上は原理的に不可能。
戦闘はバグを起こした戦闘の開始状態で始まる。
勝利した場合はフィールド画面で「○○○は たおれた」等の表示が出た後に操作不能でフリーズすることが多い。
・上位ビット変化(総数16)
毒バグ最大の現象。単に毒バグといった場合、この現象を指すことが多い。
本来は会話イベント終了時に、マップ上のキャラの位置をリセットする処理らしい。
戦闘用の各種データの最上位のビット(128に相当)が0になる(X=X&0x7F)。
ただし、逆の変化(最上位ビットが1になる変化)も起こるデータ位置もある。
どこのデータが逆の変化するかはマップとその状態に依存すると思われる。
名前変化、HPの減少、気絶解消、能力系装備がアイテム系装備に変化、空欄がしちしとうに変化、
使用回数が無限から有限(126)に変化、種族変化などが起こる。
現在HPとアイテム系の変化は戦闘終了後も残る。
種族変化は食肉時に影響が出る。
また、名前の変化によって、名前がイベント処理コードに変わり、更なる現象が起こる場合がある。
多くの場合はフリーズを伴う危険な状況になることが多いが、
うまく名前を設定することで純粋な毒バグよりさらに幅広い現象が起こせる。
これは後の「名前変化」で紹介する。
・イベントパラメータ変化(総数18から20)
イベント進行などに使われる変数が変化する。
総数18で+1(最大15)
総数19で−1(最小0)
総数20ではターン最初の行動者のグループ番号の値に変わる。
どのパラメータが変わるかは最初の行動者の属するグループのメンバー数によって決まる。
メンバー数1ならサブキャラの仲間状態が変化する。(0にするといなくなる)
あとはメンバー数2で最初の世界、3で砂漠の世界……9でビーナスの世界とレースといったように対応する。
他にも総数25でBGM変化や場所移動が起こせると予想される。
名前変化
上位ビット変化で名前が処理コードに変化た場合、その名前が表示される際にその処理が実行される。
この時起こる現象のうち、比較的有用なものをまとめた。
・戦闘突入
「9○」という名前から変化させる。
出現する敵は○に入れる文字によって変わる。
防御毒殺バグの総数9に相当するが、より多様な敵と戦える。
・イベントパラメータ変化
「け○」、「こ○」、「さ○×」という名前から変化させる。
どのパラメータが変化するかは○の位置の文字に依存する。
「け○」では+1、「こ○」では−1、「さ○×」では×の文字に依存する値になる。
防御毒殺バグでの総数18から20に相当するが、テレポート箇所や中央神殿の状態なども変えられる。
・アイテム入手
「た9○」、「たい○」から変化させる。
入手できるアイテムは○の位置の文字に依存する。
○の位置が逆変化を起こしている場合はモンスター能力を手に入れることができる。
前者は宝箱、後者はイベント入手に相当すると思われる。(アイテム欄の空きが無いときの処理が異なる)
入手メッセージの代わりに、コマンド入力時は前ターンの最後のメッセージが表示される。
持ち物がいっぱいだと「たい○」ではメッセージがとまらなくなってしまう。
また、戦闘中メッセージとして呼び出された場合は大抵フリーズしてしまう。
・秘宝入手
「たあ○」から変化させる。
入手できる秘宝は○の位置の文字に依存する。
アイテム同様、メッセージが表示される。
また、「たドそ」とした場合にはすべての秘宝が手に入る。(メッセージなし)
ただし、「ド」の位置が逆変化である必要がある。
・場所移動
「た5○」、「た6○」という名前から変化させる。
ただし、多くの場合、移動後にデータが大きく変化するため、操作不能に陥る。
・ドラゴン騎乗
「たド8」、「たド9」、「たドあ」、「たドい」から変化させる。
ただし、「ド」の位置が逆変化である必要がある。
後に挙げたものほど遅いドラゴンになる。
・並び替え
「サ」から変化させる。
並び順が冒険開始時のものに戻る。
ただし、戦闘中の並び順はそのままだが、戦闘終了時点の状態が並び順どおりに反映されるので、
結果的に現在HPや装備品が入れ替わってしまう。
能力値は変化しないが、能力がアップする装備品を入れ替えることで上げ下げできる。
能力値255のキャラの作成はこの方法を使うのが手っ取り早い。
・THE END
「ツ」から変化させる。
THE ENDの表示後はタイトルに戻る。