Most Generation PRNG Help / Information

-TCCPhreak. Are you looking into the game code? If yes could you check how the ID and the Secret ID are created? maybe we can work out how to calculate the Secret ID from the ID and the game starting date...It would be awesome.
=J=
 
Hello,

first of all I'd like to report some success regarding "does it work on D/P, too?".

* Caught the Seed after reset.
* watched the IRNG (or what seems like it) while egg was created,
* noted down the number it returned -> IRNG_return
* took the egg and saved. Then peeked at the PID of the egg -> egg_PID
* fed the Seed into PRNG-Generator and let it calculate the PIDs of the first egg -> Gen_PID

Result: IRNG_return == egg_PID == Gen_PID.

In other news, I'm trying to re-implement the EggRNG on PC. Unfortunately I don't completely understand everything Jonny has writte and would be grateful if someone could tell me whether I'm right with what I did so far.

let's start with the 0th table construction
a table is an array of 624 numbers, called t[0..623], normally indexed with n

t[0] = Initial SEED
t[n] = (( upper 2bits of t [n-1] ) xor t [n-1]) * 0x6c078965 + n
So initial_table can be generated with only SEED as input.

t_table createInitialTable(uint32_t seed);

k[0] , k[1]

k[0] = (t[A] and 0x80000000) or (t and 0x7fffffff)
k[1] = (k[0]/2) and t[C]

k0 and k1 are functions, working on a given table and tableentry.
Although they temporarily use values A,B and C, those are created by tableIndex.

uint32_t k0(uint32_t tableIndex, t_table previousTable);
uint32_t k1(uint32_t tableIndex, t_table previousTable);

where
A=n B=n+1 C=n+397 for 0 < = n < = 226
A=n B=n+1 C=n-227 for 227< = n < = 622
A=n B=0 C=396 for n = 632
small mistype here: last line should end with "for n=623", right?

and t[A],t,t[C] refer to the elements of the 0th table

When creating a new table, those have to refer to the elements of a previous table, right? For first created new table, this should be the 0th table, but later on the 0th table is not referred anymore...

the elements of the new table are formede as follows
Only previous table is needed, although k0 and k1 are used, they are calculated with the iterator.

t_table createNewTable(t_table previousTable);

In the end a total of M tables are formed (M can be choosen at free will)
I am very much puzzled by the "can be chosen at free will". If it's any relevance in the DS game, we should now where it is taken from. If it's of no relevance, then it's not really needed.

the IRNG is then formed as : S[(m-1)*624+n] = t[n] of the mth table
This very much looks like "first, table1 is cycled completely, then table2 is cycled completely, then table3..."
So the first random number is S(0) is t[0] of table 1? next random number is S(1) is t[1] of table 1 and random number 625 is S(624) is t[0] of table2?

This would also mean that after creation of table1, table0 is not needed any more and when table1 has cycled and table2 was created, we can purge table1 as well.

when the seed in the IRN is designated as E ( E = S(indices))
the PID is formed by means of an auxiliary 32 bit variable K[n] , n = 0,1,2; as follows
and then the PID is formed by taking the "random" number (E) and doing some more calculation.
k0, k1 and k2 are merely temporary variables here?

(I used a pseudo-programming syntax for better explaining)
To be honest, some of the pseudo-programming syntax more confused than clear things. You're writing arrays for simple temporary results; square braces as function parameters...

Don't get me wrong. I'm very thankful that someone figured it out at all and decided to post it here. Still at some points is seemed rather confusing.

Once my code works, is it okay to post it somewhere?

Greetings,

TCC
 

mingot

free agent
is a Site Content Manager Alumnusis a Battle Simulator Admin Alumnusis a Top Researcher Alumnusis a Contributor Alumnusis a Smogon Media Contributor Alumnusis an Administrator Alumnus
Not to discourage you from writing your own code, but it's a Mersenne Twister and if you google that you can find sample code x 2 in every language you could imagine. Also google has pretty clear pseudo code for re-implementing.

And yeah if you want to post source for an implementation, that's useful.
 
Sorry about the small mistakes, I simply translated it from a japanese article , when me and Mingot worked on it (via msn) we found several mistakes, and finally discovered that the algorithm was the well known Mersenn Twister...I thought it was pointless to edit that post ...eheeh
by the way did you see what I wrote in my last post?
 
So even D/P is broken like this? That's very interesting. After Emerald's broken RNG was discovered was D/P not checked? Are their seed generators similar? I doubt I'm using the right lingo for that last sentence...but hey, I'm trying to familiarize myself with it.
D/P is not really "broken. It's just that it can be figured out.
The broken-ness of Emerald was in the seeding the PRNG with 0 on every boot instead of using more random seed.

-TCCPhreak. Are you looking into the game code? If yes could you check how the ID and the Secret ID are created? maybe we can work out how to calculate the Secret ID from the ID and the game starting date...It would be awesome.
Seems like as soon as someone tells he looks into gamecode, suddenly many tasks arise that should be done. Mingot already wants me to figure out the synchro-pid-generation on chained shinys, I want to know more about the eggs and memory location. I have to agree that ID+SecretID would be very useful to know.

But I'd imagine that it's created very similar to PIDs and therefore comes from the seed at bootup (month*day+minutes+seconds)_(hour)...

Did anyone yet try to start a game as quickly as possible and then try with legit.exe whether trainer+secret ID might be the rolls of two early PRNG in sequence? (similar to PID generation on PRNG)

One could even misuse the RNG Generator for it. ;-)

I'm not at my emu-workplace, so I can't check into the creation right now, but checking for a seed might work.

Not to discourage you from writing your own code, but it's a Mersenne Twister and if you google that you can find sample code x 2 in every language you could imagine. Also google has pretty clear pseudo code for re-implementing.
english Wikipedia describes it as complicated as I can imagine, jonny's pseudocode seemd much more easier to understand. Also I sort of like it when I know the code in my tools by heart.

Found something that looks more friendly on german wiki, gotta try that - because my "jonny-2-code"-try didn't work.

Greetings,

TCC
 

mingot

free agent
is a Site Content Manager Alumnusis a Battle Simulator Admin Alumnusis a Top Researcher Alumnusis a Contributor Alumnusis a Smogon Media Contributor Alumnusis an Administrator Alumnus
@ TCC

For the Shiny PIDs for chains, I have finally found the generation method, so scratch it off the list ;) Unfortunately I can't see a way to get a PID for it so my dream of getting SID from a chained shiny is dead now.

You idea about the ID/Sid is interesting if an initial seed could be found for for your starter pokemon immediately after a new game and then using all the RNG calls between the initial seed and the starter to try and find the ones that were correct in the sequence. It would require people to start a new game for Shiny hatching, but for those with no other means for SID it would be worth it.

ALSO

TCC - This code a) sucks b) will only get the first 624 values.

Additionally it puts a lot of things in arrays that don't need to be in arrays, etc. It's just bad. :) And once I was satisfied that it worked I almost immediately switched to using a properly implemented version of MT instead of spending a ton of time fixing the one below. Hopefully this also gets you in the right direction.

It's the code that I wrote working with Jonny over the course of a very long morning.

Code:
            uint initialSeed = 0U;

            //  Our builder table.
            uint[] t = new uint[624];
            
            t[0] = initialSeed;

            for (uint cnt = 1; cnt < 624; cnt++)
            {
                t[cnt] = (0x6c078965 * (t[cnt - 1] ^ (t[cnt - 1] >> 30))) + cnt;
            }

            //  Start building out the S table, which we are going 
            //  to number with how many results we have.  Currently
            //  we will build multiples of these based on how many
            //  results we want to return.            
            uint[] a = new uint[624];
            uint[] b = new uint[624];
            uint[] c = new uint[624];

            for (uint n = 0; n < 624; n++)
            {
                a[n] = n;

                if (n <= 226)
                {
                    b[n] = n + 1;
                    c[n] = n + 397;
                }
                else
                {
                    if (n <= 622)
                    {
                        b[n] = n + 1;
                        c[n] = n - 227;
                    }
                    else
                    {
                        b[n] = 0;
                        c[n] = 396;
                    }
                }
            }

            uint[] d = new uint[624];

            for (uint n = 0; n < 624; n++)
            {
               
                uint k0 = (t[a[n]] & 0x80000000) + (t[b[n]] & 0x7fffffff);
                uint k1 = (k0 / 2) ^ t[c[n]];  

                if (k0 % 2 == 0)
                {
                    //  Even
                    d[n] = k1;
                }
                else
                {
                    //  Odd
                    d[n] = k1 ^ 0x9908b0df;
                }
            }

            for (uint n = 0; n < 10; n++)
            {
                uint p = d[n];

                p = p ^ (p >> 11);
                p = p ^ ((p << 7) & 0x9D2C5680U);
                p = p ^ ((p << 15) & 0xefc60000U);
                p = p ^ (p >> 18);

                Console.WriteLine(p.ToString("x"));
            }
 
Found something that looks more friendly on german wiki, gotta try that - because my "jonny-2-code"-try didn't work.

TCC
the Jonny2Code has at least 2 mistakes: an | must be replaced with a + and a & with a xor somewhere but I don't remember where...time has passed :D.
 
Does the seed you choose have to be the seed closest to the monster seed or can I choose say the 6th (that's say 32456) seed in a list of ten?
 

mingot

free agent
is a Site Content Manager Alumnusis a Battle Simulator Admin Alumnusis a Top Researcher Alumnusis a Contributor Alumnusis a Smogon Media Contributor Alumnusis an Administrator Alumnus
Why do you ask? I mean the directions say what a good seed should look like. And if you pick the wrong one (which the 6th, with 32546 will obviously be) you can't get a shiny ...
 
Not sure if this affects what you guys are doing (have not gone over everything) but the ARNG (what you guys call IRNG) is not just used for eggs. It is also what is used for mystery gift pokemon, shiny prevention, swarm route, great marsh pokemon, among other things.
 

mingot

free agent
is a Site Content Manager Alumnusis a Battle Simulator Admin Alumnusis a Top Researcher Alumnusis a Contributor Alumnusis a Smogon Media Contributor Alumnusis an Administrator Alumnus
So why are you calling it the ARNG? (Alternate?)

If this is what is used for mystery gift Pokemon then you have stumbled on something very interesting. Any documentation on this anywhere?
 
So why are you calling it the ARNG? (Alternate?)

If this is what is used for mystery gift Pokemon then you have stumbled on something very interesting. Any documentation on this anywhere?
At first ARNG was for Another RNG, but it seems now they are using it for Alternate RNG: http://projectpokemon.org/wiki/Notable_Breakpoints

There was in the article that SCV released for about mystery gift pokemon not being able to be shiny.
But they moved from pokesav.org and now we cannot access that article.
Your best bet is to talk to SCV

SCV posted this in tsanth's thread at gamefaqs:
Hey, tsanth, I have done some research regarding the generation of mystery gift pokemon.

Here is an article regarding the confirmation that they cannot be shiny: http://db.pokesav.org/main/?q=11-29-08-Mystery-Gift-PKMN-Cannot-Be-Shiny

For a bit of more technical data:

0x201BA10 -- Another RNG.
0x2068AAC -- Shiny Check for mystery gift pokemon

The seed for this RNG at 0x201BA10 is obtained from the half-words at 0x4000100 and 0x21D37B4.

Those two values are not related at all to the value of the seed for usual PRNG.

The value of the seed for the usual PRNG is used for the IVs as usual.
Man, the code for the IRNG was anything but convenient to sort out. Honestly, I think with that the goal was to actually make it harder. Even emerald runs differently for eggs.
Link to how emerald runs for eggs?
 

mingot

free agent
is a Site Content Manager Alumnusis a Battle Simulator Admin Alumnusis a Top Researcher Alumnusis a Contributor Alumnusis a Smogon Media Contributor Alumnusis an Administrator Alumnus
A few people here (Wichu/Pink) asked him to look into the Platinum/4th Gen Egg RNG a while back (as in a week or so ago) and he said he would look into it and not that it was already documented as this ARNG. So I dunno, I guess I will see if I can get in touch with him about it.

The seed for this RNG at 0x201BA10 is obtained from the half-words at 0x4000100 and 0x21D37B4.

This seems a little strange, though, as the MT does not have a simple seed that you can store in 32 bits.

One thing that is very interesting is his Shiny Prevention article mentions the Shiny check bug for hatches, as they test with the old OT and this is pretty much the same bug making things not look shiny on hatch. Always nice when observations line up.

Emerald Egg Question - Refer to Wichu or SCV.
 
A few people here (Wichu/Pink) asked him to look into the Egg RNG a while back (as in a week or so ago) and he said he would look into it and not that it was already documented as this ARNG. So I dunno, I guess I will see if I can get in touch with him about it.
My guess is he did not know it was used for eggs as well. I actually already know what he told Wichu and for emerald it was a seemingly similar proccess. I was just curious as to what you meant by different. Except in that case it was two instances of the same RNG, whearas here there are at least two RNGs.

The seed for this RNG at 0x201BA10 is obtained from the half-words at 0x4000100 and 0x21D37B4.
This seems a little strange, though, as the MT does not have a simple seed that you can store in 32 bits.
Well maybe the people who re-discovered this RNG have not gone as far SCV did. He figured out exactly where the seed comes from and where it goes since Sabresite was hoping there could be a legality check for mystery gift pokemon.

One thing that is very interesting is his Shiny Prevention article mentions the Shiny check bug for hatches, as they test with the old OT and this is pretty much the same bug making things not look shiny on hatch. Always nice when observations line up.
 

mingot

free agent
is a Site Content Manager Alumnusis a Battle Simulator Admin Alumnusis a Top Researcher Alumnusis a Contributor Alumnusis a Smogon Media Contributor Alumnusis an Administrator Alumnus
Er, but that's just the thing. MT is seeded one time only, it's not perpetually fed a seed (nor does it have a location where it need to 'store' its seed) on each iteration as the LCRNG. It actually has to build a table of 624 words.

It could be the location of the initial seed (same as the one used for the LCRNG) but then in that case it would never need to change.
 
Er, but that's just the thing. MT is seeded one time only, it's not perpetually fed a seed (nor does it have a location where it need to 'store' its seed) on each iteration as the LCRNG. It actually has to build a table of 624 words.

It could be the location of the initial seed (same as the one used for the LCRNG) but then in that case it would never need to change.
Well then, what happens is that the seed in not obtained in the same way in each case. Now, that I think about it, the seed for the marsh pokemon and swarm route is stored in the save.
 
mingoti had a question:
i downloaded that .NET file to load the RNG application but when i downloaded it it said thats it cant download because there is some clash or somethinig like that.What should i do?
 

mingot

free agent
is a Site Content Manager Alumnusis a Battle Simulator Admin Alumnusis a Top Researcher Alumnusis a Contributor Alumnusis a Smogon Media Contributor Alumnusis an Administrator Alumnus
@ ayush

"Or something like that" is about the most useless thing you could possibly tell me when trying to solve an installation problem, sorry.

@ hrc969

Ok, I went to the memory location listed @ 0201BA10 and described as "Alternate RNG used in some cases: Examples, PID generation for mystery gift pokemon, recalculating a PID after a failed shiny check, number which determines swarm pokemon and great marsh pokemon"

It is definately NOT the IRNG.

This routine is used, though, as part of the breeding process for international parents to alter pids to increase the chance of it being shiny.

Here is what it looks like in my code:

pid = pid * 0x6c078965 + 1;

It's basically another implementation of an LCRNG, I believe, with a different multiplier and increment.

It really looks like they might be calling the routine from a different entry point (or more likely have two implementations of this) one for just using r0 and applying the multiply and add and another for taking a seed for it.

Either way, these are not the droids you are looking for.
 
@ hrc969

Ok, I went to the memory location listed @ 0201BA10 and described as "Alternate RNG used in some cases: Examples, PID generation for mystery gift pokemon, recalculating a PID after a failed shiny check, number which determines swarm pokemon and great marsh pokemon"

It is definately NOT the IRNG.

This routine is used, though, as part of the breeding process for international parents to alter pids to increase the chance of it being shiny.

Here is what it looks like in my code:

pid = pid * 0x6c078965 + 1;

It's basically another implementation of an LCRNG, I believe, with a different multiplier and increment.

It really looks like they might be calling the routine from a different entry point (or more likely have two implementations of this) one for just using r0 and applying the multiply and add and another for taking a seed for it.

Either way, these are not the droids you are looking for.
Was that in DP or platinum?

The platinum one is at 0201D30C, I asked SCV if he could figure out the platinum one. The information I linked to/quoted was done when platinum was not out and had been updated for platinum.
 

mingot

free agent
is a Site Content Manager Alumnusis a Battle Simulator Admin Alumnusis a Top Researcher Alumnusis a Contributor Alumnusis a Smogon Media Contributor Alumnusis an Administrator Alumnus
@ hrc969 - I just did it in DP using the offset listed for DP for the ARNG. The offset for Platinum is simply the same routine at a new offset, I would think.

I used your Notable Breakpoints page to go look at the assembly for the routine.

It was definately x = x * 0x6c078965 + 1;

Which is definately NOT the IRNG.

So three RNGs.

I really can't be assed to go find the breakpoint for the IRNG as I already understand what it does, but someone who wants to see if it is used for anything other than egg PID generation might be interested in doing so.

Here is one intersting thought, though --

It's been said that this ARNG (in your linked material) generates the PID for wonder card pokemon. I wonder if that's really the case, now, or is it _only_ using this routine for PID modification to un-shiny them, when in fact, there was some earlier method used to create the initial PID. What makes me think it could be is that the IRNG actually uses this routine when you have parents from different regions in daycare to modify the PID (up to 3 times) to increase the chance of it being shiny.

So this really could just be some "shuffle pid" routine, which looks like an RNG on initial inspection, and kinda sorta acts like one, but has a very specific use.

EDIT MORE: 0x6c078965 is, oddly enough, one of MT's magic numbers. Course what they are doing with the number (iteratively multiplying it by the output of an MT in the case of egg PID generation) does not give the next number in the MT series. By a longshot. Still makes ya wonder why the picked that magic number.
 
@ hrc969 - I just did it in DP using the offset listed for DP for the ARNG. The offset for Platinum is simply the same routine at a new offset, I would think.

I used your Notable Breakpoints page to go look at the assembly for the routine.

It was definately x = x * 0x6c078965 + 1;

Which is definately NOT the IRNG.

So three RNGs.

I really can't be assed to go find the breakpoint for the IRNG as I already understand what it does, but someone who wants to see if it is used for anything other than egg PID generation might be interested in doing so.
OK, thanks for clearing that up.
 

Users Who Are Viewing This Thread (Users: 1, Guests: 23)

Top