• Our software update is now concluded. You will need to reset your password to log in. In order to do this, you will have to click "Log in" in the top right corner and then "Forgot your password?".
  • Welcome to PokéCommunity! Register now and join one of the best fan communities on the 'net to talk Pokémon and more! We are not affiliated with The Pokémon Company or Nintendo.

[ASM & Hex] Where is the shiny formula stored in Gen 3?

476
Posts
6
Years
    • Seen Feb 26, 2020
    I've been wanting to up the shiny encounter rate in my hack for a long while, but I really don't like using TSK's ShinyCC because it changes the way shininess is determined completely, which means true shinies may not show up as shiny. I want true shinies to keep their shininess in my hack, but still have the encounter of them to be higher, so where is the formula/function for shininess stored? I know that in BW/BW2, there's an offset that has the hex values 08 28, where 08 is how the shininess is determined (it's still 1/8192 because it's technically 8/65536) but one does not simply search for two bites in a ROM and expect that combination to only show up once (I tried that and it came up more than 10 times in the first 1/4 of the ROM). I am using FireRed for my hack but if possible it would be good to know/have the offsets for all the Gen 3 games, just for informational purposes.
     
    788
    Posts
    17
    Years
    • Seen today
    For Fire Red, you're looking for the byte at 0x08044120.

    If your desired shiny chance is n / 65536, then the byte should be equal to n - 1. For example, the vanilla game has 07 (for 8/65536); if you wanted 16/65536 like the newer games, you'd use 0F.

    Edit: To anyone finding this after the fact, you'll also need the changes noted here.
     
    Last edited:
    476
    Posts
    6
    Years
    • Seen Feb 26, 2020
    For Fire Red, you're looking for the byte at 0x08044120.

    If your desired shiny chance is n / 65536, then the byte should be equal to n - 1. For example, the vanilla game has 07 (for 8/65536); if you wanted 16/65536 like the newer games, you'd use 0F.

    Omg you are an actual livesaver! I've been looking for this for so long! Thank you! :D :D :D
     

    TaviTurnip

    Artist and Streamer | Also a turnip
    96
    Posts
    6
    Years
    • Seen yesterday
    This is actually useful for me too, haha. What a coincidence that someone would post about this today.

    If I can hijack this thread with a very similar question: is there a way in Gen III to give a specific trainer Pok?mon shininess? I've been looking all over the web and found nothing and no trainer-edit tools have a shiny button. Is there an easy byte to edit for this or a place to look for said byte?
     
    476
    Posts
    6
    Years
    • Seen Feb 26, 2020
    This is actually useful for me too, haha. What a coincidence that someone would post about this today.

    If I can hijack this thread with a very similar question: is there a way in Gen III to give a specific trainer Pok?mon shininess? I've been looking all over the web and found nothing and no trainer-edit tools have a shiny button. Is there an easy byte to edit for this or a place to look for said byte?

    This is something you *would* use Shinyzer for.

    Here's a tutorial I found a while ago that still works.

    https://www.youtube.com/watch?v=5bCg8pJ12hk
     
    476
    Posts
    6
    Years
    • Seen Feb 26, 2020
    For Fire Red, you're looking for the byte at 0x08044120.

    If your desired shiny chance is n / 65536, then the byte should be equal to n - 1. For example, the vanilla game has 07 (for 8/65536); if you wanted 16/65536 like the newer games, you'd use 0F.

    So, another question: Is it possible to reduce the maximum value? IE let's say I wanted more than 255/65536, is it possible to reduce the upper limit of the number to be something like 255/32768 or 255/16384? I know a 1/64 shiny odds is ridiculously extreme and unrealistic but all of my custom mons have shinies and I want the player to have a good chance at getting or seeing them. :)
     
    88
    Posts
    7
    Years
    • Seen Jan 16, 2020
    So, another question: Is it possible to reduce the maximum value? IE let's say I wanted more than 255/65536, is it possible to reduce the upper limit of the number to be something like 255/32768 or 255/16384? I know a 1/64 shiny odds is ridiculously extreme and unrealistic but all of my custom mons have shinies and I want the player to have a good chance at getting or seeing them. :)

    Yes, but you will probably need assembly knowledge. The formula/comparison looks as follows:
    Code:
    08044110      lsr r0, r1, #0x10
    08044112      ldr r2, [$0804412c] (=$0000ffff)
    08044114      and r1, r2
    08044116      eor r0, r1
    08044118      lsr r1, r3, #0x10
    0804411a      eor r0, r1
    0804411c      and r3, r2
    0804411e      eor r0, r3
    08044120      cmp r0, #0x7
    08044122      bls $08044134

    the cmp r0, #0x7 can only be increased to 0xFF, but you can modify this math formula to alter the numerator and/or denominator as you like.
     
    476
    Posts
    6
    Years
    • Seen Feb 26, 2020
    Yes, but you will probably need assembly knowledge. The formula/comparison looks as follows:
    Code:
    08044110      lsr r0, r1, #0x10
    08044112      ldr r2, [$0804412c] (=$0000ffff)
    08044114      and r1, r2
    08044116      eor r0, r1
    08044118      lsr r1, r3, #0x10
    0804411a      eor r0, r1
    0804411c      and r3, r2
    0804411e      eor r0, r3
    08044120      cmp r0, #0x7
    08044122      bls $08044134

    the cmp r0, #0x7 can only be increased to 0xFF, but you can modify this math formula to alter the numerator and/or denominator as you like.

    Hmm...I've already edited the numerator (since it's stored as a normal byte) but I have no knowledge of ASM or how to import it. At what point in this routine is the denominator stored?
     
    788
    Posts
    17
    Years
    • Seen today
    Hmm...I've already edited the numerator (since it's stored as a normal byte) but I have no knowledge of ASM or how to import it. At what point in this routine is the denominator stored?

    It's not. The denominator is implicit in the algorithm. It doesn't literally do a division.
     
    88
    Posts
    7
    Years
    • Seen Jan 16, 2020
    Ah, OK, so what exactly would the steps be if I wanted to make the 65536 lower?

    For this area of the ROM, you could make a routine that compares r0 to a different register. That would require inserting a hook to your custom code, though. Although this code only changes which palette is loaded, it doesn't actually make the pokemon shiny (aka no shiny star/summary box)

    To actually enforce a shiny pokemon, see this
     
    476
    Posts
    6
    Years
    • Seen Feb 26, 2020
    For this area of the ROM, you could make a routine that compares r0 to a different register. That would require inserting a hook to your custom code, though. Although this code only changes which palette is loaded, it doesn't actually make the pokemon shiny (aka no shiny star/summary box)

    To actually enforce a shiny pokemon, see this

    That looks incredibly helpful, but...

    a) it only seems to make the encounter rate 1/4096 (like Gen 6+), but by changing the "numerator" via a simple hex edit that we've already seen, I can already make it as high as 1/512, unless I'm just dumb and missing something, which brings me to point b

    b) I don't know anything about ASM, how to "compile" it, or how to insert it. Anything ASM (which I'd honestly like to avoid anyway) is literally another language to me, so apologies if I sound really stupid, lol
     
    88
    Posts
    7
    Years
    • Seen Jan 16, 2020
    That looks incredibly helpful, but...

    a) it only seems to make the encounter rate 1/4096 (like Gen 6+), but by changing the "numerator" via a simple hex edit that we've already seen, I can already make it as high as 1/512, unless I'm just dumb and missing something, which brings me to point b

    b) I don't know anything about ASM, how to "compile" it, or how to insert it. Anything ASM (which I'd honestly like to avoid anyway) is literally another language to me, so apologies if I sound really stupid, lol

    Unfortunately, you will need assembly to do what you are asking. The routine I linked has two different denominator values (it's for shiny charm). If you want a single, higher shiny rate, just remove the first section, "main", and replace
    Code:
    normal:
    	ldr r0, =(4096)
    with ldr r0, =(xxxx), where x is the denominator value you want (1/x)

    Check this post for learning how to compile. good luck.
     
    71
    Posts
    7
    Years
    • Seen Jul 11, 2022
    For Fire Red, you're looking for the byte at 0x08044120.

    If your desired shiny chance is n / 65536, then the byte should be equal to n - 1. For example, the vanilla game has 07 (for 8/65536); if you wanted 16/65536 like the newer games, you'd use 0F.
    I just found out changing it to 0x0F causes all Pokemon sprites to appear shiny in the Pokedex.
     
    Last edited:
    788
    Posts
    17
    Years
    • Seen today
    I just found out changing it to 0x0F causes all Pokemon sprites to appear shiny in the Pokedex.

    You also need to change 0x08104A24. This one isn't one less; so change it from 08 to 10 for 16/65536.

    Apparently, for the purposes of viewing them in the Pokedex, they're considered to have an OTID of 0 and a personality value of 8. That would result in 8 for the calculation, and guarantee that they wouldn't be shiny under normal conditions. But a result of 8 is shiny under our changed conditions and so they show up shiny.

    Edit: Someone pointed out to me that while the Pokemon will show up with their Shiny coloration, they won't have the shiny animation when being sent out or the differently colored frame they're supposed to on the Summary screen. To fix these, you'll need to modify the bytes at 0x080444B0 and 0x080F1776.

    They should both be equal to the byte at 0x08044120 ( n - 1 if you want n / 65536 as the chance).
     
    Last edited:
    476
    Posts
    6
    Years
    • Seen Feb 26, 2020
    You also need to change 0x08104A24. This one isn't one less; so change it from 08 to 10 for 16/65536.

    Apparently, for the purposes of viewing them in the Pokedex, they're considered to have an OTID of 0 and a personality value of 8. That would result in 8 for the calculation, and guarantee that they wouldn't be shiny under normal conditions. But a result of 8 is shiny under our changed conditions and so they show up shiny.

    So if I make the shiny chance 256/65536 (changing the original byte to 0xFF) ...how do I make them not show up as shiny in the Dex? For me personally, it doesn't matter, bu for others that might want more polish, they'd probably want to know :P (more than likely needs ASM afaik)
     
    476
    Posts
    6
    Years
    • Seen Feb 26, 2020
    Unfortunately, you will need assembly to do what you are asking. The routine I linked has two different denominator values (it's for shiny charm). If you want a single, higher shiny rate, just remove the first section, "main", and replace
    Code:
    normal:
    	ldr r0, =(4096)
    with ldr r0, =(xxxx), where x is the denominator value you want (1/x)

    Check this post for learning how to compile. good luck.

    Now that I think about it, isn't this just a manual version of TSK's ShinyCC?
     
    88
    Posts
    7
    Years
    • Seen Jan 16, 2020
    Now that I think about it, isn't this just a manual version of TSK's ShinyCC?

    It seems so. The utility of the assembly code I provided is that you can have different shiny rates, eg. a shiny charm. Not only that, but inserting code yourself means you are in charge of any changes, whereas with a tool you are in the dark with how the changes are being made.
     
    Back
    Top