サイファーの日記

過去作の乱数について書きます

MHXXのお守りスナイプ(マカ錬金の乱数調整)

 

1. はじめに

ここではモンスターハンターダブルクロスの乱数アルゴリズムや、マカ錬金でお守りのスキル内容を乱数調整する手順を紹介します。

2月のセールでMHXXのSwitchバージョンが格安になっていたので、購入するついでに3DS版で乱数生成も調べてみました。

2. MHXXの乱数生成

MHXXおよびMHXでは乱数の生成にXorshiftのようなものが使われているようです。前作まで*1とは全く異なります。CAPCOMの乱数調整対策なんだろうか。

ただしゲーム起動時の初期seedが全く同じなので、乱数調整は現実的に可能。

厳選的な観点では、HOME画面からの再起動を繰り返して錬金すると同じお守りを生成してしまう確率が高くなります。

 
//3DS版とSwitch版共にホームから起動するとこの値で初期化(らしい)
static uint a = 0x194FD72;
static uint b = 0x79E6C985;
static uint c = 0x8DD9701;
static uint d = 0x41CFCE91;

static uint Next()
  {
      uint t = a ^ (a << 15);
      t ^= t >> 4;
      t ^= d ^ (d >> 21);
 a = b;
      b = c;
      c = d;
    d = t;
return t;
}


3. お守りの生成方法

ここではお守りのスキルの生成方法について説明します。

謎のお守りの場合、「乱数値 % スキル1の種類」がスキルの種類になります。スキル1の種類は謎のお守りなら59

スキルポイントは更に1消費して「乱数値 % (最大値 - 最小値 + 1) + 最小値」で決定されます。

スロット数や上位以降のお守りの生成方法は未確認ですが、おそらく過去作と同様の方法だと思われます。後日追記する予定。追記した

4. マカ錬金のお守り

マカ錬金の乱数は、ゲームを起動してからお守りを複数投入して確定した瞬間までの時間を制御します。具体的にはマカ錬金で「龍歴員ポイントを◯◯ポイント支払います。よろしいですか?」の画面で「はい」を選択した瞬間です。場所はベルナ村でOK。

ただし、セーブファイルを選択した直後に不定消費(猫飯スキル決定時の再計算のためか消費数が毎回一定でない)が存在します。選択した瞬間のフレームが同じなら実質的な影響はありません。

そのため、①起動してからセーブファイルを選択するまで②セーブファイルを選択してからお守りを投入するまでの時間を共に合わせることが安定につながります。1つのタイマーだけでは割とズレます。

前者のフレームが一致しているかどうかは、ハンターの動きのパターンや起動直後の猫飯の内容である程度分かります。
(訂正:2026/3/3)不定消費の発生はセーブファイルではなく、continueを選択したタイミングかもしれません。少なくとも、どちらのタイミングも合わせれば安定するのは確かです。


この画面での動きのパターンを見る

ちなみに、30fpsとはいえ手動かつセーブファイル選択を適当に行うとズレが酷かったです。また、3DSや旧SwitchではズレやすいかもしれないのでSwitch2で行った方がいいかも。

今回はSwitch2をArduinoで自動化して3001F, 0x5A59FF6Fの「耐暑+10」を狙い、数回の挑戦でゲットできました。

自動化する場合は、1Fズレたらプログラムの最後の待機時間を33ms程度変更して...というようにやっていけばいいです。

上述の仕様のため、手動でやる場合は必ず2連続でカウント可能な30fpsのタイマーを使ってください。CCTimerとか。全体の待機時間は目標フレーム - 700くらいになるはず。

5. クエスト報酬のお守り

(追記:2026/3/8)
クエスト中に入手したお守りは、クエストクリア後に「鑑定する」を押した瞬間に内容が生成されます。生成処理がマカ錬金と異なるので同一フレームでも別のお守りになる。

クエスト中は様々な要因によって不規則に乱数が進みますが、その後表示されるクエスト報酬画面の内容や並びから現在フレームが特定可能です。それを利用すれば直後の鑑定タイミングを合わせるのも容易。実際の調整では報酬画面が表示された瞬間にCCTimerなどのカウントアップ式タイマーをスタートさせ、目標フレームから報酬の生成終了フレームを引いたものを待機時間にすればOK。

報酬は調査した結果、最初に乱数値%32を最大4回まで呼び出して追加報酬の数を決定していました。22未満なら追加。

次に(乱数値&0xFFFF)%100で通常および追加報酬の内容を続けて決定します。(乱数値&0xFFFF)%100の値は村下位の採取ツアー系なら0-19が謎の骨、20-39が釣りミミズ、40-64が生肉、65-84が砥石、85-89が力の成長餌、90-94が重の成長餌、95-99が速の成長餌に該当する。おそらくG級も同様。

6. 有識者の方からの追加情報

(追記:2026/3/2)
この記事を最初に公開した後、既に解析を完了されている有識者の方からご厚意で貴重な資料をいただくことができました。許可も貰えたので、そちらで得られた情報の一部を以下に掲載します。

(追記:2026/3/7)
有識者の方作成のツールが公開されたので、以下の文章を読むよりこちらを参考にしてください。

github.com


【MHXXの乱数の特徴】

初期乱数は「ホーム画面でゲームタイトルを選択した瞬間」に一定の値に設定されます。セーブデータや装備、3DSかSwitchか、本体時間などは一切関係なし。つまり、ゲーム起動からお守りを生成するまでのフレームが同じなら、誰でも同じお守りを入手できます。

クエストでお守りを入手したときの乱数の消費量は第2スキルの付与判定のなし/ありで4/7なのに対して、マカ錬金でお守りを入手したときの乱数の消費量は4/6です。ありの時の差分はマカ錬金では第2スキルの正負の判定をしないことに起因します。

これにより、マカ錬金とクエストで入手できるお守りのパターンには違いが生じます。報酬決定のアルゴリズムが分かれば、クエストの鑑定画面でもスナイプが可能になるかもしれません。今のところ不明。

【お守りの決定方法】

①第1スキルの種類の決定
乱数を一つ進める。乱数値を第1スキルの個数で割った余りに対応するIDを第1スキルとする。

②第1スキルのスキルポイントの決定
乱数を一つ進める。乱数値を第1スキルの(最大値 - 最小値 + 1)で割った余りに最小値を足したものを第1スキルのスキルポイントとする。

③第2スキルの有無の判定
乱数を一つ進める。風化したお守りの場合、乱数値を100で割った余りが15以上なら第2スキルを付与する。15未満なら第2スキルは付与せず⑦に飛ぶ。この値は古びたおまもりなら25、光るおまもりなら35、謎のお守りなら100になる。

④第2スキルの種類の決定
乱数を一つ進める。乱数値を第2スキルの個数で割った余りに対応するIDを第2スキルとする。マカ錬金の場合、ここから⑥に飛ぶ。

⑤第2スキルのスキルポイントの正負の決定
乱数を一つ進める。乱数値を2で割った余りが1なら、第2スキルの値は正となる。0なら、負となる。 

⑥第2スキルのスキルポイントの決定
乱数を一つ進める。ここでは条件により2パターンの分岐をする。

⑤で正と決定された or マカ錬金の場合】
乱数値を第2スキルの最大値で割った余りに1を足したものを第2スキルのスキルポイントとする。
⑤で負と決定された場合】
第2スキルの負の下限を-Aとする。乱数値を第2スキルの(A + 1)で割った余りからAを引いたものを第2スキルのスキルポイントとする。第1スキルと第2スキルが被った場合、もしくは第2スキルのスキルポイントが0となった場合、第2スキルは無いものとして扱われる。

⑦判定値の決定
乱数を一つ進める。乱数値を100で割った余りを「判定値」とする。

次に「充足値」を計算しておく。まず第1スキルの取りうる最大値をS1、第2スキルの取りうる最大値をS2、上で決定した第1スキルの値をT1、第2スキルの値をT2とする。ただしT2は第2スキルが無い場合や、第1スキルと第2スキルが被っている場合、もしくは第2スキルのスキルポイントが負の場合、強制的に0となる。そして、充足値をT1 ÷ S1 × 10 + T2 ÷ S2 × 10という式で計算する。厳密には、和を計算してから小数点以下を切り捨てたものが正確な充足値である。

この充足値をもとに、以下の配列を参照する。1〜20番目の要素は充足値に対応し、各要素は3つの数値から構成される。これらは左から順にスロット1・スロット2・スロット3の判定値を表す。

これでスロット数が決定される。例えば、充足値が17で判定値が92の風おまの場合、(79,91,98)に該当する。判定値が91以上98未満であるからスロット数は2と決定される。

風化したお守りの場合
(100,100,100),(3,53,88),(5,55,89),(7,57,89),(13,58,89),
(16,60,90),(22,62,90),(30,66,90),(38,68,91),(50,72,91),
(55,75,92),(59,77,92),(64,81,94),(67,83,94),(71,86,96),
(74,88,96),(79,91,98),(82,92,98),(86,94,99),(90,96,99)

古びたお守りの場合
(8,58,88),(9,59,88),(16,61,89),(17,62,89),(23,63,89),
(25,65,90),(31,66,90),(38,68,90),(45,71,91),(58,76,91),
(63,79,92),(66,80,92),(71,83,94),(74,84,94),(78,87,96),
(82,90,96),(86,93,98),(88,94,98),(91,96,99),(94,97,99)

光るお守りの場合
(2,72,100),(9,74,100),(16,76,100),(23,78,100),(30,80,100),
(37,82,100),(44,84,100),(51,86,100),(58,88,100),(75,90,100),
(83,92,100),(87,95,100),(90,97,100),(92,98,100),(94,99,100),
(95,99,100),(97,100,100),(98,100,100),(99,100,100),(99,100,100)

謎のお守りの場合
(55,100,100),(60,100,100),(65,100,100),(70,100,100),(75,100,100),
(80,100,100),(85,100,100),(90,100,100),(95,100,100),(99,100,100),
(100,100,100),(100,100,100),(100,100,100),(100,100,100),(100,100,100),
(100,100,100),(100,100,100),(100,100,100),(100,100,100),(100,100,100)

 

ここまでの過程を経て1つのお守りの内容が決定します。次のお守りが残っている場合、そのまま再度①から次のお守りを決定します。


※「⑦判定値の決定」の補足

充足値を計算する際、商がs/t、(s,tは整数、tは2の冪乗でない)、の形になり、その計算結果がちょうど割り切れて整数になった場合、3DSの計算誤差により、その整数より1小さい値が実際のゲームでの値になるかもしれません。50/6+60/9=14.999999999→14のようなイメージです。

過去作では、そのように充足値の計算が合わないパターンがあったそう。また、XXでもダメージ計算の場面などでその誤差が生じる例が確認されている。



↑ 以上が有識者の方から頂いた情報でした。

(参考)風おまの0~9F目までの並び
0F  我慢    5               スロット 0  3910EE3A
1F  護石    3               スロット 0  25E6E2EF
2F  回距    5               スロット 2  EA8E25B1
3F  根性    4  属耐    3  スロット 1  4661189D
4F  食事    3  泡沫    3  スロット 0  0C8C2A77
5F  抜減    3  剣術    3  スロット 0  5D545ED2
6F  回性    3  抜会    1  スロット 1  AA8793D2
7F  弾節    7  速射    3  スロット 0  6C0AF792
8F  重強    4  無心    3  スロット 2  74262422
9F  反動    2  剣術    7  スロット 0  0138ACBC

7. おわりに

ここまで読んでいただきありがとうございました。一般向けの計算ツールはいつか作るかもしれない。

発売から10年くらい経とうとしているゲームなので需要があるか分かりませんが、少しでも参考になれば嬉しいです。

8. 参考文献

・スキルのIDやスキルポイントの範囲の調査に便利。

お守りのスキルポイント | MHXX | Kiranico | モンスターハンターダブルクロス


・TASに関する記事ですが3DSの乱数調査の上でも参考になりました。

3DSのTAS制作 環境導入~TAS完成までのプロセス : さっぱりわからんブログ

・未開拓の乱数調整を調査する上で参考になる情報が載っています。

AIに新しい乱数調整ツールを作らせる① - TASはTASけあい

・過去作におけるお守りの生成方法の参考になるものがここでしか見つからなかった(変な広告がいっぱい出てきたので要注意)。

!ninjaテストスレ4

*1:P3から4GまではX_{n+1} = X_n * 176 % 65363という漸化式。