かけらの記録ノート

主にポケモンの乱数について語るブログ

ポケモンXDのフィールド消費についてのメモ

あらかじめ書いておきますが、完全に調査が済んだ訳ではないのでまだ一部が分かってません。それでもせっかくなので、供養として調べた結果についてメモ程度にまとめておきます。お盆近いですしね。

検証には欧州版XDを使用しました。また、消費のあるフィールドとして、トゲピーが貰える「町外れのスタンド」での消費を調べました。
フィールド上で消費を行っている部分のコードはこんな感じです。

from LCG import LCG

class State:
    def __init__(self, _0x8=None, _0xc=None):
        self._0x8 = _0x8
        self._0xc = _0xc

def InitState(state):
    for i, s in enumerate(state):
        if(i & 1 == 0):
            s._0x8 = 0.01
            s._0xc = 1
        else:
            s._0x8 = 0.5
            s._0xc = None

def NextState(seed):
    state = [State() for i in range(4)]
    InitState(state)
    RNG = LCG(seed)
    roll_const = 2
    roll = 0
    frame = 0
    while(True):
        for s in state:
            if(s._0xc is None):
                RNG.Advance(1)
                rand = (RNG.Seed >> 16) / 0x10000
                s._0xc = rand
            RNG.Advance(1)
            rand = (RNG.Seed >> 16) / 0x10000
            s._0xc = s._0x8 * rand + s._0xc
            if(s._0xc >= 1):
                RNG.Advance(1)
                s._0xc -= 1
        roll += 1
        if(roll == roll_const):
            # frame_advance()
            frame += 1
            roll_const = 2
            if(frame == 5):
                roll_const += 1
                frame = 0
            roll = 0
            yield RNG.Seed

乱数値を使用する場合に乱数値の商を使ってるのが特徴です。
そしてフィールドで消費をしている何らかのオブジェクトの内部状態を決定するのにこの乱数値の商を使用していて、毎フレームごとに2~3回、各オブジェクトに対して乱数値が使われます。
オブジェクトの内部状態を決定するのに過去の乱数値の情報も使用しているところがポイントです。ちなみに、このオブジェクトが何なのかはよくわかりませんでした。
実際にはこの処理に移る前にフィールドの読み込みのために22消費されます。

よく分かっていない部分についてですが、このフィールド消費を行っているオブジェクトの数についてです。
フィールド読み込み直後は上のコードの通り4で初期化されるのですが、フレームが進むにつれて増えたり減ったりします。
ゲーム開始時直後についてはある程度決まった幅で増減するっぽいことがわかったのですが、それ以降については完全にランダムに変動していることがわかりました。
これ以降については、モチベが消え去ったのと該当コードがうんち過ぎて読む気が起きなかったので、また今度調べます(遺言)。

ちなみに息抜きに日本コロシアムの方のフィールド消費についても調べてみましたが、ぱっと見た感じ同じような処理をしてるようでした。
これがわかればXDトゲピーと、あわよくばCoスイクンも楽になる可能性があります。

【おまけ】
ポケモンチャンネルでのタイトルが表示されるときの各オブジェクトの表示順序について。

TitleSequence = {"123":3124,"132":3142,
                 "213":2134,"231":2143,
                 "312":4132,"321":4123,
                 "0123":1324,"0132":1342,
                 "0213":1234,"0231":1243,
                 "0312":1432,"0321":1423}

def DisplayTitle(seed):
    RNG = LCG(seed)
    idxtmp = ""
    initflag = False
    while(True):
        idx = ((RNG.Advance(1) >> 16) * 4) >> 16
        idx = str(idx)
        if(not initflag):
            idxtmp += idx
            initflag = True
            continue
        if(idx != "0" and idx not in idxtmp):
            idxtmp += idx
            if(idxtmp[0] == "0"):
                if(len(idxtmp) == 4):
                    break
            elif(len(idxtmp) == 3):
                break
    return TitleSequence[idxtmp]

ちゃんと中身のコードを読んだわけではないですが、たぶん合ってます。
表示順序に関してですが、左上、右上、左下、右下の順で1、2、3、4という感じです。
例を挙げると、DisplayTitle関数の戻り値が3142の場合、左下、左上、右下、右上の順で表示されます。
「つづきから」→「はじめから」→「スペシャル」→「オプション」という感じです。
ゲーム起動直後は事前に1消費されてからタイトルが表示されます。

これを使えばジラーチの受け取りを使わずにシードを求められるので、とても楽になりますね!

【コロシアム乱数】ID調整とエーフィ・ブラッキーの乱数調整

【注意】この方法で欧州版のID調整はできません。(そもそもやる人いないと思うけど)
日本と北米版では問題なくできます。
やる気があればそのうち調べて機能を追加するかもしれないです。

ツールはうpろだからダウンロードできます。

6/11更新
IDの検索を高速化しました。

具体的なやり方は前のXDのID調整と同じなので割愛します。

こちらのツールでは初期シードから検索する場合は自動で不定消費を考慮して計算してくれるので、チェックを入れる必要はありません。

コマンド入力のタイミングについては、ここの画面から

f:id:sina_poke:20190607164622p:plain

ここまでです。

f:id:sina_poke:20190607164631p:plain

こちらもデフォルトネームでしか試してないので、任意TNでは各自検証してみてください。

・初期シード検索部分について

前に作った初期シード検索ツールのUIが適当すぎたので、ギンザルさんのツールを参考にして作り直しました。

f:id:sina_poke:20190607163839p:plain

使うに当たってデータベースを作成しておく必要があるので、前に上げた記事を参考にして作ってください。

以前に作成済みのものがあればそのまま使えます。その場合はDatabaseフォルダをそのまま移動させて、config.iniファイル内のシードの範囲を書き換えてください。

デフォルトでは0x0~0x1000までのデータベースファイルが入っています。

【日本XD】ID調整とイーブイの乱数調整

海外で仕組みが公開されていたので、乱数調整用に使いやすいようにツールを作りました。使うツールはいますぐバトル用のやつと一緒です。

・やり方について

1. いますぐバトルでシードを求める

前に上げた記事の通りです。

2. 目標個体の検索

「シードから検索」を選択して、検索したい消費数を入力します。そして、下にある「不定消費を考慮する」にチェックを入れて、計算をクリックします。

※再計算処理の関係でID、個体値のみで検索した場合の個体が出現しない可能性があります。単一のシードを狙う場合は一度シードから検索をして、出現するかどうか調べてから行うと確実です。

f:id:sina_poke:20190602155726p:plain

ここで出る消費数は、一般的な消費数ではなく、待機時間(Frame)なので注意

出た消費数(Frame)をエメタイマーに入力して、「最初から始める」を選択と同時にタイマーを開始します。

f:id:sina_poke:20190318183229p:plain

そして、タイマーが終わると同時に名前を決定します。
後は出たイーブイから検索して、ずれを修正してもう一度行ってください。

・色イーブイ

f:id:sina_poke:20190602160555j:plain

デフォルトネームでしか試してないので、任意TNだと何かずれがあるかもしれません。
同じようなやり方でコロシアムのID調整もできるらしいので、そのうちツールを作るかも。

【欧州版XD乱数】臆病5Va0ラルトス

ID調整をしてメソッドずれを起こすことで出現する個体です。

f:id:sina_poke:20190506210623j:plain

f:id:sina_poke:20190506210640j:plain

臆病 31-0-31-31-31-31 性格値 0x9D8707EB

・ID調整

seed 0xABB1DF4F 表ID 00000 裏ID 39532

強制消費のメモ

n=38,39,42

38,1
39,2
40,2
42,2

931^957 ≒ 944

403754^404305 550^1101
375069^375660 665^1256
365697^366222 893^1422
375020^375425 616^1021
403700^404245 496^1041
384725^385284 721^1280
384935^385101 931^1097

いますぐ対戦後
n=33

33,4

317465^317832 661^1028
317473^318173 669^1369
317495^317757 691^953
317630^317874 826^1070

※強制消費の値はいますぐバトルでシードを特定→続きから直後にエンカウントしたものです。

ラルトスnpc消費とnずれの両方がありますが、いますぐバトルでシードの特定&消費をすることでnpc消費によるずれはほとんど無視できます。nのずれに関しても、検証した結果少し楽になりそうなのでまとめておきます。

いますぐバトルでnpcと対戦することで、その後に戦う戦闘員とのエンカウントではnの値に変化があることが分かりました。デルビル、ドンメルと今回のラルトスで検証しましたが、どれもいますぐバトルで対戦後の場合、nの値が小さくなりました。(ドンメルとデルビルの結果は保存ミスで消えてしまった)

ドンメルの結果ではいますぐ後でもnの値に結構ブレがあったのですが、ラルトスの結果ではいますぐを使用する場合でnの値が安定してるのが分かります。数回しか検証してないので固定できてるかは不明。前のメモにも書きましたが、欧州版ではn固定法によってnの固定ができないという欠点があります。その代わり、ポケモンによってはnの値にある程度偏りが出るようです。今回のラルトスの検証で、いますぐの有無でnの偏りが変わることが分かったので、検証次第ではとても楽になるポケモンもいそうです。

日本版でも同じような現象が起こるかは未検証なので、だれか検証してみてください。

【追記】

クチートで検証してみた結果

いますぐ対戦後

n=31

31,4

297910^298188 306^584
298067^298359 463^755
298084^298177 480^574

固定できてそうです。

【欧州版XD】いますぐバトルで初期シードを特定した場合のトゲピーの消費数

日本版だと難しそうという記事を見たので、試しに欧州版で検証してみた結果を書きます。

10回ほど検証して出た強制消費の値は下のようになりました。

1428
1419
1433
1443
1429
1403
1443
1405
1425
1423

10回で近い消費数がちらほら出ていたり、一致したものもあるので結構安定してる方じゃないでしょうか。やったことないのでよく分かりませんが...。

一応操作を書いておきますが、続きから始めるを選択したあとに、Bを長押しした状態でメッセージを早送りしながらA連打で受け取りました。言語はドイツ語です。

日本版では安定しないそうですが、フィールドでの消費速度の違いや、npcのいる環境で続きから始める場合に消費数の違いがあるのかもしれないです。その辺は気が向いたら調べます。今の所は欧州版大安定なので、欧州版を購入しましょう。

元々この方法での初期シードの特定は、ガルーラあたりが楽になるかなぁ~程度だったのでトゲピーまでは想定してませんでした。やっぱり展開がないと少し難しそうですね。

【追記】

連射コンで試してみましたが安定しませんでした。

1427
1424
1419
1391

もしやるなら素直にA連打でいいと思います。

【コロシアム乱数】初期シード検索の高速化

先日需要があると言われたので試しに作ってみました。ツイッターを眺めてて思ったんですけど、コロシアム乱数やってる人って結構いるんですね、驚きました。なんとなく触発されて私もやりたくなったので、久しぶりに何かやってみようと思います。

そんなどうでもいい話はともかく、ツールの説明に入りたいと思います。外観はこんなかんじです↓

f:id:sina_poke:20190319003328p:plain

コロシアム乱数をやったことのある人ならどうやって使えばいいかすぐわかると思います。見ての通り、1~8にトレーナー名と手持ちポケモン入力して計算を押すだけです。それだけで一瞬でシードが特定できます。

f:id:sina_poke:20190319003342p:plain

ただ、ツールを使用する前にデータベースを作成しておく必要があります。この辺はさっき上げたXD乱数の記事と一緒なので割愛します。

ツールはここからダウンロードできます。

新しくしたのでこっちを使ってください。

※dllファイルを同封するのを忘れてたので上げ直しました。

一瞬で結果が出ると思うので試行回数を稼ぐ系の乱数にぴったりだと思います。みなさんもコロシアムスイクンやりましょう!

ツールのバグ報告や、直してほしいところがあったらコメント欄で教えてください。

【XD乱数】いますぐバトルでのシードの特定

お待たせしました。日本版での調査とツールのデバッグが一通り終わったのでやり方を公開したいと思います。

【注意】ID調整、ダークポケモンの乱数への応用に関しては欧州版でのみ可能です。日本版は消費の微調整ができないため、展開の広いポケモンに対しての乱数のみ現実的な難易度でできると思います。日本版でもできるようになりました。

ツールはここからダウンロードできます。

8/8更新
細かいバグを修正。

初期シード検索用のデータベースとは別に全範囲の検索ができるデータベースを作成したので、ここからダウンロードしてDatabaseフォルダに入れといてください。800MB程度で割と大きいので注意。使わなくても一応できますが、あった方が色々と楽です。

1. 初期シード検索用データベースの作成

一度GUIツール上で検索するコードを書いてみたところあまりにも遅かったので、データベースを作成することで高速化しました。これによって数十分かかっていたのが数秒に変わりました。7世代でおなじみの方法になりますね。作成するに当たり、最低500MB程度の空き容量が必要です。検索範囲を広げる場合は+数百MB必要になります。データベースの作成にはXDatabase.exeというツールを使います。

まずはじめにいつものやり方でシードを特定して、ある程度予想されるシードの範囲を特定しておきます。そしてその範囲+αのシードをツールに入力します。

f:id:sina_poke:20190318184911p:plain

データベースの作成にはシードの範囲にもよりますが10分以内には終わると思います。あまり検索範囲を取りすぎると計算時間も長くなりますし容量も大きくなってしまうので、そこはうまい具合に決めてください。データベースの作成中はとてもPCが重くなって他の用途に使えなくなるので注意してください。

データベースの作成が終わったら次にソートを行います。これは付属のXDatabaseSort.exeを実行するだけです。

f:id:sina_poke:20190318185005p:plain

データベースの容量にもよりますが数分で終わります。

これでデータベースの作成は完了です。

2. 目標個体の設定

ここからはXDQuickBattleSearchを使っていきます。

まずは初めに、ギンザルさんのツールやID / イーブイ検索タブを使って目標のシードを検索しておきます。

f:id:sina_poke:20190318180452p:plain

私のツールでは検索結果の一番左のシード列がこれに当たります。イーブイの検索に関してなんですが、個体値の範囲を広くして計算するとあまりにも遅すぎてツールが止まってしまうので別に専用のツールを添付しました。こんなかんじで使ってください。

f:id:sina_poke:20190318233745p:plain

適当に作ったので割とガバガバです。どちらも計算結果をresult.csvとして出力する機能がついています。

ここまでできたら初期シードの特定に入る前に一度ゲームを始めてリバース状態のダークポケモンと適当なポケモンを手持ちに置いておきます。これらは消費を行うのに使用します。

3. 初期シードの特定

初期シードの特定方法には、①作成した初期シード検索用のデータベースから検索する方法と②全範囲のシードから作成したデータベースから検索する方法の2種類あります。②の方法に関してはデータベースファイルをダウンロードしていないと使えないので注意。

①の方法では初期シードの特定に限って簡単にシードを求めることができます。②の方法では検索が大変ですが、起動直後に限らずどこでもシードを求めることができます。

①作成した初期シード検索用のデータベースから検索する方法

いつものように決められた秒数で起動を行い「対戦モード」を選択します。そのまま「いますぐバトル」を選択し、「コンピュータとバトル」の「さいきょう」を選びます。

f:id:sina_poke:20190318185546p:plain

初期シードを検索にチェックを入れて、出た手持ちの種類とHPの実数値をツールに入力し、計算をクリックします。

f:id:sina_poke:20190506005409p:plain

結果が出たら「候補から絞り込む」にチェックを入れて、一度戻ってからもう一度「さいきょう」を選択して出た手持ちをツールに入力して計算します。

何度か行って結果が1つに絞り込むことができれば初期シードの特定は成功です。

f:id:sina_poke:20190506010145p:plain※最新のツールだと表示が少し違います。

②全範囲のシードから作成したデータベースから検索する方法

「初期シードを検索」のチェックが外れていることを確認しておきます。

その後、ゲーム起動直後に関わらずどのタイミングからでも構わないので、「いますぐバトル」の「さいきょう」を選択して出た連続した3つの手持ちをツールに入力します。

最初に出た組み合わせは手持ちの種類のみを「手持ちの情報」の欄に入力して、その後の2つは下の枠内に手持ちの種類とHPの実数値を入力します。

そして計算をクリックします。

f:id:sina_poke:20190506013131p:plain

結果が見つかるとこのように表示されます。

候補が見つかった後は①と同じようにして候補から絞り込んでください。

f:id:sina_poke:20190506013242p:plain

この方法は基本的にLCG上のどこにいても使えるので、大量に消費したあとのシードの特定に使うととても便利だと思います。

4. 目標個体までの消費

大まかな消費を行う場合はつないでバトルで行います。

f:id:sina_poke:20190318181715p:plain

適当に項目を設定して決定を選択するとXD上での今の手持ちが表示されるので、つよさをみるを使って消費します。

f:id:sina_poke:20190318182458p:plain

ギンザルさんのページにある通り、リバース状態のダークポケモンを眺めると約3700/sの消費を行うことができます。そのため、あらかじめメインのデータの手持ちに消費用のポケモンをセットしておく必要があります。

ここで消費を行ったあとはいますぐバトルで現在のシードを求めます。シード検索タブのシードを選択して、消費前のシードと検索したい消費数の範囲を入力します。そして出てきた手持ちを入力して計算を押します。

f:id:sina_poke:20190602153202p:plain

検索する消費数の範囲が数千万単位でとても広い場合、上にある全範囲のデータベースを使って計算した方が楽に現在シードを求めることができます。

そして残り消費数が約10000程度になったら消費契機タブで残りの消費を行います。

現在のシードと目標の消費数を入力します。続きから始める場合は持ち物消費にチェックを入れてロード後のフィールドの持ち物消費数を入力しておきます。※持ち物消費数が分からない場合は入力しなくていいと思います。

f:id:sina_poke:20190318235507p:plain

ここで結果が出た場合は出力された組み合わせの通りに行動すれば消費ができます。いくつか候補が出ると思いますがどれを行っても大丈夫です。カッコ内はその行動をする回数になります。

・最強

一度Bで戻ってからもう一度「さいきょう」を選択します。

f:id:sina_poke:20190602154701p:plain

・最初

タイトルに戻った後、最初から始めるを選択します。

f:id:sina_poke:20190318183229p:plain

この画面で「はい」を選択すると2消費されます。日本XDはここで「はい」を選択後に高速消費が起きてしまうので消費の調整ができません。

・設定

設定を変更してセーブすると40消費されます。

f:id:sina_poke:20190318183249p:plain

・いますぐ

対戦モードの画面からいますぐバトルを選択します。対戦モードからいますぐバトルの画面に移る時に消費が行われます。

f:id:sina_poke:20190318183321p:plain

日本XDでは「最初」での2消費を使えないので、ダークポケモンの乱数をする場合はできるだけ「最初」による消費が少ない候補を使うか、ID調整をする場合を参考にして名前選択画面でフレーム単位で調整する必要があります。

5. 目標個体とのエンカウント

ID調整、イーブイの場合は最後に「最初から始める」を選択して消費を行ってからタイトルには戻らずにそのまま名前選択を行って最初から始めてください。※消費の最後に「最初(0)」の候補は使えません。続きから始める場合はタイトルに戻ってから続きからを選択してください。続きから直後のエンカウントについて、nの調査や消費数の範囲などは調べてないので各自調べてそれに合わせて調整を行ってください。うまく目標個体とエンカウントできれば成功です。

成功するとこんなかんじになります。

f:id:sina_poke:20190319125751j:plain

f:id:sina_poke:20190319125802j:plain

臆病色イーブイ 29-4-29-31-30-31 表ID 48835 裏ID57548

以上でツールの説明を終わりにします。ツールについて何か要望や改善してほしいところがあったら教えてください。

需要がありそうなら仕組みについて記事にまとめます。