rusted-coil old blog

はてなダイアリー上で書かれていた旧東方錆恋録 ~Slipping Rusted Magnemite~のデータをそのままインポートしたブログです。リダイレクト先を変える前に気づいたらダイアリーがサービス終了していたので、とりあえずリンク切れを防ぐため公開しています。

サンムーン 孵化乱数調整についての現状

この記事は特にPokémon RNG Advent Calendar 2016の記事とかではないです。

サンムーンでも乱数調整(以前のような時計を合わせてどうこうではなく、XYのような孵化乱数列を固定して操作する形式)ができるらしいとのことでさっそく調べてみた。


どうやら今作ではXYのようにタマゴから生まれる個体を生成する孵化乱数がセーブされる。そして、タマゴを受け取っても数列自体は再計算されない。
現状では数列がリセットされる条件が見つかっていないため、冒頭でも言ったが本体の時間を合わせるタイプの乱数調整ではない。(タマゴを受け取った時に乱数列がリセットされた従来の作品と異なる。)
しかし、欲しい乱数列を手軽に生成できる訳ではないが、現在の数列さえ求めてしまえばそのデータで起こる結果を予測・調整することは可能ということ。

ここで問題となってくるのが、「どうやって現在の乱数列を特定するか」「どうやって目的の乱数位置を特定するか」「どうやって目的の乱数位置まで乱数を消費するか」の3点。

どうやって現在の乱数列を特定するか

今作の孵化乱数に使われているのはTinyMTというアルゴリズム。(ソフトの説明書に書いてあるライセンス表記から判明したとか…)
この具体的な内容はおだんぽよさんがまとめている。
ぽよのーと: SM孵化の乱数列生成アルゴリズムについて
そしてこれを元に、「乱数列の最下位bit127個からある時点でのState(乱数seed)を求める」という手法はさきさんの記事参照。
SM孵化乱数列を計算する : ただの雑記byさき
最下位bitというのは要するに2で割った余りのこと。
つまり127個の乱数の偶奇がわかればTinyMT Stateを逆算することができる
また、BW2などでは乱数の余りという値は直接個体値などには使われていなかったが、何故か今作では乱数の余りが直接個体値や遺伝箇所などの決定に使われるようになった

ということで、今作は生まれたポケモン個体値や遺伝箇所などから乱数の偶奇を判別できるようになっているため、乱数の使われ方を元に生まれた個体の結果から逆算することで「127個の乱数の偶奇を求める」ことが"理論上"可能になっている。
具体的に生まれた個体から手作業で乱数列を逆算する方法は次の記事で紹介します(多分まだツールとかはないはず)。

どうやって目的の乱数位置を特定するか

タマゴから生まれた個体を生成するための乱数の使われ方はろいしんさんが詳しくまとめている。
SM孵化仕組み検証 - ろいしんぶろぐ
この仕組み通りに計算すれば、特定の乱数位置からタマゴを作った時に出来る個体はほぼ予測できると言っていいだろう。
あとは、目当ての条件になるように検索するツールがあれば目的の乱数位置は検索できる。
twitterでSnさんが上げているツールがあるようです(未検証)

どうやって目的の乱数位置まで乱数を消費するか

前述のろいしんさんの記事にあるように、タマゴの受け取りを拒否することで1、タマゴを受け取ることで使った乱数分消費できる
現状これ以外の消費方法は見つかっていない。

例えば調査が進んで色違いが500個先で生まれるのが検索できるようになったものの他の消費方法が見つかってないという状況になったら、、あかいいと持たせて大雑把に消費→受け取り拒否で微調整みたいにして目的の位置までもっていくことになるのかなあ。



以上が現時点で(日本語のサイトだけ)軽く調べてみた調査結果まとめになります。
多分現在の乱数列を特定するために127個の孵化乱数項を調べるところが一番時間かかるけど、孵化乱数列が再計算されないならセーブデータ消去しない限り一回求めたseed Stateは使いまわせるので、個人ゲノム解析みたいなものと思えばいいのかも。
調べておく価値はありそうなので、後でその辺りの記事を書く予定。(バンク解禁後に6Vとオール0個体持ってきてからの方が絶対楽だけど)