見出し画像

#25 【懐ゲーム】ドラクエⅣのバグについてプログラマー視点で解説する

本日仕事中に盛り上がった話について書いていこうと思います。

新人にchar型変数1バイトのビットの管理を教えている最中、シフトし続けてオーバーフローしたらどうなるか?という話をしていたのですが、

そこで突如、ドラクエⅣで8回逃げたら会心の一撃連発になるバグ、あれってオーバーフローが原因だったらしいよ、という同僚の言葉。
ああ確かにそんなバグあった!!!って盛り上がるおじさん連中にキョトンとする新人くん。

まさかビット計算の話から、ドラクエ4に話が飛ぶとは思いませんでした(笑)

ドラクエⅣ
今までロト3部作のシリーズから一転。
のちに、天空シリーズと呼ばれる第一作目。

そのバグについて今更ながら解説。
ファミコン版のドラクエ4は、今考えると信じられませんが、512キロバイトのROM容量だったようです。
スマホで撮った写真1枚より小さいね。
そんなROMであったため、少しでも容量を抑えるための努力として、フラグをビットで管理していたようなのです。
高々数回のカウンターとしか使わない変数に、1バイトすら使うのがもったいないと。


ドラクエⅣの場合、通常の戦闘であれば4回目の逃げるを行うと確実に逃げられるようになるのですが、その際のフラグカウントとして、以下。

初期値 :0000 0000(2進数8ビットです)

逃げ1回:0000 0001
逃げ2回:0000 0010
逃げ3回:0000 0011
という管理になっていたようで、要は2ビットあれば0~3を表現できるため、3桁目~8桁目は別の情報として使っていたのですね。

ところが、ボス戦では当然何回逃げようが逃げられるわけがないので、逃げるカウンターがどんどん加算されていきます。
(これがバグですね)

逃げ4回:0000 0100
逃げ5回:0000 0101
逃げ6回:0000 0110
逃げ7回:0000 0111
逃げ8回:0000 1000
この逃げ8回の状態までカウントアップして書き込まれた領域。
これが、会心の一撃連発状態、になるフラグだったようです。
(通常であれば、パルプンテを使って「力がみなぎってきた」が発動したときに書かれる領域らしいです)
ここに「1」が設定されていると常に会心の一撃モード。
当時エスタークが倒せなかった小学生は、大変お世話になったバグですねw


また、ついでにもう一つ同じようなバグが。

838861

この数字に聞き覚えはありますでしょうか。


そう。
カジノコイン激安で買える裏ワザです。


ドラクエのカジノでは、1枚20ゴールドで買えるコインを使って、スロットマシンやらポーカーやらでコインを増やし、はぐれメタルシリーズの防具を手に入れることができました。

838,860枚のコインを買うために必要なお金は、約1,700万ゴールド
ですが、この数字に1を足した、838,861枚に設定することで、なんと4ゴールドで買えてしまうというバグがありました。

これはいわゆるオーバーフローが原因だったようです。

逃げるフラグとは違い、カジノコイン変数は24ビットで表現していたみたいです。
4バイト変数の下位24ビットを使っていたのでしょうね。

1が24個分のビットで
1111 1111 1111 1111 1111 1111(2進数)
10進数表記で16,777,215。
これを20ゴールドで割ると838,860.75枚になり、一度に買うことのできる最大枚数は838,860枚のハズでした。

が、これに1枚足して買うことによって、
838,861枚×20ゴールド=16,777,220

2進数で表記すると
1 0000 0000 0000 0000 0000 0100
25桁になってしまい、オーバーフローした25桁目の1が有効値ではなくなり、(100)が残ります。
この(100)は10進数で4になるため、4ゴールドで838,861枚のコインが買えてしまう、というバグなのですね


いやー懐かしすぎて涙出るほど笑いましたw



noteまとめ『文書遊戯』に参加しています
面白いnote沢山更新されるので、覗いてみてはいかがでしょうか♪

画像1

この記事が気に入ったらサポートをしてみませんか?