Legendaries are generated as if another Poke is received before them, i.e. 5 additional PIDRNG advances and 13 additional IV frame advances. The particle effects when receiving them have no effect on either RNG (before they are received, anyway).

Click to expand...

The above is actually only true for the genies. The other legendaries do not get any fanfare, and are generated in the same way as normal mons, except that the PID is generated as if they are a 100% male gender species for some reason.

The PID data for each mon is generated one right after the other (either 4 or 5 PIDRNG frames later depending on whether the previous mon was genderless or not).

The IVs for each mon are 13 IVRNG frames apart.

How legendaries fit in with this scheme is untested, as they have their own slots separate from the normal mons, and I always made sure to have the legendary captured by itself.

I'd definitely recommend just RNGing the first mon, since the PID frame of the later ones depend on the genders of all the previous ones.

One activation of the IR key swap functionality to view the spinner (first menu choice in the Isshu link menu) advances both PIDRNG and IVRNG by 2.

This means that PID and IVs are tied together and therefore the number of useful seeds is far fewer than normal Gen 5 standard abuse.

I'm treating each spinner advance as one 'Dream Radar' frame to avoid people aiming for frames they can't hit.

The spinner allows you to know in about 3 advances whether you hit your seed or not, so you won't lose your legendary by accident.

If receiving a legendary, the gender/ratio is forced to be 100% male regardless of species (e.g. the 4th gen legendaries that I have tested have PIDs generated as if they were 100% male species). I'm guessing it's because while they don't get the fanfare that the genies (100% male species) get, they do sit in the special slots separate from normal mons in the Dream Radar.

PID frame structure:

For the first mon only, an unknown RNG call. Subsequent mons start from step 2.

PID (one RNG call for genderless, two for gendered using the standard gender forcing algorithm). Xor with 0x00010000 occurs.

Unknown RNG call

Unknown RNG call

Nature

​

The spinner position you see when you activate the IR key swap function is determined by the highest 3 bits of the RNG value produced in step 1 in the above structure.

If receiving a genie, throw out first mon and regenerate (i.e. PIDRNG advanced by 5 additional frames, IVRNG advanced by 13 additional frames).

nidorans and volbeat/illumise breeding aren't done the same way anymore. in bw1, they were done with normal rng call, but in bw2, they use and inline copy of the rng and a different state that is stored in ram along with the daycare pkms. it looks like "01 pkm1 9f 01 pkm2 9f 01 rng state 9f 01 something 9f" as one long block in ram.

the inline rng call used for nidoran and volbeat is based on a seed generated when you first set up your character on starting the game for the first time. this is due to an error on gamefreak's part, however. each time the game starts, this seed should be unique. this function runs on every boot:

and it writes the 8-byte seed to 2225E70. however, right after this, the old seed is read into the same spot. the game reads in the save data into the svc stack and then copies the memory into place, overwriting the new seed with the one that was first created. what should happen is that the egg data and rng state should be loaded from the cart then copied into place THEN that function should run and overwrite the old seed with the new one. they happen in the wrong order and thus, you end up stuck with the same seed every time. this also explains the 2 mersenne twister calls that happen on every boot, causing it to always start at 3.

so uh, it's not just illumise and nidoran. everything bred is done with inline rng calls using that rng state that never changes unless you start a new game. inheritance, nature, etc etc etc, everything. the only thing that isn't is the extra rolls for shiny charm and masuda method.

e: turns out it's for everything important except for pids. and thankfully they get it right after the first egg and the game reseeds the egg state from the mersenne twister. not that it matters as generating a second egg throws everything off due to walking around, npcs, etc.

so uh, it's not just illumise and nidoran. everything bred is done with inline rng calls using that rng state that never changes unless you start a new game. inheritance, nature, pids, etc etc etc, everything. the only thing that isn't is the extra rolls for shiny charm and masuda method.

Click to expand...

So what's that mean?

I hear you're stuck w/ one nidoran or vol/ill "gender", but does that hurt other breeding on BW2... like force people to always get one gender, or always get a particular IV set?

PIDs are random. There's still 3 calls to the PIDRNG. 2 calls in makePKMN, then PID, then another call in makePKMN.

sub_200C49C actually updates the value of this new rng's seed at 2225E70. It calls MT twice and uses that for values in the seed. After you receive your first egg it is seeded correctly (like it tries to do at boot but fails because they then load a new value to it) and you get the value of the next two MT calls for the seed of it. For the first egg it's the value at frame 16 and 17 of the table (BW2 frames 14 and 15).

Basically to sum up what Bond posted on the previous page, the game will loop though every Hidden Hollow (0-19) every 256 steps. If the hollow is empty (lowest bit is not set) then it calls rand(100). If that's less than 5 it goes and generates a hidden hollow.

While generating the game calls rand(4) that determines the sub slot (or group in the chart) 0=A,1=B,2=C,3=D. There's an equal chance for each one.

Then the game calls rand(100)+1. It presumably works exactly like other encounter slots (I've never looked at the assembly for encounter slots so I'm not sure) where if it's in a certain range of values it'll be one slot or another. The chat has the percent chance of each row as well as the possible values of the rand(100) call to get the specific slots.

Then if the slot = 2 it does a check and basically if a certain byte in an array that appears to always be 0x30, isn't 0x30 it jumps back to the start of the slot decision loop. From what I can tell this never happens so Reporter is ignoring that possibility.

Code relevant to this in case we need to research that more later:
Code which loads R7 to be either 1 or 3:

Then a rand(100) call is made again. This is used to store the gender value. The game does if gender value < chance female then make it female.

Finally it is stored into the array. The top byte is equal to the gender value. The lower byte is is this form (each digit representing a bit):
XXXY YYYZ

Where X is the subslot, the rand(4) call. It should be between 0 and 3.
Y is the value of the slot, after the encounter slot loop. It should be between 0 and 10.
And Z is the is empty bit. Where if it's set to 1 then the hollow is treated as if it has something in it but if it's set to 0 it's treated as empty.

You get some pretty weird stuff and sometimes the error NPC if you give the game values which are normally not possible.
The scripted Minccino encounter sets the value of the array to 0x6400 to force it to be male and be the Pokemon in slot 0, subslot 0.
And yes there is a 0.075% chance of normally getting a hollow with a female Pinsir in White2 and female Heracross in Black2.

For both versions:
The first two nazo values are the same as on a DS (as Bond697 suspected).
The pattern for the third, fourth, and fifth nazos is the same as on DS (fourth and fifth are both third plus 0x54).

Next time I can do the searches since my computer are more powerful. I think I finally got OpenCL working and should be able to use my GPUs to make searches even faster.

Click to expand...

I would be interested to know how it performs on a higher powered GPU (including which of the vectorized implementations is fastest). Have you tested it with actual seed data and verified that it's working correctly?

I wonder why the Timer0s are so far apart.

Click to expand...

The timer0 (and vcount) difference is probably related to whatever it is that creates the large difference in the nazos (0x730 vs. 0x5F0). Extra memory allocated for something...

I decided to look into Pokemon Channel Jirachi and the results so far aren't too great.

I can't get VBA-M + Dolphin to work correctly no matter how hard I try. It starts the connection, the image of Jirachi displays on my VBA window and both run really slow and then I get a connection error. This makes debugging pretty hard to do. I'd probably have to just open the dol file in IDA and look at the assembly with no debugging to help me.

The SID and game origin is even different between the two Pokemon. Either there's a list of SIDs and games (possibly one for ruby and one for sapphire) or it generates those as well as the Pokemon.

The only assumption I can make is that it's based off an RNG using the Gamecube's RTC as a seed.

Using the first Jirachi (PID 7C805A75)

I decided to use the PID and test different known RNGs. Here are the only possible seeds which would give the correct PID:
XD Seed: 705DA0FF
Regular Seed: 43F9E475

The only way this is possible is if the upper PID is generated first and then the lower pid. This is consistent with how the bonus disc Jirachi as well as the Pokemon Box Pokemon's PIDs are generated.

If you look at these seeds no where near these RNG values is possible values for the IVs, 3019 or B019 and 4352 or C352. The best assumption I can make in this situation is that we're facing a new RNG. Hopefully it's a LCRNG which I can find with disassemble.

I've just made a discovery that will revolutionize RNG abuse on retail Emerald carts: You can use Battle Videos from the Battle Frontier to save a PRNG state. (tl;dr version at the end of this post)

Any battle that can be saved on the Frontier Pass actually disables the vBlank function from advancing the PRNG. I assume this is so the Battle Video can function simply as a starting seed, the Pokémon, and a set of instructions (like the later gen battle videos). The storage of the starting seed is the key to this whole thing. When you load the battle video the PRNG advances in the exact same way as it did the real battle (one frame advancement right away, then no advancements until move selection) giving about a 10 second window where the PRNG is completely still with 1 frame past the stored value. This gives one ample time to press B to exit the video, and start an external timer (note that the PRNG starts advancing normally again on the 24th video frame after pressing B).

When a battle that can be saved starts the PRNG stops advancing as soon as the screen completely fades to black, and the current PRNG value is stored. So for example, let's say it's holding the PRNG value at frame 1000000 (starting seed of 0 obviously). Win/lose the battle, save the video. When you load the video, even after turning off the game, it will jump to the PRNG value at frame 1000000, and advance once right away. Then one would press B before the first turn begins, and after 23 frames, the PRNG advances normally, starting at frame 1000002.

This clearly has amazing potential - one can instantly jump to a desired PRNG state so they don't have to wait hours just to hope that they pressed the A button (or took a step) at the correct video frame. One can simply store a PRNG value much closer to the actual frame, within 10000 PRNG frames optimally. By making multiple battle videos, one can slowly but surely advance to frames previously thought humanly impossible to within very few frames of the target. That Careful 31/31/31/7/31/31 spread on frame 144187325? That would be easily attainable on a retail cart by using multiple battle videos over a few weeks. It would take a while but one could get to a PRNG that is a reasonable amount of frames away from the target, then do a fairly quick RNG abuse. And then, it can even be used on multiple Pokémon!

Edit: This all came about because I wanted to find out if Anabel's Alakazam had a fixed ability or not. It doesn't. I then noticed the PRNG wasn't advancing while idling in battle. Took me 10 minutes to realize this was for syncing battle videos.

Limitations: One must beat the Pokémon league, and walk outside of the player's house for a certain amount of steps for Scott to call, enabling you to go to the Battle Frontier. This means the roaming Lati cannot be RNG abused with this without cheating, nor can one use the proper seeding of the PRNG from starting a new save file.

Edit 2: To estimate the PRNG value stored by the battle video simply capture a Pokémon (preferably a stationary encounter) multiple times around the same amount of time after exiting the video and search that spread in RNG reporter Method 1 (or H-2 for a wild encounter, maybe H-1 or H-4).

tl;dr - Battle videos can act like "save states" for the PRNG on retail Emerald carts.

Edit 3: Battle videos cannot be used for RNG abusing egg PIDs. Half of the egg PID uses another RNG, which is seeded by a timer that tracks frames since the last boot/SR. There is no way to change it outside of waiting.

Did some testing, trying, and it's indeed awesome. I'm not quite sure at which moment it grab's / saves the seed (perhaps I didn't read Hozu's post close enough). But I used VBA + Lua and grabt the seed at the point I'm saving my game before entering the Tower, get defeated and went to Rayquaza's place openend the Battle vid and checked wich frame I landed, and it was about 3000 frames later then from the seed (I entered the seed I grabt into RNGReporter). So it looks like stuff like Regi's or other stuff could be quite easy now.

I've found a seed for which the current B2W2 initial PIDRNG frame calc does not work.

Seed: 221222F33BDC030C
Calc says: 59
Actual frame: 55

Verified twice on an actual White 2 cart:

Once in a quiet Pokecenter when picking up Keldeo (picked up on frame 55)

Once in the first room of Reverse Mountain (captured on frame 56 - something here is advancing the PIDRNG by one frame at startup no matter which seed I hit).

Click to expand...

I've hit that seed 3 times in a row on an emulator and it's always been frame 59 when I start my game. I'm inside the Nimbasa Pokemon Center. Just for consistency what Pokemon Center are you using? Or even better extract your save file and give it to me.
The first probability table does 8 advances, then there's 3 other advances for various things leaving it at 11.
The second, third, fourth, and fifth probability table calls (all during the loading of the game) bring it to 23, 35, 45, 56 respectively.
Then the final extra call passes after the first set of 3 generations, bringing it to 59.

For verification the value of the PIDRNG seed (64 bit number at 0x21FF5D8) is D240E5800EF091F6. Looking at the researcher that's frame 58, meaning my starting frame is actually 59.

I've hit that seed 3 times in a row on an emulator and it's always been frame 59 when I start my game. I'm inside the Nimbasa Pokemon Center. Just for consistency what Pokemon Center are you using? Or even better extract your save file and give it to me.
The first probability table does 8 advances, then there's 3 other advances for various things leaving it at 11.
The second, third, fourth, and fifth probability table calls (all during the loading of the game) bring it to 23, 35, 45, 56 respectively.
Then the final extra call passes after the first set of 3 generations, bringing it to 59.

For verification the value of the PIDRNG seed (64 bit number at 0x21FF5D8) is D240E5800EF091F6. Looking at the researcher that's frame 58, meaning my starting frame is actually 59.

Click to expand...

Yeah, I expected this to be the case. I recently did the memory link with my White cart, and I'm assuming that doing that has changed the initial PIDRNG frame for some seeds, while other seeds are the same. It has also changed the initial PIDRNG frame for all seeds for the Dream Radar, which used to be the same as when starting the game normally.

Unfortunately, I don't have the tools to extract my save. I was in the Undella town Pokecenter.

If you have a way to do the memory link, that would definitely be a first step.

Edit:
Here are some seeds and the initial PIDRNG frame when accessing the spinner under the Isshu Link menu. I have not confirmed what the initial frames for these seeds are when starting the game normally.

Got it that memory link was all I needed thanks. I'm not sure exactly what causes it but instead of doing
ProbabilityTable()
rand() x3
ProbabilityTable()x4
Extra()
It does
ProbabilityTable()
rand() x2
ProbabilityTable()x4
Extra()

Pokemon Emerald Safari Zone Encounter slots appear to be off by 1 frame. That means there's an extra RNG call between the generation of the Encounter slot and the PID. I'm not sure what causes this call, I'll look into it later if I can manage to get gbd debugging working correctly.

Got it that memory link was all I needed thanks. I'm not sure exactly what causes it but instead of doing
ProbabilityTable()
rand() x3
ProbabilityTable()x4
Extra()
It does
ProbabilityTable()
rand() x2
ProbabilityTable()x4
Extra()

Click to expand...

As a follow up to this, if the memory link has not been done, there is an extra PIDRNG advance when entering the Isshu Link menu. There is no advancement if the memory link has been done. This affects the spinner sequence and the nature of a received DR poke, and combined with the difference in the initial PIDRNG frame makes it very likely that a DR seed found before doing a memory link will no longer be useable after unless you get lucky with the sequence of natures.

Structure of R/S Egg generation:
The lower PID is generated when you take your step and the egg is generated.
It generates the egg if rand(100) < Compatibility. The compatibility number is 20 if same id different species, 50 if same id same species or different id different species, and 70 if different id same species.
Then it calls rand() to get the lower PID. If this number is 0xFFFE or 0xFFFF the game does pid+2 % 0xFFFF (I believe the actual code is something more efficient than that or it doesn't need to use the mod because it's using 16 bit numbers). One is then added to the pid and it's stored.

The rest of the PID is generated as follows:
rand() for the upper pid
vblank sometimes
rand() x2 for the ivs
rand() % (6-i) for the inheritance slot
vblank
rand() % (6-i) for the inheritance slot
rand()&1 x3 to determine which parent to inherit from for each of the iv slots.
Inheritance calcs are identical to how they are in HG/SS.

if it's like emerald(and it probably is in that regard), then it's doing pid half % 0xFFFE in those cases. if i'm understanding what you're saying properly, anyway. instead of adding, they waste a bunch of processing time doing modulus.