Jump to content

[Black/White] Locating PIDRNG Frame


lateralus

Recommended Posts

The past couple days I have been trying to find the address of this frame on desmume using its memory search. I have been mostly searching for increases in number of changes while advancing the frame with a chatot, also tried searching for values that are different by +1 from the previous but had no luck.

Any suggestions are welcome.

Link to comment
Share on other sites

If you are trying to RNG in your game by finding the frame given by the seed, I recommend RNG Reporter. It is perfect for a job like this. Just google it, and you'll find guides and even youtube videos for this, even for emulators. On RNG Reporter, it is almost always correct on the location of the starter frame the game starts on with the respective seed. Whats more, it has the pitch level of the Chatot's custom cry for each frame, making it easier to locate the frame you are on. Though for this, it takes a well trained ear. I hit my seed and frame almost every time because of this.

Link to comment
Share on other sites

If you are trying to RNG in your game by finding the frame given by the seed, I recommend RNG Reporter. It is perfect for a job like this. Just google it, and you'll find guides and even youtube videos for this, even for emulators. On RNG Reporter, it is almost always correct on the location of the starter frame the game starts on with the respective seed. Whats more, it has the pitch level of the Chatot's custom cry for each frame, making it easier to locate the frame you are on. Though for this, it takes a well trained ear. I hit my seed and frame almost every time because of this.

Thanks for the reply but I already know about all that. I am looking to find the address of this pidrng frame or seed so I can write AR to control it.

The reason for this is that when trying to catch (and not breed) shiny and flawless (i mean 31 on every single stat) it is almost impossible to find a seed that has a flawless iv spread on frame 1. If the flawless spread is anywhere other than frame 1 you can't advance both that frame AND the one that controls nature and shininess. Whenever you would advance the iv frame by 1 the other one would have advanced by 2*128 so hitting both frames isn't possible this way.

If I understood what Kaphotics said correctly then what I need to find is the address of the full 64bit seed.

Link to comment
Share on other sites

You can't edit the mersenne twister so you won't be able to get flawless stuff without editing.

Thats not the one I want to edit, I want to freeze the one that controls shininess so I can advance the iv one with steps and then separately advance the other with chatots. Is this also not possible ?

Even if it can't be done, I'd still be content with just being able to confirm I've hit the correct seed. Ive been thinking how I could find its location, one way would be to start the rom in desmume and save state then find the seed by calibrating the parameters in rng reporter and then load state and search for the seed I found but I have no idea whether I'd ever find the parameters on an emulator.

Link to comment
Share on other sites

So I take it I can't edit the PIDRNG "frame" either can I.

EDIT: In this case do you know whether theres a location that holds the frame each rng has been advanced to ? If I could see both frames in-game (but most importantly the pidrng) I should be able to advance the iv one first by moving pokemon into my party then going to the area I want to catch my pokemon at and advance the pid separately, I need to be able to see the pid frame count because of the wandering npcs.

Edited by lateralus
Link to comment
Share on other sites

EDIT: I have been comparing the prng frames (i'll be referring to the advancements as frames) I land on each time I hit the seed and go from the pokecenter to that area. Due to several wandering npcs the frame varies by a lot each time.

Is it possible for me to get something off the memory which I could then use to see which frame within the list I am on ?

EDIT 2: I just noticed the chatot pitches in rng reporter have numbers next to them. Im thinking those numbers should lie somewhere in memory each time, I'll start searching for them.

Edited by lateralus
Link to comment
Share on other sites

So I have found an 8 byte value at 02216224 (patched pokemon black) which changes whenever I view Chatot's summary. I assume it is related to PRNG but I still don't know what it is or how I can use it to determine the frame number on the list.

EDIT: It looks like its the actual PID seed and I can even freeze it then unfreeze it and advance it normally which is what I initially wanted. I would prefer to be able to determine which frame I am at instead of freezing it though, any tips on how I'd do that ?

Edited by lateralus
Link to comment
Share on other sites

Find the initial value it starts with, then use that as the seed. have a program seeded with that seed and have it advance until it matches the current value, the advances it took to get to the current value is the frames.

Does it necessarily have to be the initial seed or can any advancement of it be used to produce valid advancements.

Link to comment
Share on other sites

there's no such thing as "frame"

the seed in gen 5 is 64 bits (2 memory addresses long), UPPER_LOWER.

when the game needs a random value, it advances it and places a new magic number in its location. that new magic number is used for the next, and another new magic number will then be the next seed. it repeats.

seriously just look at RNG Reporter's researcher. also, freezing and editing memory locations is not called RNG abuse, it's hacking. you may be using RNG mechanics but you're hacking stuff to be the way you want it.

Link to comment
Share on other sites

Does it necessarily have to be the initial seed or can any advancement of it be used to produce valid advancements.

1. keep in mind, these random number generators are circular. you can get to any spot in the line from any other spot just by advancing enough. seed = seed * 0x5d588b656c078965 + 0x269EC3 (or any other lcrng) will loop after completing 2^64 advancements.

2. the concept of a "frame" isn't real. it's something used in reporter to count the number of advancements. frames = number of advancements, that's it. kazo's way of doing it is really the best. the only game that had an advancement counter was emerald. i wouldn't expect it to happen again.

3. whoever said you couldn't dick around with the seeds in the mersenne twister seed array was wrong. the seeds sitting in ram in the array aren't finalized. upon retrieval they are tempered like so:

RAM_ARM9:0203F1C4             getNextValue__:                         @ CODE XREF: mersenneTwisterHandler__+14j
RAM_ARM9:0203F1C4 00 C0 94 E5                 LDR     R12, [R4]       @ load the address of the top of the table into r12
RAM_ARM9:0203F1C8 3C 00 9F E5                 LDR     R0, =0x9D2C5680 @ tempering mask A
RAM_ARM9:0203F1CC C0 39 9C E5                 LDR     R3, [R12,#0x9C0] @ load the current word-aligned table pointer value into r3(we already know it's below 0x270, so still insde the current table)
RAM_ARM9:0203F1D0 38 10 9F E5                 LDR     R1, =0xEFC60000 @ tempering mask B
RAM_ARM9:0203F1D4 01 20 83 E2                 ADD     R2, R3, #1      @ counter++
RAM_ARM9:0203F1D8 C0 29 8C E5                 STR     R2, [R12,#0x9C0] @ now that 1 is added to the counter, the current position in our table is updated.  store the new value away for safe keeping.
RAM_ARM9:0203F1DC 00 20 94 E5                 LDR     R2, [R4]        @ load the address of the top of the table into r2
RAM_ARM9:0203F1E0 03 21 92 E7                 LDR     R2, [R2,R3,LSL#2] @ load into r2 the value of the top of the table + the table counter *4(word-aligned, so ((value*4) +top of table) gives you the current table position)
RAM_ARM9:0203F1E4 A2 25 22 E0                 EOR     R2, R2, R2,LSR#11 @ r2 = r2 ^ (r2 >> 11)
RAM_ARM9:0203F1E8 82 03 00 E0                 AND     R0, R0, R2,LSL#7 @ r0(currently 0x9D2C5680) = (r2 << 7) & 0x9D2C5680
RAM_ARM9:0203F1EC 00 20 22 E0                 EOR     R2, R2, R0      @ r2 = ((r2 << 7) & 0x9D2C5680) ^ r2
RAM_ARM9:0203F1F0 82 07 01 E0                 AND     R0, R1, R2,LSL#15 @ r0 = (r2 <<15) & 0xEFC60000 - eliminates the bottom half of the number
RAM_ARM9:0203F1F4 00 00 22 E0                 EOR     R0, R2, R0      @ r0 = r2 ^ r0
RAM_ARM9:0203F1F8 20 09 20 E0                 EOR     R0, R0, R0,LSR#18 @ r0 = r0 ^ (r0 >> 18)
RAM_ARM9:0203F1FC 10 80 BD E8                 LDMFD   SP!, {R4,PC}
RAM_ARM9:0203F1FC             @ End of function mersenneTwisterHandler__
RAM_ARM9:0203F1FC

so all you would need to do to get what you want is figure out what the seeds look like after tempering and change what you need wherever. easy.

4. one entire "pidrng frame advancement" is one run of seed = seed * 0x5d588b656c078965 + 0x269EC3. that's it. it's not half the seed or anything else. take the (big endian) number at 2216244 and feed the next 16 digits into that formula and you have 1 "frame" advancement.

5. no, those numbers with the chatot pitches don't exist in ram. od made those up to make figuring out the pitch easier. it's... ((seed >> 32) * 0x64) >> 32 and having that makes doing chatot pitches more manageable.

and finally:

when the devs need a random number, they use this:

static inline u32 Rand32(RandContext *context, u32 event)

the "context" thing is a way of naming and sorting the many random number generators they use in bw. when the rng is intialized it's given a context "name" sort of thing and each call afterward is referred to using that "name". it's really a pretty clever way to do it using cheap, easy to manage rngs. they're not great for generating random numbers, but they get the job done.

so they would do: (let's say i wanted a random number between 0 and 99)

Rand32(&mainRnd, 100)

and the game would do:

seed(this is the value at 2216244) = seed * 0x5d588b656c078965 + 0x269EC3

return ((seed >> 32) * 100) >> 32

which would give a value between 0 and 99(between 0 and event-1)

and also, there's a lot of info here:

http://projectpokemon.org/wiki/Notable_Breakpoints

Link to comment
Share on other sites

Alright so I wrote a code that retrieves the last 4 hex digits of the PID (practically the last 4 hex digits of the 32 bit high of the seed). The problem is that although the advancements the researcher produced were correct (they matched what my rom had in memory) they didn't match the ones produced by RNG Reporter (they had similarities though). For example :

Researcher:

1	CAD3B6CBD4F7E3CD	CAD3B6CB		
2	B5BAC926657733A4	B5BAC926		
3	70A364326C4CC277	70A36432		
4	5FEE31F053C206B6	5FEE31F0	
5	E45CED94D844AA91	E45CED94

RNG Reporter:

1	Mid-High (79)	5	5FEF31F0		Sassy		
2	Mid-High (70)	2	645DED94		Hardy		
3	Mid (43)	1	08A84BF2		Brave			
4	Mid-Low (37)	7	6848FC8A		Sassy		
5	High (89)	0	1701BBBE		Sassy	

Notice the relation between researcher's frame 4 and reporter's frame 1. The same seed was used to produce advancements in both the researcher and reporter. I tested this in-game and reporter's results are not correct, heres a screenshot of the reporter results in this case.

eOiZh.png

Bottom line, reporter fails to produce valid advancements. Does anyone know why ?

Also this is what I am trying to hit.

3v9pt.png

Edited by lateralus
Link to comment
Share on other sites

sigh you honestly have no idea what you are doing

just use ram watch and get experience with RNG on an actual DS. then read how PIDs are generated, because pid is not always = high32 of the seed.

Researcher just forecasts what seeds will appear, whereas Reporter forecasts what Pokemon you will get (given a starting point) at a given moment.

just plug in the current seed value from ram watch and you will be fine.

Link to comment
Share on other sites

I caught a pokemon after having reached the 319th advancement of the seed. The pokemon did not have bold nature nor was it shiny like it should be according to reporter. I then output 700 reporter results in a txt file and searched for the PID of the caught pokemon (I checked the PID using PokeGen after it was caught), the search had no results.

Needless to say I did hit the initial seed.

Link to comment
Share on other sites

If you did hit your seed and you did not get the result you were aiming for, there is a likely chance your frame was advanced by NPCs. They are rather annoying and quickly advance the frame if you are not careful or watchful.

You probably understand even less than I do lol. Determining the frame I am on by using the researcher is what I am trying to do. The NPCs always advance that frame but thats not the problem, if reporter produced valid results the PID of the pokemon I caught should have been found in the search I performed in my previous post.

EDIT: I finally managed to get this to work the way Kaphotics suggested, plugged the current seed from the researcher list into reporter. I still wonder why it failed to produce valid results with the initial seed though, could it be that it was one digit shorter than usual ?

Edited by lateralus
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...