TOP > プログラミング関係解説&調査 > かわひもバグ

かわひもバグ

当ページの内容は、ある程度のプログラミングの知識を必要とする。
まず、プログラミング関係解説&調査をひととおり読んでいただきたい。
注意!
このバグを実行すると、ゲームが進行不能になります。
ゲームソフトにも何らかの損傷があるかもしれませんので、実行しないでください。
もし実行して何らかの不具合が生じたとしても、筆者は一切の責任を負いません。

SFC版「ライブ・ア・ライブ」には幾つかバグがあり、中にはSF編のように、「パワージャッキを使いすぎて詰む」などといった仕様上の問題で進行不可能になる場合がある。
だが、今回紹介するバグは、表示自体もバグり、進行不能となってしまう、かなり致命的なバグである。
セーブデータにセーブさえしなければ、リセットすると解消されるはずであるが、最悪、ゲームソフト自体に損傷を生じる可能性もあるため、実行するべきではない。
以上をご理解いただいた上でお読みいただくようお願いする次第である。

原始編では、序盤にべると出会った後、朝になるとざきがポゴたちの集落を襲撃してくる。
べるは縄でぐるぐる巻きにされて捕まってしまうが、ポゴとゴリが救出に来て、べるの縄を解く。
このイベントの最中に、合成アイテム「かわひも」が、持ち物に1個加わる。
演出上、べるを縛っていた縄が「かわひも」として持ち物に追加された、ということなのだろう。

この時、「かわひも」を99個所持していると起こるのがかわひもバグである。
アイテムを99個所持している時に、フィールド上で更にもう1個もらったり拾った時に、「このアイテムは それ以上持てません。」と表示されて入手できない。
中世編序盤に、城下町の人から無限にもらえる「こんなモン」や、なおり草群生地で「なおり草」を集めまくった時などが、比較的簡単に確認できる場面である。
近未来編のたい焼き屋の手伝いなど、時間さえかければ、見ることのできる場面は割と多い。
戦闘勝利時にアイテムを得た時は特に表示はないものの、99個を越えていたら自動的に切り捨てられている。

では、原始編のイベント前に既に「かわひも」を99個所持しているとどうなるか。
べるの縄を解くモーションの後、唐突に
「このアイテムは もう持てない!!」
というテキストが表示され、そのテキストをAボタンで消すと、操作キャラのポゴの表示がおかしくなる。具体的には肉のアイコンになってしまう。
そして、イベント中なのに自由に行動可能になって、音楽も通常時の「いいお天気でしょ!」に変わる。ゴリも後からついてくる(位置はすこしずれる)。
だが、これ以上イベントは進行しなくなる。
移動可能なのは、ポゴたちが入ってきた上の通路のみで、通路に入るとポゴの表示は元に戻り、一見すると通常状態に戻っている。
下に行くとイベント開始前の状態に戻っている。
だがイベントを発生させてみると、「かわひも」が99個の状態である限り同じようにバグってしまう。
本作はアイテムを捨てることができず、この状況では合成屋に行くこともできないため、「かわひも」の数を減らすことができない。
つまり、「かわひも」が99個の時点で詰みである。
もし「かわひも」を99個所持していたとしても、ざき襲撃イベントまでに合成屋を利用して、「かわひも」を材料に使うアイテムを合成し、「かわひも」の個数を減らせばバグは回避可能であるが、ざき襲撃イベントを起こしてしまうとどうしようもない。

なお、肉アイコンになった後に、上に停まっている石の車を調べると、再び石の車が暴走するイベントが起こるが、べるが画面外に吹き飛ばされてしまい、何のボタンを押しても反応しなくなる。こうなるとリセットしかない。

通常プレイの範囲では、ざきが襲撃してくる時点で「かわひも」を99個所持というのはほぼありえないだろう。
アイテム合成を利用して「かわひも」を99個まで増やすこと自体はこの時点でも可能だが、やる必要がない。
「かわひも」はアイテム合成にしか使い道がないので、作ったら何かしらのアイテムを合成する材料として消費するだろう。
また、このタイミングで「かわひも」を99個入手するためには、材料となる「ホネ」「かたい石」「ケガワ」を大量に用意する必要があり、狩場で大量のザコを倒して入手するか、20人部屋のミニゲームを100回近くこなし、更に合成屋でひたすら合成を繰り返さなければならない。
そこまでするのは、よほどのやりこみプレイヤーであろう。
このため、通常プレイでこのバグに遭遇することはまずないと思われる。
少なくともSF編のパワージャッキの件よりも、遭遇する可能性は段違いに低く、そのために製品版でも見過ごされたバグではないかと推測される。

ちなみに、集落を追い出されたタイミングで「どでかホネ肉」を3個入手できるが、「どでかホネ肉」は集落を追い出されるまでに入手することが不可能なので、「かわひも」のようなバグは起こらないはずである。

実際の画像

このバグはオリジナルのスーパーファミコン版だけではなく、バーチャルコンソール版でも発生する。
実際に確認したところ、キャラのドット絵までバグってしまうという、かなり危険なバグなのだが、特に修正はされていないことがわかった。
セレクトバグや功夫編修行の技習得バグなどもオリジナル版のままであることからしても、バーチャルコンソール版の「ライブ・ア・ライブ」はオリジナル版のプログラムをそのまま使用しているのではないか、と思われる。

筆者が実際に確認してみた写真を掲載する。
ニンテンドー3DSのバーチャルコンソールのため、3DSの画面を直接写真に撮っている。
しつこいようだが、もし実際に試してみるつもりなら自己責任で。
筆者は、「かわひも」を98個まで増やした時点でセーブし、その後はバグ発生後にリセットしたが、特にゲームプレイに支障はなかった。
ちなみに、序盤で20人部屋のミニゲームを利用して「かわひも」を集める場合、99個にするには1時間半ほどはかかる(手際が良ければもっと短縮できると思う)。

原因

かわひもバグの原因は、アイテム所持数が99個を越えてオーバーフローしたことではない。
10進数での99は16進数での$63にあたるが、アイテムの個数が$63を越えた場合の処理自体はきちんとされている。
その後の「このアイテムは もう持てない!!」の表示後の処理が問題である。

ちなみに「このアイテムは もう持てない!!」という表示は原始編のみで、他シナリオだと「このアイテムは それ以上持てません。」である。

シナリオにより表記を変えた理由はよくわからないが、「このアイテムは もう持てない!!」という表示だからバグが発生するのではない。
ポゴたちの集落や、クー族の集落など、アイテムが拾える場所において、既に99個所持しているアイテムを拾った場合、「このアイテムは もう持てない!!」と表示されてアイテムが入手できないが、バグることはない。

本作では、フィールドにおけるイベントでアイテムが増える時、該当アイテムの所持数が既に99個だと、所持数のチェックをした後、
「このアイテムは もう持てない!!」または「このアイテムは それ以上持てません。」
とウィンドウに表示して、該当イベントを強制終了させるという処理が入るようである。

例えば近未来編のたい焼き屋の手伝いであれば、客に合った値段を選択してたい焼きを売ると、売値に対応した回復アイテムがもらえるが、その回復アイテムの所持数が99個未満なら、

無法松「ごくろうだったな。
 これ持ってけ。

『こ これは‥‥
 (アイテム名)じゃねーか!

という会話になり、回復アイテムを入手できる。
だが、99個所持している場合、

無法松「ごくろうだったな。
 これ持ってけ。

このアイテムは それ以上
持てません。

と表示されて、アキラの入手時セリフはカットされてイベントが終了になる。
これはアイテムを拾う時などでも同様であり、箪笥や宝箱、壺などをAボタンで調べた時、中身のアイテムを既に99個所持していたら、「このアイテムは もう持てない!!」または「このアイテムは それ以上持てません。」と表示されて終了となる。
(このため、拾えなかったアイテムが何だったのかは、「持ち物欄で所持数が99個のアイテムのどれか」ということしかわからない)
この強制終了では何の問題も起こらない。
ただ、アイテムが入手できず、フィールド上においてプレイヤーがキャラを操作できる通常状態に戻るというだけである。

ほとんどの場合は、何かをもらう(拾う)イベントにおいて、所持数99の時点でイベント終了で問題は起こらない。
まず、アイテムの所持数が最大まで増やせるシナリオが限定されている。
近未来・原始・中世・最終編の4シナリオのみであり、これらのシナリオであっても、「99個以上に増やせる可能性があるアイテムを、イベントの途中でもらう」というケースは原始編の「かわひも」のみである。
しかもこの「かわひも」の入手タイミングは、イベントの真っ最中、べるの縄を解いた直後である。
ここでイベントを中断され、更に「フィールド上においてプレイヤーがキャラを操作できる通常状態に戻る」という処理が入ると、続けて発生する敵との戦闘に進めず、進行不能バグが発生することになる。
ちなみに、
「フィールド上においてプレイヤーがキャラを操作できる通常状態に戻る」
という処理の中に、各シナリオにおけるフィールド上の通常BGMに戻す処理も含まれており、ざき襲撃時のBGM「KISS OF JEALOUSY」(原始編通常戦闘曲)が、かわひもバグ発生直後に「いいお天気でしょ!」(原始編フィールドの通常BGM)に変更される原因になっている。

ポゴのグラフィックまでも変わってしまうのは、通常状態に戻った時にスプライト(キャラクターのドット絵)の読み込みアドレスがズレてしまうからのようだ。
筆者はグラフィック関係については詳しくないので、ここでは触れないこととする。

サブルーチン

実際の処理は以下のようになっている。
以下のサブルーチンは、キューブのバッテリーの判定の仕様で紹介した、取得アイテムの処理とほぼ同一である。

$C0/227D LDA $8E00,y[$7F:C6C4]   ;Aに[$7F:C6C4](=$31, 「かわひも」のアイテムID)をロード
$C0/2280 STA $00013D[$00:013D]   ;A(=$31)を[$00:013D]に書き込み
$C0/2284 INY                     ;Yをインクリメント +1
$C0/2285 PHY                     ;Yをスタックへプッシュ
$C0/2286 JSR $47DA  [$C0:47DA]   ;[$C0:47DA]へジャンプ
;
$C0/47DA LDA $00013D[$00:013D]   ;Aに[$00:013D](=$31)をロード
$C0/47DE BEQ $4B    [$482B]      ;ゼロフラグが立っているとき[$482B]分岐
$C0/47E0 PHB                     ;DBレジスタをスタックにプッシュ
$C0/47E1 LDA #$D5                ;Aに$D5をロード
$C0/47E3 PHA                     ;Aをスタックにプッシュ
$C0/47E4 PLB                     ;DBレジスタに値をプル
$C0/47E5 JSR $487F  [$C0:487F]   ;[$C0:487F]へジャンプ

これがイベント寸前の処理で、[$7F:C6C4]をロードして[$00:013D]に書き込んでいる。
この[$7F:C???]あたりに入っているのはシナリオ進行上必要な値で、各シナリオで変動するが、原始編だと[$7F:C6C4]に入っているのは$31
これは「かわひも」のアイテムIDにあたる。
つまりアイテム名の呼び出しであり、キューブのバッテリーの時も同じサブルーチンが使われていた。

$C0/47E8 LDA #$00                ;Aに$00をロード
$C0/47EA PHA                     ;Aをスタックにプッシュ
$C0/47EB PLB                     ;DBレジスタに値をプル
$C0/47EC PHX                     ;Xをスタックにプッシュ
$C0/47ED PHY                     ;Yをスタックへプッシュ
;
;持ち物欄のアイテムIDチェック ループ処理(X:0B28 Y:0C28から開始)
$C0/47EE LDA $00,x               ;Aに[$00:0B28~]をロード
$C0/47F0 CMP $013D  [$00:013D]   ;Aと[$00:013D](=$31)を減算比較(ステータスレジスタ変更のみ)
$C0/47F3 BEQ $1C    [$4811]      ;ゼロフラグが立っているとき[$4811]分岐
$C0/47F5 INX                     ;Xをインクリメント +1
$C0/47F6 INY                     ;Yをインクリメント +1
$C0/47F7 CPX #$0C00              ;Xと$0C00を減算比較(ステータスレジスタ変更のみ)
$C0/47FA BNE $F2    [$47EE]      ;ゼロフラグが立っていないとき[$47EE]分岐
;ループ終了
;
;$C0/47F3でゼロフラグON(「かわひも」を既に所持済み)
$C0/4811 LDA $0000,y             ;Aに[$0000,y]をロード
$C0/4814 CMP #$63                ;Aと$63を減算比較(ステータスレジスタ変更のみ)
$C0/4816 BCS $F4    [$480C]      ;キャリーフラグが立っているとき[$480C]分岐
$C0/4818 INC A                   ;Aをインクリメント +1
$C0/4819 STA $0000,y             ;Aを[$0000,y]に書き込み
$C0/481C PLY                     ;Yレジスタにスタックからプル
$C0/481D PLX                     ;Xレジスタにスタックからプル
$C0/481E BRA $0A    [$482A]      ;フラグにかかわりなく常に分岐[$482A]
;
$C0/482A PLB                     ;DBレジスタに値をプル
$C0/482B CLC                     ;キャリーフラグクリア
$C0/482C RTS                     ;サブルーチン戻り
;
;$C0/4816でキャリーフラグON(「かわひも」所持数が$63)
$C0/480C PLY                     ;Yレジスタにスタックからプル
$C0/480D PLX                     ;Xレジスタにスタックからプル
$C0/480E PLB                     ;DBレジスタに値をプル
$C0/480F SEC                     ;キャリーフラグON
$C0/4810 RTS                     ;サブルーチン戻り

ここが、持ち物欄に入手したアイテムを書き込むサブルーチンである。
持ち物欄関係のアドレスは、シナリオにより変わる。
原始編だと、持ち物欄に入っているアイテムIDは$00:0B28$00:0B4C、持ち物欄に入っているアイテムIDの各個数は$00:0C28$00:0C4Cである。
つまり、原始編では、所持できるアイテム種類は最大37種類である。これは持ち物欄でカーソルを下まで移動させてみるとわかる。

このため、$C0/47EE~のアイテムIDチェックのループ処理は、[$00:0B28]のチェックから開始になる。
[$00:013D]に入っている、「かわひも」のアイテムID$31と一致する場合は$C0/47F3でループを抜ける。
アイテム欄に「かわひも」がひとつもない場合はアイテム欄の最後までチェックをする。つまりX$0C00に増加するまでチェックし、なかった場合は$C0/47FCに進む。

ただ、$C0/47F7CPX #$0C00で、アイテムIDチェックは最大で[$00:0BFF]まで行うように指定されていることがわかる。
このサブルーチンはどのシナリオでも共通なので、中世編・最終編のアイテムIDが入る最後のアドレス$00:0BFFまでチェックするようにCPX #$0C00が指定されていると思われるが、原始編の場合は$00:0B4Cまでで事足りるので、$00:0B4Cより後のチェックは意味がない(原始編では00で埋まっている)。
シナリオ毎にループ回数を決めて分岐させるよりもこちらの方が都合が良いのかもしれないが、何にしても筆者には理由はわからない。

さて、今回重要なのは、既に「かわひも」の所持数が99だった場合、つまり、16進数の$63だった場合なので、持ち物欄のどこかに「かわひも」があり、$C0/47F3でループを抜けたという前提で後の処理を見ていく。
ループを抜けると$C0/4811にジャンプし、「かわひも」の所持数をチェックする。
$C0/4814$63(10進数99)と減算比較しているので、「かわひも」の所持数が99ならキャリーフラグが立ち、$C0/480Cにジャンプする。
所持数99未満なら$C0/4816以降の処理で、「かわひも」の所持数を+1している。

この個数による分岐で重要なのは、「かわひも」所持数が$63だと、$C0/480FでキャリーフラグがONの状態でサブルーチンの処理が終わる。
「かわひも」所持数が$63未満の時は、$C0/482BでキャリーフラグがOFFの状態でサブルーチンの処理が終わる。
この違いにより、この先の処理が変わる。

$C0/2289 PLY                     ;Yレジスタにスタックからプル
$C0/228A BCS $03    [$228F]      ;キャリーフラグが立っているとき[$228F]分岐
;キャリーフラグなし(「かわひも」所持数が$63未満)
$C0/228C BRL $F912  [$1BA1]      ;フラグにかかわりなく常に分岐[$1BA1]

;キャリーフラグあり(「かわひも」所持数が$63)
$C0/228F PLB                     ;DBレジスタに値をプル
$C0/2290 LDA #$FF                ;Aに$FFをロード
$C0/2292 BRL $F8F8  [$1B8D]      ;フラグにかかわりなく常に分岐[$1B8D]

サブルーチンの処理が終わった後の戻り先はC0/2289になるのだが、$C0/228Aでキャリーフラグによる分岐がある。
つまりここで、「かわひも」所持数が$63だったかどうかで処理が分岐になる。
「かわひも」所持数が$63未満だった場合なら、ジャンプ先は$C0/1BA1
「かわひも」所持数が$63だった場合なら、ジャンプ先は$C0/1B8Dである。
つまり全く別のアドレスに飛ぶ。

「かわひも」所持数が$63だった場合の$C0/1B8D~が、「このアイテムは もう持てない!!」をウィンドウで表示し、プレイヤーがウィンドウをAボタンで消すと、フィールド上においてプレイヤーがキャラを操作できる通常状態に戻す、というサブルーチンである。
「このアイテムは もう持てない!!」の後に、「かわひも」所持数が$63未満だった時の処理に合流することはないので進行不能バグとなってしまう。



このページをシェアする

上へ