【裏技】SFC ドラゴンクエスト6 乱数固定現象を紐解く【バグ技】

スーパーファミコン版『ドラゴンクエストVI 幻の大地』には、ゲーム内の乱数を意図的に固定状態にする裏技が存在します。本記事では、その手順から仕組み、コードレベルの解析、チートによる実現方法、さらには放置による乱数固定の理屈までを解説します。
※この裏技を利用することによってゲームバランスが崩壊したり、ゲームデータが消えるリスクなどがあります。お試しの際は自己責任でお願いします。
目次
幻のバグから究極の裏技へ ドラクエ6の「乱数固定技」とは
SFC版『ドラゴンクエスト6』には、かつてプレイヤーの間で囁かれていた都市伝説がありました。
それは、「なんらかの条件で会心の一撃が100%発生し、カジノのスロットで常にスリーセブンが揃い、さらにはアイテムドロップ率が100%になる」といった、まるでSFCドラクエ5の「ひとしこのみ」を彷彿とさせるような、ゲームバランスを根底から覆す現象が起きるというものです。
実際にこの現象を目にし、学校のクラスメイトや友達に興奮して話したものの、信じてもらえず嘘つき呼ばわりされた、という人もいたほどです。
この噂は、2000年代半ばに個人攻略サイトのBBS掲示板や匿名掲示板、Wazapなどで報告され広まり、「カセット挿しっぱなしで3日放置したら起きた」といった体験談が語られましたが、その発生条件は誰にも分からず、再現方法も不明であったため、狙って出せるものではないとされていました。
そのため、長らく「SFC本体の熱暴走によるエラー」などと推測され、「これは幻の大地ではなく、幻のバグ」として扱われてきたのです。
しかし、2023年にこの状況は劇的な変化を迎えます。
DQ乱数解析者のかくれみ氏(@_kakuremi)が、ついにこの不思議な現象を意図的に発生させる方法を特定し、再現性のある手順として確立させたことで長年の謎が解き明かされたのです。
DQ6で乱数を0に固定します。
まず、パーティ1人状態でダーマ神殿でセーブします。
その後、リセット & Aボタン長押しで再開し、動画のように操作します。メッセージ送り以外は十分な猶予フレームがあります。1:16, 1:25辺りはNPCの足踏みをヒントにします。
※実機で再現済みです pic.twitter.com/ezbi7A0HDt— かくれみ (@_kakuremi) February 16, 2023
その正体は、「単なるバグ」ではありませんでした。内容としては、特定の場所でセーブし、特殊な起動方法とフレーム単位の精密な操作を組み合わせることで、ゲームの乱数生成機能を意図的に破壊し、都合の良い結果に固定するという、極めて高度な「乱数固定技」だったのです。この現象はSFC本体の仕様とゲームプログラムの脆弱性が奇跡的に組み合わさって生まれた、リバースエンジニアリングの産物とも言えるものです。
そして今、この「乱数固定技」は、ゲームクリアまでの速さを競うRTA(リアルタイムアタック)という競技的なゲームプレイの世界で、その真価を発揮。バグや裏技ありのレギュレーションでは、記録を劇的に短縮するための必須テクニックとしてチャートに組み込まれ、戦略上、極めて重要な位置を占めるに至っています。
かつて「幻のバグ」と呼ばれた都市伝説は、一人の探求者の手によってそのメカニズムが解明され、ゲーム攻略の最先端を切り拓く究極の裏技として昇華されました。
大前提:ゲームにおける「乱数」の仕組み
ゲームにおける乱数の仕組みを理解するために、まず基本的な概念から説明します。
ゲームで使用される「乱数」は、実際には完全にランダムな数値ではありません。これらは「疑似乱数」と呼ばれるもので、特定の計算式やアルゴリズムによって生成される数値の列です。一見ランダムに見えますが、実際には数学的な規則に従って作られています。
ゲーム内部には乱数生成器(RNG:Random Number Generator)というプログラムが組み込まれており、これが次の乱数を計算する役割を担っています。この乱数生成器は「内部状態」または「シード」と呼ばれる数値をメモリ上に保持しています。新しい乱数が必要になるたびに、この内部状態を基に次の乱数を計算し、同時に内部状態自体も新しい値に更新されます。
ゲーム中では、敵キャラクターの行動パターンの決定、攻撃や魔法のダメージ計算、アイテムのドロップ率判定など、様々な場面でランダムな要素が必要となります。こうした処理が発生するたびに、乱数が一つずつ「消費」されていく仕組みになっています。
この疑似乱数システムにおいて最も重要な特徴は、同じ内部状態から開始すれば、その後に生成される乱数の列は必ず同じになるという点です。つまり予測可能な数値列なのです。
乱数固定技のやり方
乱数を固定する具体的な手順は以下の通りです。
- 準備
スーパーファミコン本体と『ドラゴンクエストVI』のカセットを用意します。
クリア後のデータを使用するのが推奨されますが、下(下の世界)で実体化していれば問題なく、ある程度ストーリーを進めておくとより楽しめるでしょう。 - 操作キャラを一人にする
並び替えをして操作キャラクター1人だけにしておきます。(キャラクターは誰でも可) - サンマリーノへ移動
サンマリーノの町へ向かいます。 - 教会へ向かい祈る
サンマリーノに入ったら教会へ向かい、神父に話しかけて「お祈り」をして冒険の書に記録します。 - 電源を切る
セーブが完了したら、本体の電源を切ります。 - Aボタンを押しながら電源を入れる
次に、Aボタンを押しっぱなしにした状態で電源を入れます。 - Bボタン連打する
Aボタンを押しっぱなしにしていると、ゆっくりと自動的に「冒険の書」が選択されます。選ばれたらBボタンを連打します。 - シスターの目の前へ移動
神父のメッセージを素早く送り、ウィンドウが閉じたら、すぐに右下にいるシスターの目の前へ移動します。 - シスターの動きを見て、当たりパターンがどうか確認
この時点で「外れパターン」の場合(乱数固定が成功しない場合)は、再度電源を入れ直して手順6から繰り返します。パターンの判断や詳細な手順については、このバグの発見者(かくれみ氏)のウェブページをご参照ください。動画もあります。
http://kakuremi.s370.xrea.com/dq6_rng_manip.html - 当たりパターンであれば、NPC(シスター)の動きをキャラクターで妨害しつつ、解析によって特定された操作を決められた手順で実行
- 乱数固定の成功を確認
NPCが上をずっと向いているなら成功です。
乱数が固定されると、どのような現象が起こるのか?
乱数生成器が常に同じ値を返すようになると、確率に依存する全ての事象が固定化されるようになります。これは有利に働くこともあれば、不利になることもあります。
- 町の人々(NPC)が、本来は上下左右に動き回るところ、上方向のみにしか動かなくなります。
- 戦闘開始時、必ずモンスターがおどろきとまどい、100%先制攻撃が可能になります。
- 出現するモンスターの組み合わせが特定のテーブルに固定されます。同種モンスター1匹×2という組み合わせとなり、これによって特定の敵を狙えますが、逆に一部のモンスターとは遭遇できなくなります。
- 回避率が設定されている敵の攻撃は、必ず回避できるようになります。
- 「会心の一撃」といった確率で発生する攻撃は、必ず発動するようになります。
- 敵の行動は、行動パターンの中で最も優先度の高い(通常は最初に設定された)ものが常に選択されます。これにより敵が弱体化することも、逆に強力な攻撃ばかりを繰り出す脅威となることもあります。
- 戦闘終了後、モンスターが宝箱を100%ドロップします。
- モンスターが仲間になる条件を満たしていれば、戦闘終了後に必ず仲間になります。
- 2回行動する可能性のあるモンスターやキャラクターは、必ず1回しか行動しなくなります。
- エンカウントするまでの歩数が、設定された範囲内の最小値に固定されます。つまり敵が出現しやすくなります。
- メダパニやラリホーなど、一定確率で成功する状態異常系の呪文は、耐性を持たない敵に対して100%成功します。
- ダメージや回復量の計算に乱数幅がある場合、常にその最小値が適用されます。
- 「あなほり」では、もはや錬金術の如く必ずアイテムをゲットできます。
- 「ちからのたね」といったドーピングアイテム使用時の上昇値が、常に最低値に固定されます。
- ポーカーでは、最初に配られた時点でストレートフラッシュなどの強力な役が、イカサマのように確定で揃います。ダブルアップも必ず成功します。
- スロットでは、「777」が無限に揃い続けます。コインが最大値(9999999枚)となってカウンターストップに達してもスロットが止まらなくなり、リセットするしかなくなります。ボーナスカウントも999を超えてオーバーフローし継続されます。
DQ6の乱数システムの基本仕様と構造的欠陥
RNG内部状態を格納するWRAMアドレス
『ドラゴンクエストVI』では、戦闘やNPCの挙動など、ゲーム内のあらゆる「運」の要素が疑似乱数生成器(RNG)によって制御されています。このRNGの内部状態は32ビットの値で構成されており、スーパーファミコンのWRAM(ワークRAM)上のアドレス $7E584A ~ $7E584D にリトルエンディアン形式で格納されています。
$7E584A (最下位バイト)
$7E584B
$7E584C
$7E584D (最上位バイト)
開発者が設定した初期シード
ゲームの起動時、乱数生成器の内部状態(RNG状態)は、不定な値から始まるわけではありません。コード($C0:00F6~)により、RNG状態は「0xAAE21259」という32ビットの固定値(初期シード)に設定されています。
NMI割り込みによる毎フレームの乱数更新
SFC版『ドラゴンクエストVI』の乱数システムを理解する上で、最も基盤となるのがNMI(ノンマスカブル割り込み)ハンドラ($C0:0260~)の存在です。これは、ゲームの挙動を根底から支える、まさに「心臓」とも言えるプログラムです。
NMIとは何か?
NMIは、CPUが絶対に無視できない強制的な割り込み信号で、スーパーファミコンでは通常、テレビ画面の1フレーム描画が終了した後の「V-Blank(垂直帰線消去期間)」に発生します。つまり、このNMIハンドラに書かれたコードは、ゲームがどんな状態であっても1フレーム(約1/60秒)に1回、バックグラウンドで必ず呼び出され続けています。
このNMIハンドラは、パッド入力の受付やPPU(画像処理ユニット)の制御、画面効果の更新など、毎フレーム欠かせない多くの定常処理を担っていますが、その中でも特に重要なのが「乱数状態の軽量更新」です。
待機中でも乱数が変化し続ける理由:条件分岐による2系統の更新
プレイヤーが何も操作していなくても乱数が変化し続けている理由は、このNMIハンドラがRNG状態を常に更新しているためです。しかし、その更新方法は一通りではありません。NMIハンドラは、ゲーム内のフラグなどをチェックし、現在のゲームの状況に応じて、2種類の異なるパスのいずれかを実行するという、非常に高度な設計になっています。
待機・軽量処理時の更新 ($C0:028A~):
画面の暗転中など、ゲームが「待機状態」にあるフレームでは、最低限の処理だけが行われます。この時、RNG状態は32ビット左ローテート(ROL)によって軽くかき混ぜられます。
メイン処理中の更新 ($C0:031E~):
ゲームが「アクティブ状態」にあるフレームでは、キャラクターの更新やイベント処理といったメインの処理が実行されます。そして、その一連の処理の一部として、待機時と全く同じ32ビット左ローテート処理が再度組み込まれています。
結果として、ゲームがどのような状態であっても、毎フレーム必ずどちらかのパスに存在するROL命令が実行されることになります。これにより、RNG状態は決して停滞することなく、1秒間に約60回という猛烈な勢いでかき混ぜられ、変化し続けているのです。
Addr | Value | Source | Cmt |
---|---|---|---|
C0:028A | AD 4D 58 | LDA $584D | |
C0:028D | 0A | ASL A | |
C0:028E | 2E 4A 58 | ROL $584A | |
C0:0291 | 2E 4B 58 | ROL $584B | |
C0:0294 | 2E 4C 58 | ROL $584C | |
C0:0297 | 2E 4D 58 | ROL $584D |
この一連の命令は、$7E584A~$7E584Dに格納されている32ビットの乱数内部状態(RNG状態)を、まるごと1ビット左に回転(ローテート)させる処理です。計算負荷は非常に軽く、RNG状態は毎フレームかき混ぜられ、決して停滞することはありません。つまり、左ローテートのみ行われている間は、乱数が固定されることはないのです。
<32ビット幅ローテートの技術的解説>
65816 CPUには、32ビットの値を一度に回転させる便利な命令はありません。そのため、このコードは複数の8ビット命令を巧みに組み合わせることで、32ビットのローテートを擬似的に実現しています。そのプロセスは以下の通りです。
- まず、32ビット全体の最上位ビット($584Dの左端ビット)をLDA命令で読み込みます。
- 次にASL命令でAレジスタを1ビット左にシフトします。この時、押し出された最上位ビットはCPUのキャリーフラグ(Cフラグ)に一時的に保存されます。
- ROL $584A命令を実行します。この命令は、キャリーフラグの値を$584Aの最下位ビットに入れ、同時に$584Aの最上位ビットを新しいキャリーフラグとして設定します。これにより、(2)で退避させた「32ビット全体の左端ビット」が右端に繋がり、回転の輪が完成します。
- 続く3つのROL命令($584B~$584D)は、この「前のバイトから押し出されたビット(Cフラグ)を、次のバイトの右端に入れる」という処理を連鎖的に行います。
この一連の連携により、32ビットの値が全体として、綺麗に1ビット左に回転するのです。
LFSR(線形帰還シフトレジスタ)アルゴリズムに基づいたメインルーチン($C0:0E97~)
NMI割り込みによる軽量な更新とは別に、本作の乱数システムの中心的役割を担うのが、LFSR(線形帰還シフトレジスタ) と呼ばれるアルゴリズムを応用した、メインのRNG状態更新ルーチンです。このルーチンこそが、本記事でとりあげる乱数固定の肝となる部分です。
このLFSRルーチンは、NMIハンドラのように常時実行されるわけではありません。シフトやEOR(排他的論理和:はいたてきろんりわ)といった複数の計算を組み合わせた、比較的負荷の高い処理であるため、戦闘中の行動決定や、NPCの移動方向の決定など、質の高い乱数が必要とされる特定の場面で、必要に応じて呼び出されます。
解析の結果、機能的に全く同一のLFSRルーチンが、ROM上の異なるアドレスに2つ存在することが判明しました。
- サブルーチン1 ($C0:0E97~): 主に戦闘中の各種判定処理やカジノ処理から呼び出されます。
- サブルーチン2 ($C0:0ECC~): 主にフィールドや町でのNPCの移動など、マップ上のイベント処理から呼び出されます。
これは、プログラムの構造化やSFCのバンク切り替えの都合など、開発上の実践的な理由によるものと考えられます。異なるゲーム状況に応じて、それぞれ専用のルーチンを呼び出すという、最適化された設計になっています。
Addr | Value | Source | Cmt |
---|---|---|---|
C0:0E97 | 08 | PHP | |
C0:0E98 | 8B | PHB | |
C0:0E99 | 78 | SEI | |
C0:0E9A | C2 20 | REP #$20 | A:16 |
C0:0E9C | F4 7E 7E | PEA #$7E7E | |
C0:0E9F | AB | PLB | |
C0:0EA0 | AB | PLB | |
C0:0EA1 | AD 4A 58 | LDA $584A | |
C0:0EA4 | 0A | ASL A | |
C0:0EA5 | 0A | ASL A | |
C0:0EA6 | 4D 4C 58 | EOR $584C | |
C0:0EA9 | 0A | ASL A | |
C0:0EAA | 29 00 FF | AND #$FF00 | |
C0:0EAD | EB | XBA | |
C0:0EAE | E2 20 | SEP #$20 | A:8 |
C0:0EB0 | 48 | PHA | |
C0:0EB1 | AD 4C 58 | LDA $584C | |
C0:0EB4 | 8D 4D 58 | STA $584D | |
C0:0EB7 | AD 4B 58 | LDA $584B | |
C0:0EBA | 8D 4C 58 | STA $584C | |
C0:0EBD | AD 4A 58 | LDA $584A | |
C0:0EC0 | 8D 4B 58 | STA $584B | |
C0:0EC3 | 68 | PLA | |
C0:0EC4 | 8D 4A 58 | STA $584A | |
C0:0EC7 | AB | PLB | |
C0:0EC8 | 28 | PLP | |
C0:0EC9 | 48 | PHA | |
C0:0ECA | 68 | PLA | |
C0:0ECB | 6B | RTL |
Addr | Value | Source | Cmt |
---|---|---|---|
C0:0ECC | AD 4A 58 | LDA $584A | |
C0:0ECF | 0A | ASL A | |
C0:0ED0 | 0A | ASL A | |
C0:0ED1 | 4D 4C 58 | EOR $584C | |
C0:0ED4 | 0A | ASL A | |
C0:0ED5 | 29 00 FF | AND #$FF00 | |
C0:0ED8 | EB | XBA | |
C0:0ED9 | E2 20 | SEP #$20 | |
C0:0EDB | 48 | PHA | |
C0:0EDC | AD 4C 58 | LDA $584C | |
C0:0EDF | 8D 4D 58 | STA $584D | |
C0:0EE2 | AD 4B 58 | LDA $584B | |
C0:0EE5 | 8D 4C 58 | STA $584C | |
C0:0EE8 | AD 4A 58 | LDA $584A | |
C0:0EEB | 8D 4B 58 | STA $584B | |
C0:0EEE | 68 | PLA | |
C0:0EEF | 8D 4A 58 | STA $584A | |
C0:0EF2 | C2 20 | REP #$20 | A:16 |
C0:0EF4 | 6B | RTL |
LFSRルーチンにおける乱数生成の動作解説
このルーチンは、現在の32ビットRNG状態($7E584A~$7E584D)を元に、以下のプロセスで内部状態を更新し、新たな乱数を生成します。
- 準備処理:プロセッサの状態を保存し、割り込みを禁止。アキュムレータを16ビットモードにし、データバンクを$7Eに設定。
- 値の読み込み: まず、RNG状態の下位16ビットと上位16ビットをそれぞれ読み込みます。
- フィードバック値の計算: 読み込んだ値を、ビットシフトやEOR(排他的論理和)といった命令で複雑に計算します。これがLFSRにおける「フィードバック」の計算であり、次の乱数の元となる新しい値を生成します。
- 内部状態のシフト: RNG状態の3バイト分を、1バイトずつ左方向にシフトさせます。
- フィードバック値の書き込み: (3)で生成した新しいフィードバック値を、シフトによって空いたRNG状態の最下位バイトに書き込みます。
- 後処理:状態を元に戻し、サブルーチンを終了。
この一連の処理により、全く新しい32ビットの値へと更新されます。LFSRは高速で実装が簡単なため、当時のゲームでよく使われました。
乱数値の取得ルーチン:内部状態から実用的な「値」への変換
LFSRルーチンによって更新された32ビットのRNGは、その値自体がそのまま使われるわけではありません。ダメージ計算やアイテムの選択など、ゲーム内で実際に「高品質でランダムな数値」が必要になった際には、その都度、乱数値取得用の専用サブルーチン($C0:0EF5~)が呼び出されます。以下のサブルーチンの役割は、現在のRNG状態を元に、それをさらにかき混ぜ(ハッシュ化し)、最終的にゲームで扱いやすい8ビットの乱数値(0~255)を生成して返すことです。
Addr | Value | Source | Cmt |
---|---|---|---|
C0:0EF5 | 08 | PHP | |
C0:0EF6 | 8B | PHB | |
C0:0EF7 | 78 | SEI | |
C0:0EF8 | E2 30 | SEP #$30 | AXY:8 |
C0:0EFA | A9 7E | LDA #$7E | |
C0:0EFC | 48 | PHA | |
C0:0EFD | AB | PLB | |
C0:0EFE | A0 08 | LDY #$08 | |
C0:0F00 | AD 4B 58 | LDA $584B | |
C0:0F03 | 4D 4E 58 | EOR $584E | |
C0:0F06 | 0E 4A 58 | ASL $584A | |
C0:0F09 | 2E 4B 58 | ROL $584B | |
C0:0F0C | 0E 4E 58 | ASL $584E | |
C0:0F0F | 0A | ASL A | |
C0:0F10 | 90 10 | BCC $0F22 | |
C0:0F12 | AD 4A 58 | LDA $584A | |
C0:0F15 | 49 21 | EOR #$21 | |
C0:0F17 | 8D 4A 58 | STA $584A | |
C0:0F1A | AD 4B 58 | LDA $584B | |
C0:0F1D | 49 10 | EOR #$10 | |
C0:0F1F | 8D 4B 58 | STA $584B | |
C0:0F22 | 88 | DEY | |
C0:0F23 | D0 DB | BNE $0F00 | |
C0:0F25 | AB | PLB | |
C0:0F26 | 28 | PLP | |
C0:0F27 | 6B | RTL |
乱数値取得の動作解説
このサブルーチンは、単純にRNG状態の一部を切り出して返すのではなく、より高品質で偏りの少ない乱数値を得るために、以下の計算プロセスを踏んでいます。
- 8回のループ処理:まず、LDY #$08という命令でカウンターをセットし、これから続く計算処理を8回繰り返すループ構造に入ります。これは、RNG状態のビットを徹底的にかき混ぜ、特定のパターンが現れるのを防ぐためです。
- マジックナンバーとの混合:ループの内部では、RNG状態の一部と、開発者が設定した固定値(マジックナンバー)をEOR(排他的論理和)で混合します。これは、計算に予測不可能な要素(に見える定数)を加え、乱数の質を向上させるために行われます。
- ビットシフトとローテート:RNG状態の各バイトに対して、ASL(算術左シフト)やROL(左ローテート)といった命令を実行し、ビットの位置をずらしてパターンをさらに複雑化させます。
- 条件分岐による計算プロセスの変化:このルーチンの特徴的な点は、計算の途中のビットの状態(キャリーフラグ)に応じて、BCC命令で処理の流れを分岐させることです。もし特定の条件を満たした場合、さらに別のマジックナンバー(#$21, #$10など)をEORで混ぜ込む処理が追加で実行されます。これにより、現在のRNG状態の値に応じて、計算プロセス自体も動的に変化するという、非常に凝った作りになっています。
この8回にわたる複雑なループ処理が完了すると、最終的にAレジスタに8ビットの乱数値が生成されます。呼び出し元のプログラムでは、このAレジスタの値を「ランダムな結果」として利用します。
次に、応用乱数ルーチンの解説をします。全ての基礎となる「LFSR更新ルーチン」の上に、目的別の3種類の「応用乱数ルーチン」が実装されており、ゲーム内の様々な確率的要素を実現しています。
1. 8ビット範囲指定乱数ルーチン($C0:0F28~)
このサブルーチンは、Aレジスタで指定された8ビットの値(0~255)を上限Nとし、「0からNまでの範囲の整数乱数」を生成します。計算方法は、まず「上限値-下限値」で乱数の幅を求め、その幅で乱数を生成した後に下限値を足し込むという、非常に標準的な実装です。主に、ダメージ計算や回復量のように、比較的狭い範囲で結果が変動する処理で使われます。
<具体的な使用例>
アイテム・呪文の効果値判定:呪文のダメージや回復量が、設定された範囲内でランダムに決定される際に呼び出されます。
「あなほり」の判定:特技「あなほり」を使用した際に、見つかるアイテムやゴールドを決定する内部的な確率判定で利用されます。
2. 16ビット範囲指定乱数ルーチン($C0:0F49~)
このサブルーチンは、8ビット版の拡張であり、Aレジスタで指定された16ビットの値(0~65535)を上限とする、より広範囲の乱数を生成します。これにより、1/256や1/1024といった、低い確率の判定を正確に行うことができます。仲間モンスターの加入判定のように、ゲームの進行に大きな影響を与える重要な確率判定で使われるのが特徴です。
<具体的な使用例>
仲間モンスターの加入判定:「確率1/N」を判定するため、「0~N-1」の乱数を生成し、結果が0だった場合のみ仲間になる、というロジックで使われます。
「おおごえ」の判定:複数ある施設の中から、どの施設が呼ばれるかをランダムに決定する際に利用されます。
盗賊の「ぬすむ」成功判定:盗賊がアイテムを盗めるかどうかの確率判定にも、このルーチンが関わっています。
3. ゼロページ間接指定 範囲乱数ルーチン($C0:0F81~)
このサブルーチンは、最も特殊で効率化されたものです。Xレジスタで指定された「ゼロページアドレス」に格納されている値を上限として、「0からその値までの範囲の乱数」を生成します。ゼロページはCPUが高速にアクセスできるメモリ領域であるため、頻繁に上限値が変動する、速度が要求される処理で特に有効です。主に戦闘中の複雑な内部処理で使用されます。
<具体的な使用例>
戦闘中の行動決定:敵AIが、複数の攻撃パターンの中からどの行動を選択するかを決定する際に呼び出されます。
攻撃対象の決定:複数の敵や味方がいる場合に、誰を攻撃対象とするかをランダムに決定する処理で利用されます。
乱数が固定される仕組み:LFSRの「ゼロ状態への陥落」
これで、DQ6が使用する主要な乱数生成関連のサブルーチンを紹介しました。
応用的な処理も含め、最終的に単一のLFSR(線形帰還シフトレジスタ)更新ルーチンに依存しているという構造こそが、乱数固定という現象がゲーム全体に影響を及ぼす理由であり、その根本原因は、このLFSRアルゴリズムが持つ数学的な弱点にあります。
本作で採用されているLFSR風のアルゴリズムには、「内部状態が一度でも全て0になると、それ以降は0以外の値を生成できなくなる」という、致命的な欠陥が存在します。これは、0という値が計算上の「不動点」となるためです。
このルーチンの計算プロセスを追うと、その理由が明確になります。
RNG状態を格納する4バイトのメモリ($7E584A~$7E584D)が全て0だった場合、レジスタに0をロードし、シフトやEOR(排他的論理和)で計算しても、0と0の計算結果は常に0です。内部状態をシフトさせる処理も、0を別の0のメモリ位置にコピーするだけで、状態に変化は生まれません。最終的に、新しく生成されるフィードバック値も0となり、RNG状態は0x00000000のまま全く更新されなくなります。
ゲーム内でこの状態から自己回復するプログラムが存在しないため、結果として電源をリセットするまで乱数は完全に0で固定され続けます。
乱数が0で固定されると、ゲーム内のあらゆる確率的な事象が影響を受けます。
例えば、実際にダメージ計算などで使われる乱数値を取得するサブルーチンは、このRNG状態を元にさらに複雑な計算を行いますが、その入力値が常に0であるため、出力される結果(Aレジスタに返される値)も常に同じ特定の値になります。
これが、「会心の一撃が100%出る」「同じモンスターが出現する」といった、全ての確率的事象が固定化される直接的な原因です。
乱数固定のグリッチ手順は、まさにこのLFSRの数学的な弱点を突き、解析によって特定された精密な操作シーケンスを実行することで、RNGの内部状態を意図的に、そして強制的にこのオールゼロ状態へと導くテクニックなのです。
NPCの移動方向と乱数の関係
町やダンジョンでランダムに歩き回るNPCは、その次の移動方向を決定するために、乱数を利用します。そのプロセスは、専用のサブルーチン($C6:CC44~)によって、以下の手順で実行されます。
1. 乱数の生成
まず、キャラクターが次に行うべき行動を決定するために、メインのLFSR更新ルーチン($C0:0ECC~)が呼び出されます。このルーチン内で現在のRNG状態を元にした、新しい乱数値が生成されます。キャラの移動は高品質な乱数は必要としないため、高品質8ビット乱数取得ルーチン($C0:0EF5~)は呼び出されません。
2. 4方向への変換
次に、生成された乱数値を、キャラクターが移動できる「上・下・左・右」の4方向に変換する必要があります。そこでAND #$0003という命令を実行します。AND演算により、乱数値の下位2ビットだけが取り出され、それ以外のビットは全て0になります。下位2ビットで表現できる数値は00(0), 01(1), 10(2), 11(3)の4パターンしかないため、どんな乱数値が生成されても、結果は必ず0, 1, 2, 3のいずれかの値に丸め込まれます。
3. 移動方向の決定
この0, 1, 2, 3という4つの数値が、それぞれ「上・下・右・左」の各移動方向に対応付けられています。解析の結果、その対応は以下のようになっていることが判明しました。
「0 = 上」
「1 = 右」
「2 = 下」
「3 = 左」
例えば、LFSRルーチンが生成した乱数の下位2ビットが10であれば、NPCは「下」に移動しようとします。乱数固定グリッチによってLFSRルーチンが常に0しか返さなくなると、この変換結果も常に0になります。その結果、NPCは「上」にしか移動できなくなるという現象が起こるのです。
SFC版『ドラゴンクエストVI』乱数固定のメカニズム
この裏技は、単なる偶然の産物ではありません。本記事で解説してきたSFC版『ドラゴンクエストVI』の乱数システムの仕様と、その根幹にあるアルゴリズムの脆弱性を巧みに利用し、RNG状態(乱数生成器の内部状態)を意図的に制御する、極めてロジカルなプロセスです。
では、なぜ乱数という不確定な要素を、完全に固定することが可能なのでしょうか。そのメカニズムは、大きく分けて以下の3つのステップで成立します。
ステップ1:初期化と調整(Initialization & Adjustment)
SFC本体の特殊機能と精密な操作によって、ゲーム開始時のRNG状態とその後の経過時間を完全に固定化します。これは、猛烈な速度で流れ続ける乱数の川の中から、目的のポイントに正確に着地するための、緻密な準備段階です。
ステップ2:実行(Execution)
NPCの思考ルーチンを利用して、メインのLFSR(重量更新)ルーチンを任意のタイミングで呼び出します。これは、解析によって特定された「振り付け」通りにRNG状態を遷移させ、最終目標である臨界点へと導く、このグリッチの核心部分です。
ステップ3:固定化と「ゼロ状態への陥落」(Solidification & Zero State Collapse)
臨界点に達したRNG状態は、LFSRアルゴリズムが持つ数学的な弱点により、回復不可能なオールゼロ状態へと陥ります。一度この状態になると、乱数生成器は永久に機能不全となり、全ての確率的事象が固定化されるのです。
これから、この裏技の全手順の一つ一つが、上記のステップにおいてどのような意味を持つのかを分解し、考えていきましょう。
※本稿のメカニズム解説は、発見者である「かくれみ」氏へ直接伺ったものではなく、あくまで解析・検証の上で筆者個人の見解に基づくものです。
その1:パーティーを1人にして、特定の場所でセーブする
この最初の準備段階は、後続の操作の「再現性」と「コントロール性」を極限まで高めるための、極めて重要な下準備です。
パーティーを1人にする理由としては、「後続の仲間キャラクターによる、意図しないNPCの移動妨害を防ぐ」ためです。本作では、プレイヤーの後ろをついてくる仲間キャラクターも、NPCの移動をブロックする物理的な障害物として扱われます。これからプレイヤー自身の操作でNPCの動きを精密にコントロールしようとする際に、仲間の存在が予期せぬ変数となってしまうのを避けるため、操作キャラクターを1人にするのです。
次に、特定の場所(サンマリーノ、ダーマ神殿の教会)でセーブする理由。この技が成功する場所には、以下の共通点があります。
- ゲーム再開地点(神父の前)のすぐ近くに、制御のターゲットとなるNPC(サンマリーノのシスター、ダーマ神殿の占いババ)がいること。
- 制御のターゲットとなるNPC以外に、ランダムに動き回る他のNPCがいないこと。
この技の核心は、特定のNPCの移動判定を利用して、LFSRルーチンを任意のタイミングで呼び出すことにあります。もし周囲に他のランダムなNPCが複数いれば、その動きによって予期せぬタイミングでLFSRルーチンが呼び出されてしまい、プレイヤーによる精密なRNG状態のコントロールが不可能になります。特定の場所でセーブし、再開時のキャラクター座標、マップ情報、そして制御すべきNPCが1人だけの単純な環境を完全に固定することで、後続の操作が毎回同じ条件下で実行されることを保証しているのです。
その2:Aボタンを押しながら電源をいれる
この操作は、単にゲームを起動する以上の、「再現性の確保」という極めて重要な目的を持っています。それは、「冒険の書をロードし終えた瞬間のRNG状態を、毎回寸分違わず同じにする」ための、機械的なタイマーとして機能します。
まず、電源を投入すると、ゲームの初期化ルーチンが実行され、RNG状態は固定の初期シード0xAAE21259に設定されます。乱数列のスタート地点は毎回同じです。
この初期化が終わった瞬間から、ゲームの心臓部であるNMI(ノンマスカブル割り込み)ハンドラが、1フレーム(約1/60秒)に1回、RNG状態をROL(ローテート)命令で更新し続けます。これは、プレイヤーが何も操作していなくても、猛烈な速度で流れ続ける「時間の川」のようなものです。普通にプレイする場合、電源を入れてから「ぼうけんのしょ」を選択し、ロードが完了するまでの時間は、プレイヤーの操作によって毎回微妙に異なります。その数フレームのズレが、ロード完了時点でのRNG状態を毎回違うものにしてしまいます。
ここで「Aボタンを押しながら電源を入れる」という操作が役割を果たします。Aボタンを押しっぱなしにすることで、タイトル画面から「ぼうけんのしょ」が自動的に選ばれ、データがロードされるまでの一連のプロセスが、人間の曖昧な操作を介さず、完全に機械的になります。これにより、「電源投入からロード完了まで」にかかる総フレーム数が、毎回寸分違わず固定されます。
総フレーム数が固定されるということは、その間に実行されるNMI割り込みの回数、すなわちROL命令によるRNG状態の更新回数も、毎回完全に同じになるということです。
結果として、毎回同じ初期シード0xAAE21259からスタートし、毎回同じ回数だけ更新された、ロード完了時点でのRNG状態が完璧に再現されるのです。Aボタン押しっぱなしは、流れ続ける川の、特定の瞬間の水(RNG状態)を正確に汲み出すための、精密なタイマーそのものなのです。
その3:Bボタン連打とシスターの動きでパターン判定
「Aボタン長押し」によって、ロード完了時点でのRNG状態はほぼ固定されました。ここからの操作は、その状態が本当に「当たり」であるかを見極め、次のステップに進むための「最終確認」と「選別」のフェーズです。
Bボタンを連打する理由
ロードが完了すると、目の前の神父がメッセージを表示します。このBボタン連打は、このメッセージウィンドウを可能な限り速く、かつ毎回同じようなフレーム数で閉じるための操作です。もたもたしていると、その間にもNMIによるROL更新でRNG状態が変化してしまいます。すぐに次の行動(シスターの観察)に移るため、最速でメッセージを送り、ウィンドウを閉じる必要があるのです。
シスターの動きが「答え」である理由
ウィンドウが閉じた瞬間、プレイヤーはすぐに行動可能になります。この時点でのRNG状態が、このグリッチの成否を分ける最初の関門です。
サンマリーノの教会にいるシスター(あるいはダーマ神殿の占いババ)は、プレイヤーが何もしなければ、NMIのROLで変化していくRNG状態を元に、自身の移動方向を決定します。つまり、シスターの動きは、現在のRNG状態を映し出す「鏡」そのものです。
「当たりパターン」の判定
「このRNG状態から始めれば、後の手順で0x80000000に到達できる」という、いくつかの「当たり」の初期状態が発見されているので、その「当たり」の状態でシスターがどのような動きをするか(例:最初に右に移動、次に下へ2歩動くなど)をパターン化しています。プレイヤーは、ロード直後のシスターの動きを観察し、それが既知の「当たりパターン」と一致するかどうかを「答え合わせ」します。
リトライの必要性
「Aボタン長押し」と「Bボタン連打」という操作は、フレーム数をかなり高い精度で固定できますが、それでもSFC本体の個体差や僅かなタイミングのズレにより、1~2フレームの誤差が生じることがあります。そのわずかなズレが、ロード完了時のRNG状態を「当たり」から「ハズレ」に変えてしまいます。もしシスターの動きが「ハズレパターン」だった場合は、この誤差が原因であるため、再度電源を入れ直して手順をやり直します。数回リトライすれば、偶然タイミングが一致し、目的の「当たりパターン」を引き当てることができるのです。
その4:NPCを妨害し、特定操作を実行する
「当たりパターン」を確認した後、いよいよこのグリッチの核心である「RNG状態の精密操作」のフェーズに入ります。この場面、何も知らない人から見れば、特定のNPCにつきまとっている不審な行動にしか見えませんが、これは解析によって定められたシーケンス通りにRNG状態を操作し、最終目標である臨界点0x80000000へと導くための、極めてロジカルなプロセスです。
この操作を理解する鍵は、「ランダムに動くNPCの思考ルーチンが、メインのLFSR(重量更新)ルーチンを呼び出すトリガーになっている」という点にあります。
(※まったく動かないNPCと、決められた動作を繰り返すNPCはランダムには動かないので乱数は消費しません。)
NPCは、次の移動方向を決定する際にLFSRルーチンを呼び出し、乱数を消費します。つまり、NPCが動くたびに、RNG状態はNMIによるROL(軽量撹拌)とは異なる、複雑な計算によって大きく変化するのです。
NPCへの「妨害」を巧みに利用して、乱数消費のパターンをコントロールします。「妨害」が持つ2つの重要な意味としては
乱数消費のタイミング制御
解析によって定められた「振り付け」の多くは、妨害を行わず、NPCを自由に歩かせます。これにより、NPCが自身の自然な思考サイクルでLFSRルーチンを呼び出すのを待ち、RNG状態を通常通り進行させます。
乱数消費パターンの変化と加速
そして、「振り付け」が指定する特定のタイミングで、プレイヤーはNPCの移動を正確にブロック(妨害)します。
デバッグログの比較分析から、この「妨害」という行為は、単にNPCの動きを止めるだけではないことが判明しました。移動に失敗したNPCは、「移動できるまで、より短い間隔で再試行する」という思考ルーチンに入ります。その結果、LFSRルーチンが通常よりも高い頻度(約2倍の速さ)で呼び出されるのです。
この「移動しようとしたが、できなかった」という特殊な状況を引き起こすことで、RNG状態の遷移パターンを意図的に変化させ、かつその進行を加速させています。
この一連の操作は、「自然進行」と「妨害による加速」という2つの異なる乱数消費パターンを使い分け、RNG状態を1ビットずつ、最終目標へと彫り上げていく精密な作業です。
この操作を完遂し、RNG状態が臨界点0x80000000に到達すると、LFSRアルゴリズムの数学的弱点である「ゼロ状態への陥落」が引き起こされ、乱数システムは完全に固定化されるというわけです。
その成功は、NPCが上しか向かなくなるなど、その行動が単一のパターンに固定されることで、視覚的に確認することができるのです
零行列への数式
この「乱数固定」現象は、単なる偶然やゲームのバグではなく、実は数学的な理論に基づいて意図的に引き起こすことが可能な、再現性のあるものです。
発見者のかくれみ氏は、自身のX(旧Twitter)のポストで、「線形代数」の行列理論を用いた数式を公開しています。
「乱数を1回消費し、n(+32k)フレーム経過させる」に対応する行列をA_n(∈F_2^{32×32})とし、便宜上B:=(A_8)^12とすると、
(B × A_4 × B × A_14 × B × A_4)^3 × B
は零行列になりますので、上記を実現できるコマンド操作があれば、操作開始時の乱数値に依存することなく乱数値を0にできるはずです。
— かくれみ (@_kakuremi) February 19, 2023
この数式が示しているのは、一言でいえば「どんな初期状態から始めても、必ず『0』というゴールにたどり着く操作手順が存在する」ということです。
これから、この数式が持つ意味を、専門的な知識がなくても理解できるように、分かりやすく解説していきます。
1. 「乱数を1回消費し、n(+32k)フレーム経過させる」に対応する行列をA_n
「乱数を1回消費し」:これは、プレイヤーの操作によってLFSRルーチンを1回呼び出すことに対応します。この操作の遷移行列を A_lfsr としましょう。
「n(+32k)フレーム経過させる」:これは、その後 nフレーム間、NMIによるROL更新だけが行われることに対応します。この操作の遷移行列は (A_rol)^n となります。(+32kは、ROLが32回で1周するため、実質的に同じ状態になることを示唆しています)
行列 A_n:したがって、発見者が定義した行列 A_n は、これら2つの操作を組み合わせたものです。
「A_n = (A_rol)^n * A_lfsr」
これは、「LFSRを1回実行し、その後nフレーム待つ」という一連の操作を表す遷移行列です。
2. 便宜上B:=(A_8)^12
A_8: 上記の定義より、A_8 = (A_rol)^8 * A_lfsr です。これは「LFSRを1回実行し、8フレーム待つ」という操作の行列です。
B := (A_8)^12: Bという行列は、この「LFSR→8フレーム待ち」という操作を12回繰り返すことに対応する、巨大な遷移行列です。
B = ( (A_rol)^8 * A_lfsr )^12
3. (B × A_4 × B × A_14 × B × A_4)^3 × Bは零行列
これが、このグリッチの核心にして、最終的な「魔法の呪文」です。この数式が、あの28秒間の複雑な操作シーケンスの、数学的な設計図そのものです。
この式を M と置くと、
M = (B * A_4 * B * A_14 * B * A_4)^3 * B
この操作シーケンスを日本語で分かりやすく言うと、以下のようになります。
- 「LFSR→8F待ち」を12回繰り返す (これが操作B)
- 「LFSR→4F待ち」を1回行う (これが操作A_4)
- 「LFSR→8F待ち」を12回繰り返す (操作B)
- 「LFSR→14F待ち」を1回行う (操作A_14)
- 「LFSR→8F待ち」を12回繰り返す (操作B)
- 「LFSR→4F待ち」を1回行う (操作A_4)
- 上記 (1)~(6) の全シーケンスを、3回繰り返す
- 最後に、「LFSR→8F待ち」を12回繰り返す (操作B)
この、人間業とは思えないほど長く複雑な手順を正確に実行できれば、その操作全体に対応する遷移行列 M はゼロ行列となります。
したがって、どんな初期RNG状態ベクトル v_initial から始めても、
「v_final = M * v_initial = 0 * v_initial = 0」
となり、RNG状態は必ずオールゼロ 0x00000000 に収束します。
もしもLFSRの脆弱性を修正するなら:問題解決案
これまで説明してきたように、本作で採用されているLFSR(線形帰還シフトレジスタ)には、その計算アルゴリズムに起因する致命的な弱点があります。一度でも内部状態がすべて0になってしまうと、その後の計算結果も常に0となり、二度と他の値を生成できなくなるのです。
この「ゼロ状態への陥落」という脆弱性を修正するための方法としては、以下のような2つのアプローチが考えられます。
解決策1:フレームカウンターの値を注入する方法
1つ目の解決策は、ゲーム内で常に変動している値を、乱数生成処理に混ぜ込むという手法です。具体的には、NMI割り込みのたびにインクリメント(増加)されているフレームカウンター($5966)の値を利用します。
この手法が効果的な理由は、システムに内部的な変動要素を注入できるからです。フレームカウンターは1フレームごとに必ず値が変わるため、仮にRNG状態が0に陥ってしまっても、この変動する値を計算に混ぜ込む(例:ADC命令で加算する)ことで、強制的に0以外の値を作り出し、ゼロ状態から脱出させることができます。
実装例:
元のEOR計算の後に、$5966の値をADC(キャリー付き加算)命令で加算する、といった1行を追加するだけで実現できます。(実際にはプログラムをそのままインサートできないため、JMP命令などによる迂回が必要)
メリット:
ハードウェアに依存しないため、処理落ちなどの副作用の心配がなく、非常に安定する。実装が容易で、ロジックも明快。
デメリット:
乱数自体の予測困難性(エントロピー)を劇的に向上させる効果はありません。あくまでゼロ状態からの脱出を主目的とした対策です。フレームカウンターの変動は完全に予測可能であるため、時間経過が新たな乱数調整の手段となってしまう可能性があります。
解決策2:ゼロチェックと初期シードによる再初期化
2つ目の解決策は、LFSRの「オールゼロ」という既知の弱点に対し、真正面から対策を講じる、非常に堅実で安全な手法です。
この方法では、乱数生成ルーチンの開始時に「現在のRNG状態が0x00000000かどうか」をチェックします。もしそうであれば、RNG状態を、ゲーム起動時に設定される初期シード0xAAE21259に強制的に書き込むようにします。これにより、ゼロ状態に陥っても次のフレームでは必ず正常な状態に回復させることができます。
実装例:
まず$584A(下位16ビット)と$584C(上位16ビット)をORA(論理和)命令で比較し、結果が0でなければ通常処理に進みます。もしオールゼロだった場合は、初期シード0xAAE21259をRNG状態に再設定する処理に分岐させます。ORA命令は、全てのビットが0の時だけ結果が0になるため、効率的にゼロチェックを行えます。
メリット:
ロジックが単純明快で、バグを生む可能性が極めて低いです。ゲーム全体の乱数の挙動を変えることなく、問題点であるゼロ状態だけをピンポイントで修正できます。
デメリット:
この対策は「オールゼロ」状態のみに対処するものです。もし他の短いサイクル(ループ)に陥る問題があった場合、それには対処できないという限界があります。
乱数固定をチートで実現する方法
RTAでチートを使うのはご法度ですが、それ以外で、乱数が固定されるとどんな感じになるのか見てみたい。でも方法が難しくてできないという方のためにコードを掲載します。この乱数固定は、チートコードによって簡単に、そして確実に再現することが可能です。
方法1:乱数RAMアドレスの値を「0」にする
最も直接的な方法です。改造ツールやエミュレーター、レトロフリークのコード機能を使い、$7E584A~$7E584Dの4バイトの値を$00に書き換えることで、乱数は即座に0で固定されます。
※どれか1つでも乱数を「0」にすると、すぐにオールゼロへと遷移します。
方法2:初期シードの即値を変更する
$C0:00F6にある LDA #$59 を LDA #$00 に変更 →「C000F700」
$C0:00FCにある LDA #$12 を LDA #$00 に変更 →「C000FD00」
$C0:0102にある LDA #$E2 を LDA #$00 に変更 →「C0010300」
$C0:0108にある LDA #$AA を LDA #$00 に変更 →「C0010900」
元々設定されていたシード値を 0x00000000 に変更することで、RNGの値はそのまま 0x00000000 に留まるようになります。ただし、ゲーム起動時にしか有効になりません。
方法3:フィードバック値を計算するロジックを破壊する
以下のように乱数生成プログラムコード自体を書き換える方法もあります。
$00:0EAAにある AND #$FF00 を AND #$0000 に変更 →「C00EAC00」
このプロセスの心臓部であるフィードバックループを直接断ち切ることで、フィードバック値は常に0になります。結果、乱数生成ルーチンが最大4回呼び出される間に、RNG状態は自然にオールゼロ0x00000000へと収束し、以降乱数は固定されます。
AND #$FF00 とはどういう意味か?
命令 AND #$FF00 は、アキュムレータ(Aレジスタ)に格納されている値と $FF00 という定数との間で ビット単位の論理積(AND演算) を行う命令です。この命令の目的は、Aレジスタの上位バイトを残し、下位バイトを消去(ゼロに)すること です。たとえば、Aレジスタが 「$1234」 の場合に AND #$FF00 を実行すると、結果は 「$1200」 になります。これは、AND演算が「両方のビットが 1 の場合だけ 1、それ以外は 0」というルールに基づいているためです。$FF00 というマスク値は「上位8ビットがすべて1、下位8ビットがすべて0」で構成されているので、上位バイトはそのまま残り、下位バイトはすべて0になるという結果になります。
AND #$0000 にすると結果が 0 になる理由
一方、AND #$0000 を実行すると、Aレジスタの値が何であっても結果は常に 「$0000」 になります。理由は単純で、$0000 という値は すべてのビットが0 だからです。AND演算では、どんなビットに対しても 0 AND ビット = 0 になるため、全体が 0 に「マスク」されてしまいます。つまり、Aレジスタの内容が $1234 でも $FFFF でも、AND #$0000 を実行すれば結果は必ず $0000 になります。
乱数固定状態でのはぐれメタル狩り
ここでは、乱数固定を利用して「はぐれメタル」を確実に倒すための準備手順を解説します。レベル上げや、はぐメタの勧誘に役立つでしょう。
乱数固定状態では、下の世界のザクソンの村周辺で「はぐれメタル2匹」のエンカウントが確定します。戦闘が始まると、はぐれメタルは必ず「おどろきとまどう」ため、こちらの先制攻撃が可能です。
しかし、通常の攻撃は100%回避されてしまいます。これを突破するには、まず1ターン目に「きあいため」を使い、次のターンに攻撃することで「会心の一撃」を確定させる必要があります。
ところが、ここに大きな壁が出てきます。はぐれメタルの行動IDは「にげる」に固定されるため、2ターン目では、はぐれメタルよりも早く行動しなければ倒せません。
この問題を解決するには、キャラクターの「すばやさ」を限界まで高める必要があります。そのために不可欠なのが「すばやさのたね」によるドーピングです。
<すばやさのたねを効率的に集める方法>
幸い、乱数固定中はモンスターのアイテムドロップ率が100%になります。これを利用して「すばやさのたね」を大量に集めましょう。
SFC版「ドラゴンクエストVI」において「すばやさのたね」がドロップアイテムとして設定されているモンスターは
- ひとくいばこ(1/256)
- スカルガルー(1/256)
- マドハンド(1/256)
- ブチュチュンパ(1/256)
- ガマニアン(1/256)
- しれんその1(1/64)
となっています。()内は職業補正なしの通常ドロップ率。
色々調べましたが、この中で普通に雑魚敵として出会えるモンスターは「ブチュチュンパ」のみです。
ブチュチュンパは、はざまの世界にある「古い炭鉱」と「湖の穴」で出現するのですが、古い炭鉱ではメガザルロック2体固定となるため、入手不可能です。
湖の穴であれば、エンカウントが「ブチュチュンパ2匹」に固定されます。
この場所で戦闘を繰り返せば、確実に「すばやさのたね」を集めることができます。
もちろん「あなほり」でもOKです。戦闘しなくてよいのでこちらのほうが時間かかりませんね。(1つのエリアで入手できるのは5回までなので、マップの切り替えをしてください)
必要な数が集まったら、はぐれメタルを狩りたいキャラクターのすばやさを500にカンストさせ、万全の態勢でザクソンの村周辺へ向かいましょう。ほしふるうでわを装備して底上げするのも効果的です。
※通常であれば無職でのすばやさ上昇量は1~3であるが、乱数が最小値で固定されてるので上がる値は「1」だけです。
<あなほりで他のたね・きのみが手に入る場所>
ちからのたね・・・モンストル周辺
まもりのたね・・・フォーン城周辺
かしこさのたね・・・ホルストック周辺
うつくしそう・・・ペスカニ周辺、ロンガデセオ周辺
いのちのきのみ・・・レイドックの井戸
ふしぎなきのみ・・・マウントスノー周辺、不思議な洞窟
<あなほり以外で他のたね・きのみが手に入る場所>
いのちのきのみ・・・オンディーナが落とす(下の世界・外海)
DQ6乱数固定バグに関連する動画紹介
投稿日:2013/06/09
SFCドラクエ6 電源つけっぱで乱数崩壊
投稿日:2023/07/26
SFC版ドラクエ6 幻のモンスターキクモトを仲間にし裏ボスダークドレアムを全マスターでぶっ倒す そして謎のバグでアイテム取り放題?
配信日:2023/10/23
【ドラクエ6バグ回】#36 急遽バグ検証回!確定レアアイテムに無限カジノに超展開【おしゃべり実況】【#レトロゲーム】【#ドラクエ】【VTuber のぺるにくす】
投稿日:2025/01/25
【DQ6】スーファミ実機を744時間電源つけっぱなしでただ放置する幻の都市伝説を知っていますか?会心率100%&味方無敵状態&ドロップ率100%の都市伝説に挑戦!
https://youtu.be/fkQOg9J0a34
投稿日:2025/02/08
【ドラクエ6】乱数が固定された世界が素晴らしかった・・・【VOICEROID実況】
投稿日:2025/03/22
新発見のこの裏ワザ知ってましたか?・・・名作ゲーム解説発売から数年数十年たって発見された事第2弾!PS1スーパーファミコン名作ソフトなど
「電源を入れっぱなしで放置」しても発生するこの現象について
これまでDQ6の乱数生成プログラムの解説と乱数固定技のメカニズムなどについて説明してきました。
正規の手順とは別に、本作では「SFCの電源を入れっぱなしで長時間放置(プレイ)する」ことでも、意図せず乱数が固定される現象が報告されていますね。
これは正規手順とは異なるメカニズムですが、最終的に乱数が0に固定されるという点では、結果的に同様の事象が発生していると考えられます。
発生までの放置時間は、数時間から数週間と幅広いので「特定のカセットや本体で起きやすいという個体差」や、「ハードウェアの熱暴走」が直接の原因である可能性は低いでしょう。本質は、ソフトウェアの挙動にあります。
では、どのような状況下でこの偶発的な乱数固定が発生しやすいのでしょうか。鍵となるのは、メインのLFSR(重量更新)ルーチンがどれだけ頻繁に呼び出されるかです。
発生しやすい状況
1.戦闘を何度も繰り返す
戦闘は、敵の行動決定やダメージ計算などで、LFSRルーチンが最も集中的に呼び出される場面です。呼び出し回数が多ければ多いほど、RNG状態が計算の過程で、偶然「ゼロ状態への陥落」を引き起こす特殊な値になる確率も僅かながら上昇します。実際に、アークボルトの兵士戦やデュラン戦、ブラッディハンドの増殖レベル上げ中といった長時間の戦闘中にこの現象に遭遇したという報告は、この仮説を強く裏付けています。期待値が高いです。
2.ランダムに動くNPCがいるマップで放置する
サンマリーノのシスターのように、自律的に動き回るNPCがいるマップも、この現象の発生確率を高める要因です。NPCは次の移動方向を決定する際に、LFSRルーチンを呼び出します。そのため、このようなマップで長時間放置することは、断続的にLFSRルーチンを呼び出し続けることになり、結果としてゼロ状態への陥落を誘発する可能性があるのです。
発生しにくい状況
一方で、フィールドマップ上で放置しているだけでは、この現象はまず発生しないでしょう。フィールド上で何もしないときには、乱数を消費する処理は行われないからです。
この時、RNG状態を更新しているのは、1フレームに1回実行されるNMI割り込みによるROL(軽量撹拌)命令だけです。ROLは32ビットの値を回転させるだけで、立っているビットの総数を変えられません。
本作の初期シード0xAAE21259には1のビットが14個ありますが、ゼロ状態への陥落の臨界点である0x80000000には1のビットが1個しかありません。ROLだけを繰り返しても、14個の1が1個に減ることは数学的に不可能なのです。これは検証済み。
結論として、放置による偶発的な乱数固定は、ハードウェアの不調ではなく、LFSRルーチンが頻繁に呼び出される状況下で、RNG状態が計算の過程で偶然、ゼロ状態へと陥落してしまうソフトウェア上の事象です。フィールドのような静的な場所ではなく、戦闘中やNPCが動き回るマップといった、より動的な環境こそが、この奇跡的な現象の舞台となり得るのでしょう。
まとめ
SFC版『ドラゴンクエストVI』の乱数固定。
本稿で解き明かしてきたように、この現象の正体は、LFSR(線形帰還シフトレジスタ)という疑似乱数生成アルゴリズムが持つ「ゼロ状態への陥落」という数学的な弱点を人為的に引き起こす、極めて高度なグリッチでした。
「SFC本体の特殊な起動方法で開始時点でのRNGを同一化し、セーブデータを読み込ませた直後、極めてシビアなタイミングで乱数消費操作を行うことで、ゲームの乱数生成プログラムを破壊し、常に同じ数値を返し続ける状態に陥らせる」
という、まさにゲームの物理法則を掌握した上で行われる、再現可能な「アート」と呼ぶべきものでした。
これは、現代のゲームでは考えられないほど内部構造が制御可能であった、SFC時代のゲームならではの貴重な事例です。開発者が全く意図しなかったであろうプログラムの隙間を、驚異的な探求心と洞察力を駆使して突き止め、乱数という不確定の象徴を完全に制御下に置くという、人とプログラムのせめぎ合いの頂点を示しています。
このSFC版『ドラゴンクエストVI』の乱数固定は、もはや幻のバグではありません。それは、RTA走者を始めとする多くのプレイヤーたちが、情熱と知性をもってゲームの深淵に挑み続けた努力の結晶です。本稿で解説したメカニズムの解明も、その緻密な先行研究と情報提供があってこそ可能となりました。
この驚くべき現象を発見し、その複雑な手順を確立し、そしてその知識を共有してくださった全ての先人たちに、心からの敬意と最大限のリスペクトを捧げます。ありがとうございました。
このページで利用している株式会社スクウェア・エニックスを代表とする共同著作者が権利を所有する画像の転載・配布は禁止いたします。
(C) ARMOR PROJECT/BIRD STUDIO/SQUARE ENIX All Rights Reserved.
おすすめ記事
コメント
この記事へのトラックバックはありません。
この記事へのコメントはありません。