Past Gen RNG Research

Currently in order to determine the time for RNG users have to repeat a process several times to determine their DS parameters. This is because the value of Timer0 seems to have a spread of 0x001.

Now while this leads to stable RNG abuse, I am wondering what causes the system to select from two different Timer0 values. Because if we could determine that, we would be able to reduce some of the trial and error for actually resetting for specific times.

Last night I was hunting down Zekrom and advancing PID frames to find a specific nature. What occurred to me was quite strange. Whenever I first set the DS system time to hit the desired RNG I consistently landed the Timer0 I had found to occur more than 75% of the time.

When I reset to that time, loaded the file and advanced the PID frame by saving once, it also worked fine.

It was after performing this save that I began to get stuck on my Timer0 that occurred less. Whenever I had saved, and the file had a time stamp in the future to that of the system time upon load, it would select the rarer Timer0. Repeating setting the system time, and loading the game a dozen times constantly had me hitting the rarer Timer0.

Setting the system time back before the save, loading, saving, and then updating to the desired time allowed me to hit the desired Timer0.

I repeated this, performing a different number of saves after loading. It was constantly reproducible.

I'm not sure if anyone else has seen something like this. Or if more is known about how the system picks between Timer0 values. While doing the parameter finding I thought it had to do with the ms delay on me launching the game. But having such a predictable recurrence last night makes me question that.
 

Bond697

Dies, died, will die.
is a Researcher Alumnus
the system isn't really "picking" between timer0 values. here's how it works:

timer0 is a fast timer that sits at 0x04000100 and it just counts from 0-65535 over and over. based on a control byte next to it(4000102), it runs at 1 of 4 different speeds. If you check the memory, the control byte is C1, which is F/64 for timer speed.(F = 16.78 mHz, the DS clock speed) 16.78mHz/64 == 262187 Hz, so 262.187 kHz meaning that it's doing 262187 cycles of 0-65535 per frame(i think, possibly per second?). anyway, that said, it's a very fast timer and the game is grabbing it at a given point in its advancement and using the value at that point as an encryption variable.

it seems that something causes the number grabbed to not always be the same, causes the DS to grab the value a small fraction of a second later. i personally think it's firmware-related, though there isn't enough data to say for sure.

keypress seems to affect some firmwares but not others. there are 6 firmwares for the nds/lite. the lite seems to just use v5, but i think there's some sort of minor revision or something, as some lites have 2 purple screens on checking the firmware and some have 1 purple and 1 magenta. i think one of these minor-revision firmwares is affected by keypresses and one isn't. aside from that, firmware v6 is unaffected by keypresses, v2 is affected(but only on certain keys), v1 was very similar to v2, and i think that's all i had data for.
 
Ah, so it was just timing going against me. I didn't have an AR or any other way to check the RAM of my DS, so I was just running off of the results.

it seems that something causes the number grabbed to not always be the same, causes the DS to grab the value a small fraction of a second later. i personally think it's firmware-related, though there isn't enough data to say for sure.
That's very plausible. You have the data that shows Timer0 is a time dependent seed. Differences in firmware can cause code execution at offset times. Basically you are looking at a race condition.

Getting the data to prove the firmware suspicion would be difficult. Considering that the RNG is already very useable I doubt it would be worth the effort to track down.
 

Bond697

Dies, died, will die.
is a Researcher Alumnus
basically, yeah. everything works as it is and the slightly varying timer0 doesn't really have much of an effect in the end. it really isn't worth pursuing due to the volume of work vs. the reward.
 

Bond697

Dies, died, will die.
is a Researcher Alumnus
(I think this deserves its own post)

So, there's been a LOT of talk about the different legendary pokes and whether they can or can't be shiny. Some people claim they can, some claim they can't, but no one has real "proof".

Code:
------------------------------------------------------------------------
legendary shiny check


020056FC F096ECB6 blx  #0209C06C      //switch to ARM, to 0209C06C

(rng.64bit.multiply())

02005700 6922          ldr  r2,[r4,#0x10]      //r2=1103b016(value @ 2216244), load value at 2216254 into r2(00269EC3)
02005702   6963          ldr  r3,[r4,#0x14]      //r3=ca0e2106(value @ 2216248),   load 02216258 into r3(aka, zero-out r3)--this word is always zero on   purpose, most likely
02005704   1810          add  r0,r2,r0             //add together r0 and r2(r2 is  b  in ax+b - 00269ec3)-add b to lower half of rng  to finish advancement
02005706 414B         adc  r3,r1                //add r3(zero) and r1(fa37b690)-this should be our new upper seed-output to r3
02005708   6020         str  r0,[r4]                //store the value at r4(lower   half rng) to r0 (possibly storing value of lower half rng to offset?)
0200570A   6063         str  r3,[r4,#0x4]       //store the value at r4+4(upper   half rng) to r3  (possibly storing value of upper half rng to offset?)
0200570C 2D00        cmp  r5, #0x0          //compare the value at r5(0x0) with 0 for( i = 0;i< 0; i++)
0200570E D101        bne #0x2005714      //false, no branch
02005714 6860         ldr r0,[r4,#0x4]         //load the value of the upper half of the rng state into r0
02005716 2100         mov r1, #0x0           //set r1 to 00000000
02005718 2300         mov r3, #0x0           //set r3 to 00000000
0200571A   1C2A        mov r2, r5                //move contents r5(0x0) to   r2
0200571C F096ECA6 blx  #0209C06C      //switch to ARM, skip branch, 
02005720 1C08     mov     r0,r1 //u32 of seed
02005722 BD38     pop     {r3-r5,r15} //jump to 20186F8

020186F8 1C04     mov     r4,r0 //save the seed to compare
020186FA E024     b       #0x2018746

02018746 9807     ldr     r0,[sp,#0x1C] //load the value of the stack pointer + 1C into r0
02018748 2800     cmp     r0,#0x0
0201874A D019     beq     #0x2018780

02018780 1C30     mov     r0,r6 // zero-out r6
02018782 1C21     mov     r1,r4 //getting ready to compute the shiny check
02018784 F7FFFBB6 bl      #0x2017EF4 // to 2017EF4!

02017EF4 4B08     ldr     r3,=#0xFFFF0000 //set #0xFFFF0000 to r3
02017EF6 040A     lsl     r2,r1,#0x10  //setting r2 to the lower half of the seed/pid
02017EF8 4019     and     r1,r3 // full pid AND FFFF0000 - set r1 = upper half of seed/pid
02017EFA 4003     and     r3,r0 //set the sid to r3
02017EFC 0400     lsl     r0,r0,#0x10 //set the tid to r0
-all 4 pieces are in place, right-shift everything to the lower 16 bits and start doing math-
02017EFE 0C1B     lsr     r3,r3,#0x10
02017F00 0C00     lsr     r0,r0,#0x10
02017F02 0C09     lsr     r1,r1,#0x10
-done prepping-
02017F04 4058     eor     r0,r3 // tid ^ sid 
02017F06 0C12     lsr     r2,r2,#0x10 //move the bottom half of the pid/seed to the l16 of the register
02017F08 4048     eor     r0,r1 //((tid ^ sid) ^ u16 pid)
02017F0A 4050     eor     r0,r2 //(((tid ^ sid) ^ u16 pid) ^ l16 pid)  
02017F0C 2808     cmp     r0,#0x8 //finish shiny check(less than 8 is a shiny)
02017F0E D201     bcs     #0x2017F14//false if shiny, keep moving!
02017F10 2001     mov     r0,#0x1 //set r0 to 1 for "pokemon is shiny" flag 
02017F12 4770     bx      r14

02018788 2801     cmp     r0,#0x1 // make sure r0 is 1 for the extra xor
0201878A D102     bne     #0x2018792 // false, keep moving
0201878C 2001     mov     r0,#0x1// for this is the start of the actual shiny prevention
0201878E 0700     lsl     r0,r0,#0x1C // set r0 to 10000000, get ready for shiny prevention xor
02018790 4044     eor     r4,r0 //full pid seed xor 10000000 to prevent shininess
02018792 2001     mov     r0,#0x1 //get ready for the 00010000 xor to create the pid
02018794 9906     ldr     r1,[sp,#0x18]
02018796 0400     lsl     r0,r0,#0x10 // make r0 00010000
02018798 1C22     mov     r2,r4 // set shiny-prevented pid to r2
0201879A 4002     and     r2,r0 //AND the pid with 00010000, resulting in 0
0201879C 0409     lsl     r1,r1,#0x10 //make r1 00020000
0201879E 428A     cmp     r2,r1 //gonna be 
020187A0 D000     beq     #0x20187A4 // 00010000 vs 00020000, not true, keep going
020187A2 4044     eor     r4,r0 // this is the final pid creation, shiny-prevented pid xor 00010000
020187A4 1C20     mov     r0,r4 //move the final pid to r0 for safe keeping :)
020187A6 BDF8     pop     {r3-r7,r15}

-here, the pid is loaded into 0225D950 and 0225DFC0, where it stays until capture.


OD EDIT: in short, there's a definite shiny check on Dragonspiral Tower Zekrom\Reshiram. Which we already knew, but it's good to look at the code just in case.
 

Kaphotics

Remodeling Kitchens
is a Researcher Alumnusis a Contributor Alumnus
Breeding Hidden Abilities

Turns out the Hidden Ability inheritance rate is actually 60% (not 40%). Hidden Ability is the official name for DW Ability.

The calculation is not:
if [n+3] * 5 >> 32 > 2 = Hidden Ability inherited

It is:
if [n+3] * 5 >> 32 > 1 = Hidden Ability inherited

Corrected the post on the breeding structure.

==

White Forest tidbits

  • Somewhat dependent PIDRNG Seed
    • Freezing the seed and moving the same direction that triggers an encounter yields the same Pokemon.
    • Moving/Turning changes what you get with the seed frozen.
  • Not dependent on time/delay elapsed (Other than PIDRNG Advancement). Seed freezing yields the same Pokemon as said above, no matter the time waited.
  • The first step into the patch does not always proc an encounter (it's not 100%).
  • I was able to freeze my direction via memory codes, it did not change the encounter if I entered sideways, thus the direction you face doesn't have an influence (doesn't seem like it)
 

Kaphotics

Remodeling Kitchens
is a Researcher Alumnusis a Contributor Alumnus
Species Determination of Nidoran♂/Nidoran♀ and Volbeat/Illumise
Data gathering by Tesseract\OmegaDonut, data analysis by Kaphotics

Green arrow'd is the frame the calc operates on, using the same calc as the everstone
Code:
u32*2>>32   === 0 or 1         or fullseed>>63
0 is Nidoran-F\Volbeat, 1 is Nidoran-M\Illumise


In gen 4, the species of the Pokemon was set upon egg generation. The egg PID was from the mersenne twister, and the Species were set. If I remember correctly, species would be the same no matter the PIDIV frame, thus it'd be determined from the Mersenne twister the egg PID was from. Eggs are grabbed from current frame +1 (0+1 usually),

this calc would probably be used on current frame +2 (0+2 usually) to determine the species.

If anyone really cares about it go ahead and try it, I haven't!
 

Bond697

Dies, died, will die.
is a Researcher Alumnus
the tid is generated in a way that isn't really predictable then the sid is generated later based on the main rng.

e:

basically, you know timer0? the one used in black and white? emerald uses timer1, which also counts 0-65535. when you get to the naming screen, timer1 turns on. when you finish naming, timer1 stops/its value is grabbed. that value is your tid. when you're entering the game, the rng is cycled twice and the u16 of the second seed is used for the sid.
 

ΩDonut

don't glaze me bro
is a Pokemon Researcheris a Programmer Alumnusis a Forum Moderator Alumnusis a Contributor Alumnus
the tid is generated in a way that isn't really predictable then the sid is generated later based on the main rng.

e:

basically, you know timer0? the one used in black and white? emerald uses timer1, which also counts 0-65535. when you get to the naming screen, timer1 turns on. when you finish naming, timer1 stops/its value is grabbed. that value is your tid. when you're entering the game, the rng is cycled twice and the u16 of the second seed is used for the sid.
So yeah, it is pretty possible to RNG for your ID\SID in Emerald, but INCREDIBLY difficult because of the fast-running timer. There's also no way to confirm you actually got your desired ID\SID without resorting to an AR or other hackish way of checking your SID.

You would need two separate timers, one for the ID and one for the SID.
 

Bond697

Dies, died, will die.
is a Researcher Alumnus
timer1 runs at 16.78 mhz in this case. that would be rather difficult to time, if it's possible at all. you would need precision to something extremely small.

the timer for the name in emerald is 64x faster than the one used in b/w. not that that means anything. just saying for a comparison.
 

Bond697

Dies, died, will die.
is a Researcher Alumnus
PID generation is something we've basically had down for awhile. I was fooling around with some other stuff, so I took a quick look to see if anything interesting was going on, just to see. Nothing super-interesting happens, though I guess 1 or 2 small pieces of what we're using can be fixed. That and I think we should be documenting exactly what the game is doing, not giving approximations.

Code:
----------------------------------------------------------------------------------------------------

standard 0x8 decision pid generation(btw, r6 is sidtid for basically this entire thing)

020056FC F096ECB6 blx  #0209C06C      //switch to ARM, to 0209C06C

(rng.64bit.multiply())

02005700 6922          ldr  r2,[r4,#0x10]      //r2=(value @ 2216244), load value at 2216254 into r2(00269EC3)
02005702    6963          ldr  r3,[r4,#0x14]      //r3=(value @ 2216248),    load 02216258 into r3(aka, zero-out r3)--this word is always zero on purpose, most likely
02005704    1810          add  r0,r2,r0             //add together r0 and r2(r2 is   b  in ax+b - 00269ec3)-add b to lower half of rng  to finish  advancement
02005706 414B         adc  r3,r1                //add r3(zero) and r1(fa37b690)-this should be our new upper seed-output to r3
02005708    6020         str  r0,[r4]                //store the value at  r4(lower half rng) to memory
0200570A    6063         str  r3,[r4,#0x4]       //store the value at r4+4(upper half rng) to memory
0200570C 2D00        cmp  r5, #0x0          //compare the value at r5(0x0) with 0 for( i = 0;i< 0; i++)
0200570E D101        bne #0x2005714      // false, no branch - this step seems to separate out pid gen from everything else.  r5==0 only on pid gen, it seems
02005714 6860         ldr r0,[r4,#0x4]         //load the value of the upper half of the rng state into r0
02005716 2100         mov r1, #0x0           //set r1 to 00000000
02005718 2300         mov r3, #0x0           //set r3 to 00000000
0200571A   1C2A        mov r2, r5                //move contents r5(0x0) to   r2
0200571C F096ECA6 blx  #0209C06C      //no branch

02005720 1C08     mov     r0,r1 //save that u32
02005722 BD38     pop     {r3-r5,r15} //jump to 20186F8

020186F8 1C04     mov     r4,r0 //save the seed to compare
020186FA E024     b       #0x2018746

02018746 9807     ldr     r0,[sp,#0x1C]  // value @ 2FE3604(0x2)
02018748 2800     cmp     r0,#0x0
0201874A D019     beq     #0x2018780
0201874C 2801     cmp     r0,#0x1
0201874E D002     beq     #0x2018756
02018750 2802     cmp     r0,#0x2
02018752 D01E     beq     #0x2018792   ;true

02018792 2001     mov     r0,#0x1
02018794 9906     ldr     r1,[sp,#0x18]
02018796 0400     lsl     r0,r0,#0x10 //prepping for base 0x00010000 xor
02018798 1C22     mov     r2,r4
0201879A 4002     and     r2,r0 //not understanding why it ANDs u32 by 10000, but r2 now == 0
0201879C 0409     lsl     r1,r1,#0x10
0201879E 428A     cmp     r2,r1 // same as with the legendaries, 10000 vs. 20000, not equal
020187A0 D000     beq     #0x20187A4 // false, no advancement
020187A2 4044     eor     r4,r0 // base xor by 00010000
020187A4 1C20     mov     r0,r4 // store this half-ready pid to r0 and save it...
020187A6 BDF8     pop     {r3-r7,r15}

021A9DB2 79A1     ldrb    r1,[r4,#0x6] //2FE36C4
021A9DB4 2902     cmp     r1,#0x2 // r1 = 0
021A9DB6 D012     beq     #0x21A9DDE // false, no branch
021A9DB8 6A2C     ldr     r4,[r5,#0x20] //load sidtid to r4
021A9DBA 0401     lsl     r1,r0,#0x10 //set the lower half of the temp pid to r1(u16 of r1, need to fix)
021A9DBC 0C0B     lsr     r3,r1,#0x10 // move the lower half temp-pid to the lower half of r3 to prep
021A9DBE 0421     lsl     r1,r4,#0x10 // separate tid and sid; this is tid
021A9DC0 0C22     lsr     r2,r4,#0x10 // sid is ready
021A9DC2 0C09     lsr     r1,r1,#0x10 // tid is ready
021A9DC4 4051     eor     r1,r2 // tid ^ sid
021A9DC6 1C1A     mov     r2,r3 // move lower 16 of pid to r2, get ready for next step
021A9DC8 404A     eor     r2,r1 l16 pid ^ (tid ^ sid)
021A9DCA 2101     mov     r1,#0x1 // r1 = 1
021A9DCC 4211     tst     r1,r2 // (tid ^ sid ^ l16 pid) & 1 (== 0 in my case)
021A9DCE D004     beq     #0x21A9DDA // resilve to 0, skip this
021A9DD0 2102     mov     r1,#0x2 // set up 0x8 xor
021A9DD2 0789     lsl     r1,r1,#0x1E  // r1 = 80000000
021A9DD4 B002     add     sp,#0x8
021A9DD6 4308     orr     r0,r1 // this is an OR, not XOR
021A9DD8 BD70     pop     {r4-r6,r15} //return
021A9DDA 4902     ldr     r1,=#0x7FFFFFFF // set up to finish the pid
021A9DDC 4008     and     r0,r1 // kill bit 31 if it's set
021A9DDE B002     add     sp,#0x8
021A9DE0 BD70     pop     {r4-r6,r15} // return


Anyway, here's what's happening:

-standard RNG multiply to advance
-save the u32 of the result
-02018746 is an interesting spot. it seems to be where the game decides what kind of pokemon pid it's creating. legendaries branch one way, wilds another. i'd wager the third is standing legendaries with no shiny check or possibly gifts, probably the former.
-so how does the game decide whether to OR(not XOR) with 0x80000000?
Code:
 -XOR tid and sid
  -XOR the lower half of the pid with that tid^sid result: (l16pid ^ (tid ^ sid))
  -AND that number with 1(tst r1, r2) and:
    -if it's 0, then AND with 0x7FFFFFFF
    -if it's 1, then OR(again, not XOR) with 0x80000000
After that, it does the normal shiny check and things progress normally again.
 
It was after performing this save that I began to get stuck on my Timer0 that occurred less. Whenever I had saved, and the file had a time stamp in the future to that of the system time upon load, it would select the rarer Timer0. Repeating setting the system time, and loading the game a dozen times constantly had me hitting the rarer Timer0.

Setting the system time back before the save, loading, saving, and then updating to the desired time allowed me to hit the desired Timer0.

I repeated this, performing a different number of saves after loading. It was constantly reproducible.

I'm not sure if anyone else has seen something like this. Or if more is known about how the system picks between Timer0 values. While doing the parameter finding I thought it had to do with the ms delay on me launching the game. But having such a predictable recurrence last night makes me question that.

I cant replicate the results. I have been using the same Time Seed: 86D7D1C43439124C starting frame 53, shiny frames 84 & 86 with a +1 shift depending on Dittos. This is on C7F. Load time 4/30 18:31, 20

I have used this solidly for maybe 2 weeks, messing around in game doing multiple breeds, lots of random saving etc.

Then all of a sudden, no matter what i do with the date stamp of the save i am suddenly only hitting C7E, and thats testing saving on a date before that date and then reloading, and then saving on a date after that and re loading. I just keep hitting the same C7E. Im stumped no matter what i do to try and get back to my great seed, i cant do it.

edit Live Update. Okay after more testing and using the cart in both DS;s and saving at various points, i conclude that the opening weather value effects which timer0 you will be using? Or is at least indicative of it. Before i was hitting Winter when starting the game, and hitting C7E and now im hitting Spring on the same time seed/date etc and i am now hitting the seed i intended, however i missed my frame by PIDframe 1 twice thingking i needed 31 not 30 chatots :( This tyranitar has taken forever.
 
timer1 runs at 16.78 mhz in this case. that would be rather difficult to time, if it's possible at all. you would need precision to something extremely small.

the timer for the name in emerald is 64x faster than the one used in b/w. not that that means anything. just saying for a comparison.[/QUOTEso it's not even worth trying it's extremely difficult..thanks guys

theoretical if i wanted to try how would now at wich second i would hit to get the pid and spread i wanted?
 

ΩDonut

don't glaze me bro
is a Pokemon Researcheris a Programmer Alumnusis a Forum Moderator Alumnusis a Contributor Alumnus
Flashback to 3rd gen:

Eep and I have been working on the possibility of RNGing for shiny eggs in Ruby\Sapphire. Emerald egg PIDs have been a tough nut to crack, but since egg PIDs aren't set the same way in Ruby\Sapphire, those should be easier to RNG. What's more, a copy of Ruby\Sapphire with a dead internal battery always has the same initial seed (0x5A0) so its RNG behaves like Emerald. So this should be pretty doable on an actual cart, once internal battery has run out. (We haven't tested if it also does this for a game without a fixed berry glitch.)

The moment the Day-Care Man starts holding an egg, the lower half of the egg PID is set, so any egg picked up will have a PID in the form ????XXXX, where XXXX is the set half. XXXX comes from the upper 16-bits of the RNG + 1. This means the Pokemon's ability is set once the egg is held.

According to Bulbapedia, the step counter for eggs is reset whenever you pick up an egg from the Day-Care Man (and we've proven this step counter is saved). So you could pick up an egg, walk 254 steps and end up one step in front of the Day-Care Man. If you take the 255th step at the right moment, an egg will be produced with your desired egg PID-half.

How would you know you hit it at the right moment? If your parents are of different species and have the same ID, the odds of the egg appearing are 20%, so if you miss the frame, you'll know based on the lack of egg. Most of the time. (Eep points out that you should approach the guy with a full party, so you can check if he's holding an egg without being forced to take it.)

Once the egg is set, you can RNG for the upper half of the PID, and do shininess. Harder to do than any shiny egg so far, but it's more doable on a real cartridge than Emerald. We're still working on inheritance, but that shouldn't be too hard.
 

ΩDonut

don't glaze me bro
is a Pokemon Researcheris a Programmer Alumnusis a Forum Moderator Alumnusis a Contributor Alumnus
More big news for people looking to legitimately breed shiny Pokemon on a cartridge: Without resorting to emulators or dozens of save files...

Emerald apparently has a second RNG that uses the same formula as the first. Like the first RNG, it has an initial seed of 0. However, it only starts running after you select Continue. When the Day-Care Man starts holding an egg, the PID is generated in the form XXXXYYYY, where XXXX comes from the second RNG and YYYY comes from the first RNG + 1.

It's tricky because you have to get the timing right for both the second RNG seed and the timing of the egg creation right, but shiny eggs in Emerald should also be doable.
 
It's from when you press Continue? I tested it ages ago, and found that hard-resetting made it consistent, implying it's something to do with the process of SRing (amount of time A+B+Start+Select were held?).
I'm more interested in how Everstone works in Emerald.
 

RockinX

My goal in life is to make everyone cringe with my puns
is a Contributor Alumnus
On that note, I think it'd also be interesting to know whether international parents affect the PID. It's a fact that the Everstone doesn't trick work with international parents.
 

ΩDonut

don't glaze me bro
is a Pokemon Researcheris a Programmer Alumnusis a Forum Moderator Alumnusis a Contributor Alumnus
It's from when you press Continue? I tested it ages ago, and found that hard-resetting made it consistent, implying it's something to do with the process of SRing (amount of time A+B+Start+Select were held?).
I'm more interested in how Everstone works in Emerald.
Just did some more testing. Looks like there are multiple versions of the US Emerald cart. The one I tested with has that second RNG running when you hit Continue. I dumped Wild Eep's Emerald cartridges, and they did not have that second RNG running. So I'm not sure where the other half of the egg PID comes from now.

Looks like Ruby\Sapphire is still our most realistic hope for shiny eggs in 3rd gen.

On that note, I think it'd also be interesting to know whether international parents affect the PID. It's a fact that the Everstone doesn't trick work with international parents.
I'm sure international parents + everstone work fine in 3rd gen. It only got broken in 4th gen because of the Masuda method, because the code to make PIDs shiny AND control the nature would've been very tricky. It was fixed again in 5th gen because nature and PID was made separate.
 

RockinX

My goal in life is to make everyone cringe with my puns
is a Contributor Alumnus
Just did some more testing. Looks like there are multiple versions of the US Emerald cart. The one I tested with has that second RNG running when you hit Continue. I dumped Wild Eep's Emerald cartridges, and they did not have that second RNG running. So I'm not sure where the other half of the egg PID comes from now.

Looks like Ruby\Sapphire is still our most realistic hope for shiny eggs in 3rd gen.



I'm sure international parents + everstone work fine in 3rd gen. It only got broken in 4th gen because of the Masuda method, because the code to make PIDs shiny AND control the nature would've been very tricky. It was fixed again in 5th gen because nature and PID was made separate.
I just tested it on my Emerald cart, and out of 13 eggs, eight of them had the Everstoned nature. I'm not sure why I remembered it not working.
 

Bond697

Dies, died, will die.
is a Researcher Alumnus
I may as well start throwing this stuff up here:

Item or Encounter Decision for Bridges

Code:
----------------------------------------------------------------------------------------------------------------------------
(bridge item/encounter) - driftveil


02005736 6863     ldr     r3,[r4,#0x4]
02005738 F096EC98 blx     #0x209C06C // switch to ARM, go forth and prosper to 0209C06C
-----RNG advancement here branch with link and exchange(link back to link register,  exchange- THUMB<->ARM)

(rng.multiply())
0209C06CE92D4030  stmfd r13!, (r4,r5,r14)   //push to the stack- highest to  lowest  registers(link reg, 0x64, lower half rng-location, not value)p
0209C070 E0845290  umull r5, r4, r0, r2       //mult.  r0 x r2, move result to r4/r5
0209C074 E0244390  mla   r4, r0, r3, r4       // seems to always resolve to 0
0209C078 E0244192  mla   r4, r2, r1, r4       // seems to always resolve to 0
0209C07C E1A01004 mov  r1, r4                 // (upper half of next rng seed is set)
0209C080 E1A00005 mov  r0, r5                 // (lower half of  next rng seed is set)
0209C084 E8BD4030 ldmfd r13!,(r4, r5, r14)//unwind the stack!  the math is done!
0209C088 E12FFF1E bx    r14                   //follow the link register home!(02005701)

0200573C 6922     ldr     r2,[r4,#0x10]
0200573E 6963     ldr     r3,[r4,#0x14]
02005740 1810     add     r0,r2,r0
02005742 414B     adc     r3,r1
02005744 6020     str     r0,[r4]
02005746 6063     str     r3,[r4,#0x4]
02005748 1C18     mov     r0,r3
0200574A 2100     mov     r1,#0x0
0200574C 2300     mov     r3,#0x0
0200574E 1C2A     mov     r2,r5
02005750 F096EC8C blx     #0x209C06C

//this is where does the u32 x1000 from the dust clouds.  it turns out a bit different in the end, though
64bit_Mult();

02005754 1C08         mov  r0, r1   // final result
02005756 BD38         pop  (r3-r5,r15)  // restore stack, jump back to restored r15

021AA9D0  0400        lsl        r0, r0, #0x10 // r0 = result of rng call for some range of values shifted left by 16 bits
021AA9D2  0C01        lsr        r1, r0, #0x10 // r1 == result shifted back down 16 bits  (upper 16 bits cleared)
021AA9D4  7B20        ldrb     r0, [r4, #0xC]  // r0 == value at 2257044
021AA9D6  2807        cmp    r0, #0x7 //  r0 == 7
021AA9D8  D10B       bne    #0x21aa9f2 // nope, branching down..
021AA9DA 29C8     cmp     r1,#0xC8 // 
021AA9DC D200     bcs     #0x21AA9E0 // branch if greater than or equal to 200dec - branch to a battle if less than 200(to 21AAA06)
021AA9DE E012     b       #0x21AAA06 // to 21AAA06

021AA9E0 F000FB56 bl      #0x21AB090

021AB090 B510     push    {r4,r14}
021AB092 24FA     mov     r4,#0xFA
021AB094 00A4     lsl     r4,r4,#0x2 // fa -> 3e8
021AB096 1C20     mov     r0,r4 // save 1000dec as an argument to pass to the multiplication/adv function
021AB098 F65AFB46 bl      #0x2005728 // to rng.advance to prep for item calc


--to battle if less than 200dec
021AAA06 1C28     mov     r0,r5 // r0 == 23647D8
021AAA08 2101     mov     r1,#0x1
021AAA0A F7FFFAA9 bl      #0x21A9F60
So, what is happening here:

Code:
-Advance the RNG using the 64-bit multiplication function
-Multiply the u32 of the RNG by 3E8(1000dec) then right-shift 32 bits
-If that result is under 200, you will encounter a poke.  If the result is 200 or greater, you will find a feather.
The item decision is just about done. It's sort of similar to dust cloud items. And just to note: yes, this means that you have an 80% chance of finding a feather when you run into a shadow on a bridge.

And here's the item decision
Code:
bridge item decision
----------------------------

02005736 6863     ldr     r3,[r4,#0x4]
02005738 F096EC98 blx     #0x209C06C // switch to ARM, go forth and prosper to 0209C06C
-----RNG advancement here branch with link and exchange(link back to link register,  exchange- THUMB<->ARM)

(rng.multiply())
0209C06CE92D4030   stmfd r13!, (r4,r5,r14)   //push to the stack- highest to  lowest   registers(link reg, 0x64, lower half rng-location, not value)p
0209C070 E0845290  umull r5, r4, r0, r2       //mult.  r0 x r2, move result to r4/r5
0209C074 E0244390  mla   r4, r0, r3, r4       // seems to always resolve to 0
0209C078 E0244192  mla   r4, r2, r1, r4       // seems to always resolve to 0
0209C07C E1A01004 mov  r1, r4                 // (upper half of next rng seed is set)
0209C080 E1A00005 mov  r0, r5                 // (lower half of  next rng seed is set)
0209C084 E8BD4030 ldmfd r13!,(r4, r5, r14)//unwind the stack!  the math is done!
0209C088 E12FFF1E bx    r14                   //follow the link register home!(02005701)

0200573C 6922     ldr     r2,[r4,#0x10] // put the rng back, get ready to do the standard u32 * XXX(or skip it for pid calcs)
0200573E 6963     ldr     r3,[r4,#0x14]
02005740 1810     add     r0,r2,r0
02005742 414B     adc     r3,r1
02005744 6020     str     r0,[r4]
02005746 6063     str     r3,[r4,#0x4]
02005748 1C18     mov     r0,r3
0200574A 2100     mov     r1,#0x0
0200574C 2300     mov     r3,#0x0
0200574E 1C2A     mov     r2,r5
02005750 F096EC8C blx     #0x209C06C

//this is where does the u32 x1000 same as the dust clouds.  it turns out a bit different in the end, though
64bit_Mult();

02005754 1C08         mov  r0, r1   // final result
02005756 BD38         pop  (r3-r5,r15)  // restore stack, jump back to restored r15

021AB09C 0400     lsl     r0,r0,#0x10  // clearing up the multiplied out result from u32 * X
021AB09E 0C00     lsr     r0,r0,#0x10 // /\
021AB0A0 3C64     sub     r4,#0x64 // 1000 - 100 == 900dec
021AB0A2 42A0     cmp     r0,r4 // compare the last u32 multiply with 900dec
021AB0A4 D20E     bcs     #0x21AB0C4 // branch here if greater than or equal to 900
021AB0A6 2496     mov     r4,#0x96 // r4(900dec) is done, set it to 0x96 and get ready to set it up for the next multiplier
021AB0A8 00A4     lsl     r4,r4,#0x2 // set r4 to 0x258(600dec)
021AB0AA 1C20     mov     r0,r4 // move the 600dec to r0 as an argument for the next multiplication
021AB0AC F65AFB3C bl      #0x2005728

--less than 900, so u32 * 600dec multiplier
rng.advance();
02005728 B538     push    {r3-r5,r14} // this all just sets up the rng for multiplication
0200572A 1C05     mov     r5,r0
0200572C 480A     ldr     r0,=#0x20AA1B4
0200572E 6904     ldr     r4,[r0,#0x10]
02005730 68A0     ldr     r0,[r4,#0x8]
02005732 68E1     ldr     r1,[r4,#0xC]
02005734 6822     ldr     r2,[r4]
02005736 6863     ldr     r3,[r4,#0x4]
02005738 F096EC98 blx     #0x209C06C

(rng.multiply())(via 64-bit multiply function)

0200573C 6922     ldr     r2,[r4,#0x10] // put the rng back, get ready to do the standard u32 * XXX(or skip it for pid calcs)
0200573E 6963     ldr     r3,[r4,#0x14]
02005740 1810     add     r0,r2,r0
02005742 414B     adc     r3,r1
02005744 6020     str     r0,[r4]
02005746 6063     str     r3,[r4,#0x4]
02005748 1C18     mov     r0,r3
0200574A 2100     mov     r1,#0x0
0200574C 2300     mov     r3,#0x0
0200574E 1C2A     mov     r2,r5
02005750 F096EC8C blx     #0x209C06C

u32 * XXX multiplier
rnd.calc();

02005754 1C08         mov  r0, r1   // final result
02005756 BD38         pop  (r3-r5,r15)  // restore stack, jump back to restored r15

021AB0B0 2164     mov     r1,#0x64  // r1 to 100dec
021AB0B2 F6F1E90A blx     #0x209C2C8

--switch statement?--
0209C2C8 E3510000 cmp     r1,#0x0 // r1 to 0 and then...
0209C2CC 012FFF1E bxeq    r14 // not equal, no branch
0209C2D0 E1500001 cmp     r0,r1 // r0 to r1 and then
0209C2D4 31A01000 movcc   r1,r0 // false
0209C2D8 33A00000 movcc   r0,#0x0 // false
0209C2DC 312FFF1E bxcc    r14 // false
0209C2E0 E3A0201C mov     r2,#0x1C 
0209C2E4 E1A03220 mov     r3,r0,lsr #0x4 // right-shift r0 by 4, place in r3 - knock off rightmost digit
0209C2E8 E1510623 cmp     r1,r3,lsr #0xC  (if r1 < 0)
0209C2EC D2422010 suble   r2,r2,#0x10 // r1 isn;t so don't
0209C2F0 D1A03823 movle   r3,r3,lsr #0x10 // same here
0209C2F4 E1510223 cmp     r1,r3,lsr #0x4  (if r1 < 1)
0209C2F8 D2422008 suble   r2,r2,#0x8 // don;t
0209C2FC D1A03423 movle   r3,r3,lsr #0x8 // no
0209C300 E1510003 cmp     r1,r3 (if r1 < r3)
0209C304 D2422004 suble   r2,r2,#0x4 // false
0209C308 D1A03223 movle   r3,r3,lsr #0x4 // false
0209C30C E1A00210 mov     r0,r0,lsl r2 // left-shift r0 by 28 bits, leaving just the lowest digit
0209C310 E2611000 rsb     r1,r1,#0x0 // this does the "opposite" subtract.  instead of 64-0, it's 0-64, leaving it as FFFFFF9C, not 64
0209C314 E0900000 adds    r0,r0,r0 // double r0- hasn't overflowed yet
0209C318 E0822082 add     r2,r2,r2,lsl #0x1
0209C31C E08FF102 add     r15,r15,r2,lsl #0x2 // i think this is sort of the "switch" part . 1c << 1 = 38 << 2 = E0 == 224dec; this tells it how much to skip.  add E0 to r15(program counter) to make it skip to a specific spot in the list -> to C474
0209C320 E1A00000 nop
0209C474 E0B13083 adcs    r3,r1,r3,lsl #0x1
0209C478 30433001 subcc   r3,r3,r1
0209C47C E0B00000 adcs    r0,r0,r0
0209C480 E0B13083 adcs    r3,r1,r3,lsl #0x1
0209C484 30433001 subcc   r3,r3,r1
0209C488 E0B00000 adcs    r0,r0,r0
0209C48C E0B13083 adcs    r3,r1,r3,lsl #0x1
0209C490 30433001 subcc   r3,r3,r1
0209C494 E0B00000 adcs    r0,r0,r0
0209C498 E0B13083 adcs    r3,r1,r3,lsl #0x1
0209C49C 30433001 subcc   r3,r3,r1
0209C4A0 E0B00000 adcs    r0,r0,r0 // last add with carry - single digit 
0209C4A4 E1A01003 mov     r1,r3
0209C4A8 E12FFF1E bx      r14

[b]
021AB0B6 0400     lsl     r0,r0,#0x10 // prepping result of adcs operations
021AB0B8 0C00     lsr     r0,r0,#0x10 // here too
021AB0BA 3C23     sub     r4,#0x23 // this is the 258(600dec) from the last u32 multiply calc-> gives us 258-23 == 235(value of the first wing in hex)
021AB0BC 1900     add     r0,r0,r4 // add result of the adcs calcs with the "base" wing value to give a wing hex number to give the player
021AB0BE 0400     lsl     r0,r0,#0x10 // prep result of operation
021AB0C0 0C00     lsr     r0,r0,#0x10 // still...
021AB0C2 BD10     pop     {r4,r15}
[/b]
---------------------------------------------------------------------------------------------------------
021AB0A4 D20E     bcs     #0x21AB0C4 // branch here if greater than or equal to 900

--if greater than or equal to 900
[b]021AB0C4 4800     ldr     r0,=#0x23B // this is the item to give if >=900 and then jump back to the program[/b]
021AB0C6 BD10     pop     {r4,r15}

--------------------------------------------------------------------------------------
So, what's happening here:
Code:
-If the item or encounter calc resulted in an item, continue to the RNG advancement function 
-After advancement, do u32 * 1000dec again
-If the result of this calc is 900 or over, the player receives a Pretty Wing
-If it is under 900, back to the RNG advancement function again
-After advancing, multiply the u32 by 600dec and run the result through the switch statement(I guess?)
-Once it's run through, add the result(number 0-6)  to 235, giving you a number 235-23A.  This number corresponds to the item you will receive
I'll provide some notes and an explanation in the morning. It's rather long and annoying. The only thing I will say quickly now is that once you hit that 80% chance of a feather, it's a 90% shot you'll get one of:

0235 Health Wing*
0236 Muscle Wing*
0237 Resist Wing*
0238 Genius Wing*
0239 Clever Wing*
023A Swift Wing*

and a 10% chance you'll get a Pretty Wing(023B).
 

Kaphotics

Remodeling Kitchens
is a Researcher Alumnusis a Contributor Alumnus
B/W Power Items and Breeding (Part 1)

Code:
2 Parents with Same Power Item. No Everstones Involved.
Frame	Seed				Description
========================================================
0	0F5F92C28B98DA7A		Initial
1	CA53C0F151B61AE5		IVs from MTRNG
2	4789469C09A6C81C		Species (unused)
3	C55D23C158CE8DCF		Nature (19=Rash)
[U]4	64477CF2C831586E		DW (1=no)       [/U]
5	CB7620F936F36029		IVP (1=F)
6	4D92C120D9C07FF0		IV# (1=Atk)
7	E0EDBA6AAD208873		[B]Power Item (1=Female, was HP, so F/HP)[/B]
8	B6F65E8FF626FF22		IV# (4=SpD)
[U]9	B130A6A44E00792D		IVP (1=F)     [/U]
10	D9393F74536A8284		PID (D9393F73)
11	B52DAA962AA0C0D7		Final Ending Frame

RNG Result: 
Rash NoDW 
[F/Atk , F/HP , F/SpD]  ==  F/F/S/S/F/S
D9393F73

========================================================

Ingame Result
Power Weight Present on Both Parents (HP IV inherited)
Rash 	NoDW	F/F/S/S/F/S   D9393F73
Code:
Power Inheritance, just like IVs
(FullSeed>>32) >> 31 == 0 or 1
0 - Male
1 - Female


What's different with a power item? It does the first part of the RNG like the breeding method, but the first two calls are in reverse; also instead of calculating a 2nd IV to inherit it calculates which parent gives the power item in case of both of them holding. It occupies one calc for the Parent, and then the Parent's Power Item dictates what IV is taken.

See Part 2 for the final verdict.
 

Kaphotics

Remodeling Kitchens
is a Researcher Alumnusis a Contributor Alumnus
5th Generation Held Item RNG




Achieved with KazoWAR's DeSmuME random encounter lua script, modded to yield Clefables all the time. Basically it just changes the encounter table for me so I will always encounter Clefables, it does not mess with the RNG at all.

The calc is not *100 in the memory, but whatever it is, it can be reduced down to this.

Information of the Calc was from the pokebw readme that gave the fishing hook and double battle proc-rate. (src). Since we are throwing out credits, Bond observed the missing calc frame (which is the sync calc) before I did.


Right after Nature,
((SEED>>32)*100) >> 32 == 0-99

Code:
[b][u]Without Compoundeyes[/u][/b]
 0-49 → 50%
50-54 →  5%
   55 →  1% --- Only in Dark ([i]double[/i]) Grass
56-99 →  No Inventory

[b][u]With Compoundeyes[/u][/b]
 0-59 → 50%
60-79 →  5%
80-84 →  1% --- Only in Dark ([i]double[/i]) Grass
85-99 →  No Inventory
Compoundeyes, you so silly.
60/20/5 instead of 50/5/1.

If you lead with Compoundeyes, the sync calc is skipped. Nobody really cares about synchronizing a Pokemon when trying to get a rare item though.
 

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

Top