本記事は、2ちゃんねるのウルティマスレで話題になった本作品のバグと、その原理・対策について、一部の情報や図解を追加したうえでまとめたものです。
バグの解析をしてくださった有志の皆様に感謝致します。
※当時のスレッド
・【Lord】ウルティマ(Ultima) 11(X)【British】 >>971-982
・【Lord】ウルティマ(Ultima) Part12【British】 >>21-36
以下の条件で戦闘に勝利したとき、羊飼いの経験値がマイナス512されてしまうバグです。
このバグのせいで、3人以下のパーティーで進めていると、羊飼いのレベルが4から上がりません。
このバグの原因は、戦闘後にパーティーメンバーのステータスを更新する処理のプログラムミスです。
簡単に説明すると、パーティメンバーに空きがある状態で戦闘終了すると、間違って羊飼いの経験値を更新してしまうのです。
※以下はコンピューター内部の話になるので、興味が無い方は(4)まで読み飛ばしてください。
ゲームの内部では、色々な情報を「バイト(byte)」(0~255の数値)という単位で管理しています。
このうち、キャラクターの経験値は2バイト(バイト2つ分)、ステータスは1バイトで管理されています。
(ちなみに、2バイト使うと0~65,535の数値を管理できます)
この経験値を管理するバイトと、ステータスを管理するバイトのアドレス(内部の位置)は、下図のように連続しています。
さて、問題のステータス更新処理ですが、内部的には「経験値を管理するバイトの最後(アドレス:68C8)から数えて○番目を更新する」という処理になっています。
この68C8が羊飼いの経験値を管理するバイトのアドレスで、○は職業に対応する1~8のID(番号)になります。
例えば、ID=2の吟遊詩人の場合は、68C8 + 2 = 68CA のアドレスを更新します。
ここでパーティーの数が3人以下で空きがある場合、ID=0のメンバーのステータスを更新しようとします。
このID=0が問題で、68C8から0番目、すなわち68C8 + 0 = 68C8 のバイトを書き換えるため、羊飼いの経験値が不正に更新されてしまうのです。
バグの原理上、4人パーティーを組んでいる間は、このバグは絶対に発生しません。
また、経験値が減ってもレベルが下がることはないので、
4人パーティーで羊飼いのレベルを8まで上げた後なら、3人以下のパーティーにしても問題はありません。
羊飼い一人旅のようなやりこみプレイでもしない限り、この方法で実害なくプレイできます。
根本的な解決方法は、プログラムを書き直すことです。
実機(ロム)のプログラム自体を書き換えることはできませんが、
ロムに焼かれたプログラムイメージを特殊なツールを使ってデータ(ロムイメージ)として吸い出し、
その一部をBzなどのバイナリエディタで書き換えることで、プログラムミスを修正することが可能です。
書き換えたロムイメージをVirtuaNESなどのエミュレータを使って読み込めば、バグが修正されたゲームを遊ぶことができます。
以下に、データの修正箇所と修正内容を載せます。
※注意事項
・データの吸出しや変更は、ご自身の責任で実施をお願い致します。
・非合法に配布・コピーされたロムイメージを使って遊ぶのは著作権の侵害であり犯罪です。
本記事の目的はバグの存在と原理の紹介であり、違法行為を肯定や推奨するものではありません。
修正箇所(バイト位置) | 修正内容(値の変更) |
---|---|
26C1C | BC → A0 |
26C1D | 15 → 08 |
26C1E | 68 → EA |
26C27 | CA → 88 |
26C28 | 10 → D0 |
26C29 | F2 → F5 |
この修正は、戦闘後のステータス変更処理の対象を、「パーティーメンバー全員」から「主人公+仲間全員」に変更します。
そのため、存在しないメンバー(ID=0)の更新処理がなくなり、バグを完全に回避できるようになります。