ポケットモンスターBWにおける乱数の仕組みについて書きます。
乱数調整に関連したツールを作ったのでよかったら使ってください。
・BW個体値乱数調整
・BW性格値乱数調整
前のseedによって求められ、次のseedを求める際使われる数値。
seedから計算して得られる、実際の計算に使われる値。
例えばseedの上位16bit等。
ゲーム中ではリアルタイムに計算されているとしても、疑似乱数は数列として扱う。
ある時点でメモリ内のseed格納用のアドレスに格納されている値のseed数列の位置 「seedの位置が[n]」であるときに生成される乱数は[n+1]の位置のseedが使われる。
seedの位置を数列の次の項にし、更新後の値から乱数を得ること。
BWでは、野生ポケモンと遭遇(エンカウント)、ボルトロス・トルネロスの徘徊開始イベント、タマゴの受け取り等の時、
そのポケモンの性格値・個体値が決められるのに乱数が使われる。
ただし性格値・性格と個体値の乱数は別の計算方法で数列化されており、前者を性格値乱数列、後者を個体値乱数列と呼ぶことにする。
性格値乱数列のseed1個は64bit、個体値乱数列は32bitで、性格値乱数列は項の上位32bitが乱数として使われる。
この実際使われる性格値乱数の数列を{r1[n]}、個体値乱数の数列を{r2[n]}、とする。
また、r1[n],r2[n]を作るseedをS1[n],S2[n]とする。
性格値乱数列と個体値乱数列の初項は共通で、ゲームを起動した瞬間(=ソフトリセットした瞬間)に決定される。
これはある52byteのデータをSHA-1でハッシュ化した64bitの値である。
ハッシュ化する前の52byteの決定方法は以下のようになっている。
nazo | AABBCCDD | 謎の値。バージョン毎に固有 ブラックだと0x2215f10、ホワイトだと0x2215f30 |
---|---|---|
AA'BB'CC'DD' | nazo+0xfc | |
AA''BB''CC''DD'' | nazo+0xfc+0x4c | |
VCount | EEFF | Vertical Counter(現在描画中の走査線番号)。バージョン毎に固有 ブラックだと0x60、ホワイトだと0x5f |
Timer0 | GGHH | DSに内蔵する4つのタイマーのうちの1つ。バージョン毎に2通りからランダムで変動? ブラックだと0x0c79または0xc7a、ホワイトだと0xc68または0xc69 |
GxStat^Frame | IIJJKKLL | GxStat:Geometry Engine Status Register。0x6000000 Frame:何らかのフレーム?本体の種類依存。初代DSだと8、DSLiteだと6 これら2つをXORしたもの。 |
MACアドレス | M1-M2-M3-M4-M5-M6 | 「Wi-Fi設定」→「オプション」→「本体情報」で見れる値 |
M1' | M1^LL | |
M2' | M2^KK | |
M3' | M3^JJ | |
M4' | M4^II | |
起動日時 | 起動時の内部時計に関する情報。使われるのはDSLite以前のメニューでソフトを選択してから1秒後ぐらい。 全て12月→0x12等、10進表記をそのまま16進数にしたもの。 | |
yy | 年の下2桁 | |
mm | 月 | |
dd | 日 | |
NN | 曜日。日曜0〜土曜6 | |
hh | 時。12時以降だと+0x40 | |
mi | 分 | |
ss | 秒 | |
キー入力 | OOPP | 起動時のキー入力の状態。 何も押されていないと0x2fff、Aボタンだけ押されていると0x2ffe |
00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 0A | 0B | 0C | 0D | 0E | 0F | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
00 | DD | CC | BB | AA | DD' | CC' | BB' | AA' | DD' | CC' | BB' | AA' | DD'' | CC'' | BB'' | AA'' |
10 | DD'' | CC'' | BB'' | AA'' | HH | GG | FF | EE | 00 | 00 | M5 | M6 | M1' | M2' | M3' | M4' |
20 | yy | mm | dd | NN | hh | mi | ss | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 |
30 | PP | OO | 00 | 00 |
性格値seed列{S1[n]}は
S1[n+1] = S1[n] * 0x5D588B656C078965 + 0x269EC3となる。ただしS1[0]=初期seedで、65bit以上は切り捨て。
乱数r1[n]はS1[n]の上位32bitとなるが、メモリの初期値はS1[0]であり、
上に書いたように最初に使われる乱数はS1[0]ではなくS1[1]の上位32bitなので、実際の乱数として使われるのはr1[1]から。
レポートを書くと1消費。ポケモンを持っていないゲーム開始時でも有効。
「おしゃべり」を録音したペラップのステータス画面を開く毎に1消費
揺れる草むらの出現判定・タマゴの生成判定等に使われる。
名前入力の時点での次に使われる乱数をr1[n]とすると、
r1[n]×0xFFFFFFFFの上位32bitがトレーナーIDとなる。
アララギ博士の確認に対し「いいえ」と答えると1個消費し別の値になる。
歩いている時やあまいかおり・あまいミツを使った時など、野生ポケモンの出現時に出現ポケモンの種類が決定されるのに使われる。
データはポケモンの友のエンカウントテーブルを参照。
次に使われる乱数をr1[n]とすると、
X | 出現ポケモン |
---|---|
0〜320 | 0 |
321〜640 | 1 |
641〜800 | 2 |
801〜960 | 3 |
961〜1120 | 4 |
1121〜1280 | 5 |
1281〜1360 | 6 |
1361〜1440 | 7 |
1441〜1504 | 8 |
1505〜1568 | 9 |
1569〜1584 | 10 |
1585〜1599 | 11 |
御三家受け取りや固定シンボルエンカウント・野生ポケモンの出現時に、性格値と性格が決定されるのに使われる。
次に使われる乱数をr1[n]とすると、
となる。3個消費。ただしシンクロの効かない御三家受け取り・化石復元の場合、シンクロ判定はスキップされる。
ボルトロス・トルネロスのイベント終了時に、性格値と性格が決定されるのに使われる。
次に使われる乱数をr1[n]とすると、
となる。2個消費。ただし雨の演出によりこの他に大量に消費されているので注意。
タマゴが出来ている時、そだてやじいさんとの会話終了時に、性格値・性格・遺伝箇所等が決定されるのに使われる。
次に使われる乱数をr1[n]とすると、
・(r1[n]*25)>>32が性格
・どちらかの親がかわらずのいしを持っている場合(r1[n+1]*2)>>32で性格遺伝判定
※以下、かわらずのいしを持っている場合。(持っていない場合、全て1つ前の乱数が使われる)
・親が♂と♀で、♀が夢特性の場合(r1[n+2]*5)>>32が2以上なら夢特性遺伝
※夢特性でない場合でもr1[n+2]は消費される。
・親にメタモンが含まれる場合1個消費
※以下、メタモンが含まれる場合。(含まれない場合、全て1つ前の乱数が使われる。かわらずのいしと合わせて最大2つ前にずれる。)
・m=n+4とし、
☆:(r1[m]*6)>>32をステータス(HABCDS:012345)、r1[m+1]>>31を親(1:後)として遺伝箇所決定
片方の親がパワー系アイテムを持っている場合、予めその箇所は遺伝確定。
ステータスが重複した場合スキップで、遺伝箇所が3箇所決まるまでmを2増やして☆を再度実行。
・(r1[m+2]*0xffffffff)>>32が性格値
性格値を256で割った余りが性別、性格値>>16の下位1bitが特性。
主人公と同エリア上のNPCが移動したり方向転換したりするときに消費。
移動も方向転換もしないNPCは消費しない。
624項の数列{t[n]}があり、t[0]から順に消費され、t[623]が消費されたとき{t[n]}が更新され、またt[0]に戻る。
t[n]の値を使う順に並べたものが、タマゴ乱数列{S2[n]}となる。
更新する処理がm回行われた後の{t[n]}を第mテーブルと呼ぶことにし、S2[(m-1)*624+n]は第mテーブルのt[n]と等しい。
最初に1回更新されるので、第0テーブルはSEEDとしては使われず第1テーブルの計算のみに使われる。
n:1〜623であり小数点以下は出る度に切り捨て。
k[0],k[1]を32bitまで保持する変数として
・k[0] = (t[A] and 0x80000000) or (t[B] and 0x7fffffff)この処理がA,B,Cが以下の順として行われる。
・A=n、B=n+1、C=n+397 (n:0〜226)
Cギアを起動すると個体値乱数列のみが再計算される。
この時初期SEEDとして使われるのは時刻依存の値(raw初期SEEDとする)にMACアドレス下位3byte(01-23-45-67-89-ABの場合0x6789AB)を加算したものとなる。
raw初期SEEDを0xABCDEFGHとすると
となる。年月日時分秒はDS内部時計の値。
再計算後に個体値乱数を2個消費。
個体値乱数列のSEEDをEとすると、k[0~3]を32bitまで保持する変数として
・k[0] = (E/0x800) xor E小数点以下は出る度に切り捨て。
次に使われるSEEDをS2[n]とすると、S2[n]〜S2[n+5]から上記の方法で個体値を計算し、それをHABCDSの個体値とする。
戦闘によりさらに個体値乱数が大量に消費される。
次に使われるSEEDをS2[n]とすると、S2[n+7]〜S2[n+12]から同様に個体値を計算し、それをHABCDSの個体値とする。
その後個体値乱数とは無関係な乱数を用いて遺伝箇所が決定され両親の個体値で上書きされる。
13個消費
小屋から出てボルトロス・トルネロスと初めて出会った瞬間に個体値が決定される。
また、一度撃破して殿堂入りすると再計算されるが詳細は不明。
次に使われるSEEDをS2[n]とすると、S2[n+1]〜S2[n+6]から上記の方法で個体値を計算し、それをHABDSCの個体値とする。