Displaced Gamersは、自身のYouTubeチャンネルで『スーパーマリオブラザーズ』の有名なバグ技である-1面に行くメカニズムを紹介した動画を公開しました。
ファミコンの人気を大きく牽引し、今なお愛され続けている人気ゲームの『スーパーマリオブラザーズ』。大ヒットタイトルということもあり、様々な裏技やテクニックが登場しました。中には別のカセットを利用して256面に行くといったものもありますが、今回焦点が当てられているのはその中でもメジャーな、1-2の最後のワープゾーンを利用したバグです。
『スーパーマリオブラザーズ』の1-2面では、通常のルートとは別に天井を移動することで2面、3面4面に行けるワープゾーンが用意されています。しかし、ブロックの間を無理矢理通り抜けてからワープすると、-1面に行くことができるというのが、このバグの簡単な概略です。-1面はひたすら海のゾーンが続くだけで特に変わったものはありませんが、当時の子供たちは面白がってプレイしていました。
この「-1」面ですが、じつは頭の数字がタイトルグラフィックになっており、8-1といった感じで本来数字のグラフィックが表示される代わりに、空白のグラフィックになっていることから「-1」と表示されているように見えているものでした。実際はこの空白のグラフィックのIDは36であるため、本来はワールド36-1と呼んだほうが正しいのかもしれません。
この-1面にバグを利用するエリアには、設計道理に機能していない見えない敵が存在しています。この隠れた敵は、ワープゾーンへのルートロックを解除する役割がありました。
スーパーマリオブラザーズのレベルデザインの仕組み
『スーパーマリオブラザーズ』は、わずか32Kのプログラムで動いています。バンク切り替えを使わずファミコンのアドレスに収まるサイズですが、ストレージ用のスペースはあまり多くありません。そのためレベルを圧縮して、少量のデータを利用してレンダリングする方法が必要になります。
『スーパーマリオブラザーズ』では、面のレイアウトすべてを保存しているわけではなく天井と床のブロック数を提供しています。特に指示が無い限り、そのパターンを描画し続けるという仕組みが採用されているのです。
マリオが画面右に移動すると、天井や床のレイアウト、追加のオブジェクトや敵、目的の部屋など次の列をプログラムが先読みします。各面の最終地点には「スクロール停止オブジェクト」が配置されており、それ以上画面がスクロールしないようになります。
ゲームのプログラムは、現在表示されているものよりも画面半分に相当する情報を先読みでレンダリングします。そのため、スクロールの停止もすぐにアクティブになります。
1-2面の最後にはふたつの「スクロール停止オブジェクト」があり、ふたつ目のワープゾーンの「スクロール停止オブジェクト」は機能しています。スクロールが停止するとワープゾーンを設定するロジックも発動します。ワープゾーンに出現する土管は、「4-3-2」、「5」、「8-7-6」の3種類です。それぞれ4、5、6の値が「WarpZoneCotrol」としてRAMに保存されます。ここで保存された数値は、コード後半のオフセット計算の一部として利用されます。
「WirteGameText」というサブルーチンで「WELCOME WARP ZONE!」を出力。そのときに「WaroZoneCotrol」の値を土管の上に番号として表示しています。
RAMにある「WarpZoneCotrol」の値は、マリオが土管に入るときに参照され、どこのゾーンに移動するか決定するときにも使用されます。特定の条件により、この値が原因で「-1」面に行くことができるようになるのです。
バグを利用する1/2のワープゾーン手前委には、見えない敵が設定されており、それがスクロールのロック解除をするためのキーとして機能するようになっています。すべてのフレームで「スクロール停止オブジェクト」をチェックし続け、ロックされるとロック解除のチェックをし続けます。その基準が満たされたときにスクロールロックが解除される仕組みです。
1-2のラストではL字パイプとふたつの壁ブロックが画面に表示されたときに、スクロールが停止します。その後、ロック解除基準が満たされたときに見えない敵がスクロールのロックを解除します。が、そもそもここでスクロールロックを解除する必要はあまりなく、画面を好きなだけ右に移動させ続けることが可能です。
レベルデザイン上で、この見えない敵の存在とスクロールを停止するようにした理由はなんでしょうか?
マリオはX軸とY軸のロケーションが設定されています。それぞれページの場所とそれに続く座標を表しており、ジャンプはY軸の変化を示しています。本作では垂直方向には移動しないため、Yページは常に1であると想定することができます。
「WarpZoneCotrol」が存在しないとかは0の値が設定されています。スクロールのロックは許可されていないときは1で、それ以外は0になっています。スクロールをアンロックする見えない敵はX32Y112に存在しています。しかし、画面上で見えない敵の正確な位置は関係なく、スクロールが停止する前にスポーンしてエリアに存在すればいい状態です。
マリオをスクロール停止位置に動かすと、スクロールが一時停止します。このとき、スクロールをアンロックする見えない敵はスクロールを解除した後で自らも破壊します。また、このときに、「WarpZoneCotrol」の値が1増加します。つまり、本来はこのときに「WarpZoneCotrol」の値は変わらないようにすべきだったのが、無効な値に変更されたことが原因でバグが発生しているのです。
動画内ではさらなる詳細が説明されているので、興味がある人はぜひチェックしてみてください。