• 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.

Quick Research & Development Thread

RichterSnipes

Not even a nibble...
513
Posts
12
Years
  • Faster Game Saving [FR]

    Starting with Gen II, attempting to update the save on your current file would tell you that "There is already a save file. Is it OK to overwrite?" This needless extra step remained until Gen V, when it reverted the process back to one step.

    To skip this step and save after just one prompt, change the byte at 0x6F874 from 0A to 56. This only applies to saving over your current profile. If you start a new game and try to save over the old profile, you'll still receive the extended overwrite warning.

    Explanation: The subroutine at 0x6F86C gets loaded if the game detects there's already a save file. First it checks if the profile is different from the current one. If it's the same profile, it branches to 0x6F88C. This is indicated in hex by 0A D1. After branching, it'll load the "There is already a saved file" text string and corresponding subroutine.

    What this change does is make the game branch instead to 0x6F924, which bypasses the already-present save subroutine and skips straight to saving the game.

    I'm still not that good at ASM. If anything needs correcting, feel free to do so!
     
    124
    Posts
    8
    Years
    • Seen Apr 5, 2024
    I made a script with the help of some asm made by FBI, he had a custom wild battle asm that helped me create a very cool and desirable event where I give away a pokemon and in return I would get a perfect iv pokemon right back. I made this for FIRE RED obviously and here is the script I made and I need some help with one thing for perfection's sake.

    Spoiler:


    Now, what I need help with is that I used special 0xbb. It is supposed to store the pokemon I selected into daycare, how I do I delete the daycare stored pokemon so there is no choice of getting it back, the whole point I made this was to get rid of the imperfect pokemon to fight a perfect version of it to re-raise. Thanks guys!
     
    81
    Posts
    7
    Years
    • Seen yesterday
    Pointer to expand object effect tables and limiter:

    For Ruby:

    Table:

    AXVE- 0x1FCDE4

    Limiters:

    0x0803E2F8: 00 00 00 00

    For Fire Red:

    Table:

    BPRE- 0x2528BC

    Limiters:

    0x08042508: 00 00 00 00

    0x0804152C: 00 00 00 00

    Credits to: JPAN

    Spoiler:
     

    Dr. Seuss

    Will finish GS Chronicles, I swear!
    523
    Posts
    10
    Years
  • Update the AI Priority move effects table [FR]
    If you open a trainer editor and you edit aany trainer, you'll notice there's an option for "Trainer AI". By default, most of trainers are set in 0, and important trainers like Gym Leaders have this set to 7. There's a good explanation about how to setup the trainer AI in this post made by Samu from Whack a Hack forums (In spanish). Well, the point of this post is not that research.

    If you set the trainer AI to 7, any trainer with that AI will start the battle giving priority to some moves that set the battle, like poisoning your Pokémon, increasing their speed, attack stats, etc. There is a table of move effects located at 0x81DBAA7 with a set of 0x37 move effects that have priority over other move effects during the beggining of the battle. The table has the following entries.

    Code:
            .byte EFFECT_ATTACK_UP
    	.byte EFFECT_DEFENSE_UP
    	.byte EFFECT_SPEED_UP
    	.byte EFFECT_SPECIAL_ATTACK_UP
    	.byte EFFECT_SPECIAL_DEFENSE_UP
    	.byte EFFECT_ACCURACY_UP
    	.byte EFFECT_EVASION_UP
    	.byte EFFECT_ATTACK_DOWN
    	.byte EFFECT_DEFENSE_DOWN
    	.byte EFFECT_SPEED_DOWN
    	.byte EFFECT_SPECIAL_ATTACK_DOWN
    	.byte EFFECT_SPECIAL_DEFENSE_DOWN
    	.byte EFFECT_ACCURACY_DOWN
    	.byte EFFECT_EVASION_DOWN
    	.byte EFFECT_CONVERSION
    	.byte EFFECT_LIGHT_SCREEN
    	.byte EFFECT_SPECIAL_DEFENSE_UP_2
    	.byte EFFECT_FOCUS_ENERGY
    	.byte EFFECT_CONFUSE
    	.byte EFFECT_ATTACK_UP_2
    	.byte EFFECT_DEFENSE_UP_2
    	.byte EFFECT_SPEED_UP_2
    	.byte EFFECT_SPECIAL_ATTACK_UP_2
    	.byte EFFECT_SPECIAL_DEFENSE_UP_2
    	.byte EFFECT_ACCURACY_UP_2
    	.byte EFFECT_EVASION_UP_2
    	.byte EFFECT_ATTACK_DOWN_2
    	.byte EFFECT_DEFENSE_DOWN_2
    	.byte EFFECT_SPEED_DOWN_2
    	.byte EFFECT_SPECIAL_ATTACK_DOWN_2
    	.byte EFFECT_SPECIAL_DEFENSE_DOWN_2
    	.byte EFFECT_ACCURACY_DOWN_2
    	.byte EFFECT_EVASION_DOWN_2
    	.byte EFFECT_REFLECT
    	.byte EFFECT_POISON
    	.byte EFFECT_PARALYZE
    	.byte EFFECT_SUBSTITUTE
    	.byte EFFECT_LEECH_SEED
    	.byte EFFECT_MINIMIZE
    	.byte EFFECT_CURSE
    	.byte EFFECT_SWAGGER
    	.byte EFFECT_CAMOUFLAGE
    	.byte EFFECT_YAWN
    	.byte EFFECT_DEFENSE_CURL
    	.byte EFFECT_TORMENT
    	.byte EFFECT_FLATTER
    	.byte EFFECT_WILL_O_WISP
    	.byte EFFECT_INGRAIN
    	.byte EFFECT_IMPRISON
    	.byte EFFECT_TEETER_DANCE
    	.byte EFFECT_TICKLE
    	.byte EFFECT_COSMIC_POWER
    	.byte EFFECT_BULK_UP
    	.byte EFFECT_CALM_MIND
    	.byte EFFECT_CAMOUFLAGE

    The pointer of this table is located at 0x81DBA96 so you can repoint the table and add new entries to the table so trainers with a high Ai might use moves on this table firstly.
     

    El Diabeetus

    Amateur Voice Actor / ROM Editor ('Hacker')
    1,064
    Posts
    17
    Years
    • Age 30
    • Seen Jun 10, 2020
    I combined my work with the one from Doesnt. As a result, there are less bytes to write into freespace.
    So, here's what to do to give exp points when you catch a pokemon:
    1-The bytes to put into freespace: 2E E0 3F 02 02 00 2E 0C 3C 02 02 00 2E 0D 3C 02 02 00 23 00 F1 63 9A 1D 08 28 58 9A 1D 08

    2-The bytes to replace at 1D9A53: 41 XX XX XX 08 (XX = pointer to the code above).

    3-Just like Doesnt wrote earlier, replace the bytes at 15A68 with A1 5A 01 08.

    It should work without problems, as I tested it before posting.

    Thanks to Doesnt for telling me how to fix a music issue.
    Is there a way to get around Rattata appearing as the captured Pokémon if you have an extended Dex?
     

    colonelsalt

    Guaranteed to raise the smile
    111
    Posts
    11
    Years
  • [FR] Suppress Pokédex screen on new Pokémon capture
    To prevent the Pokédex screen/animation from showing after catching a new Pokémon, nop the 22 bytes at 0x106B7A (that is, up to and including 0x106B8F). This will jump straight to the nickname prompt after a new Pokémon is caught (but will still show the "Pokémon X was added to the Pokédex" text if left unedited).
     
    Last edited:

    Burtle

    Discord: Burtle#6904
    30
    Posts
    4
    Years
    • Seen Dec 8, 2019
    Change Vs Seeker Step Requirement (FR)
    Change 0x0810C50E to your number in hex
     
    Last edited:
    23
    Posts
    6
    Years
  • Is there a way to get around Rattata appearing as the captured Pokémon if you have an extended Dex?

    To prevent Rattata from appearing in the Pokedex and appearing the new captured Pokémon, you must expand the Habitats Table using a Hexadecimal editor and add each new Pokémon in the Habitats ... You can use PGE to add each new Pokémon to the habitats.

    To find out where the Habitats table is located, and to learn more about it, go to the Froosty The_learner post.
    FIRE RED habitat editing: https://www.pokecommunity.com/showthread.php?t=379667
     
    Last edited:
    31
    Posts
    6
    Years
  • Making the EVs more "RBY/GSC-like" on FireRed

    RBY and GSC are known for supporting "full EV spread", as the 510 EV limit didn't existed at the time. Bringing back the old Stat Exp system would be a very hard task, but I found a way to simulate the full EVs from past gens by limitting the max EV to 63 and reducing the EV divider from 4 to 1 (of course, removing the 510 EV limit would be a better solution, but I haven't found a way to do that with binary hacking).

    This solution works on FireRed.

    Step 1) Limit the EV cap to 63

    From Touched's tutorial:
    Address 0x0439FC = 0x3F (63)
    Address 0x043A02 = 0x3F (63)

    Step 2) Change EV divider to 1

    I owe this one to Mr.Pkmn posting the hex addresses to do that. In that case, he shows how to change the EV divider from 4 to 2.

    To make it 1, I have made some tests to find a value that A) stats would be correctly divided by 1 and B) would not screw up the stats (this one is dedicated to the HP EV divider).

    The values I found are completely empirical, I have no idea of why they have worked and I haven't found any glitches until now (I have not tested link battles on my hack yet).

    Here are the changes:

    Address 0x03E582 = 0x02 (HP)
    Address 0x03E5CE = 0x0F (ATK)
    Address 0x03E614 = 0x0F (DEF)
    Address 0x03E65A = 0x0F (SPD)
    Address 0x03E6A0 = 0x0F (SAT)
    Address 0x03E6E6 = 0x0F (SDE)


    Credits:
    - Touched
    - Mr.Pkmn
    ________________

    KNOWN PROBLEMS:

    About that 63 limit... well, a Pokémon won't get past it by gaining EV by battle. However, Vitamins (HP Up, Protein, etc.) will completely ignore that, so your HP can reach 100 EV with HP Up (and the same for other stats).
    For now, the best solution I have is to remove the access to every vitamin from the game with AdvanceMap, so you'll get EVs only by battle. I really don't know how to change the max EV you can get with vitamins (default = 100).
     
    Last edited:
    788
    Posts
    17
    Years
    • Seen yesterday
    Static Levels For In-Game Trades [FR]

    EDIT: Since this is just a simple byte change, I'm keeping this up, but I suggest you use this instead, which allows for this and more.

    Prior to Gen V, Pokemon you receive from in-game trades will be at the same level as the Pokemon you traded. From Black and White onwards, however, they come at a particular level. To get that in FR, simply make the following change:

    Code:
    0x08053B5E: 3A 20 28 5C C0 46 C0 46 C0 46 C0 46 C0 46

    To actually set the level for a particular Pokemon, you'll need a hex editor and a calculator. In an unmodified FR 1.0 ROM, sIngameTrades is stored at 0x0826CF8C. Each in game trade takes 0x3C bytes, and the level is stored at offset 0x3A from the start of the struct. So you'll need to calculate 0x0826CF8C + 0x3C * id + 0x3A, where id is the index of the in-game trade you're modifying (e.g. Reyley's Mimien is 0, and Norma's Tangela is 7). Pull up the resulting address in a hex editor, and modify that byte to set the level for that Pokemon.

    Since this uses some of the padding bytes in the existing struct which were zeroed out (because they were originally unused), you'll need to set levels for all of them or they'll come at level 0.

    If you have any problems, let me know.
     
    Last edited:
    5,256
    Posts
    16
    Years
  • [FR] Remove TM/HM PP replenishing
    If you want to port the behaviour of TMs/HMs' interaction with PP from Gen V+ to FireRed, where teaching a move retains its current PP, assemble and insert the following routine:

    Code:
    .thumb
    
    .equ free_space, 0x @ Replace with your desired address
    .equ move_data, 0x250C04 @ Replace with the address of your move data
    .equ rom, 0x08000000
    
    .org 0x124F48, 0xFF
    branch1:
        ldr r1, =(rom + hack1 + 1)
        bx r1
    .pool
    
    .org 0x125FC4, 0xFF
    branch2:
        ldr r1, =(rom + hack2 + 1)
        bx r1
    .pool
    
    .org 0x1260B4, 0xFF
    branch3:
        ldr r1, =(rom + hack3 + 1)
        bx r1
    .pool
    
    .org free_space, 0xFF
    hack1:
        mov r1, r0
        lsl r1, r1, #0x10
        lsr r1, r1, #0x10
        mov r0, r5
        mov r2, r4
        bl set_move_and_pp
        ldr r0, =(rom + 0x124F56 + 1)
        bx r0
    .pool
    
    hack2:
        mov r0, r9
        ldrh r1, [r0, #0xE]
        mov r0, r6
        mov r2, r5
        bl set_move_and_pp
        ldr r0, =(rom + 0x125FD0 + 1)
        bx r0
    .pool
    
    hack3:
        mov r2, r0
        lsl r2, r2, #0x18
        lsr r2, r2, #0x18
        mov r0, r4
        mov r1, r5
        bl set_move_and_pp
        ldr r0, =(rom + 0x1260C2 + 1)
        bx r0
    .pool
    
    set_move_and_pp:
        push {r4,r5,lr}
        sub sp, sp, #4
        mov r5, r0
        mov r4, r2
        mov r0, sp
        strh r1, [r0]
        lsl r4, r4, #0x18
        lsr r4, r4, #0x18
        mov r1, r4
        add r1, #0xD
        mov r0, r5
        mov r2, sp
        bl pokemon_setattr
    
        add r4, #0x11
        mov r0, r5
        mov r1, r4
        bl pokemon_getattr
        lsl r0, r0, #0x18
        lsr r3, r0, #0x18
    
        mov r0, sp
        ldrh r0, [r0]
        lsl r2, r0, #1
        add r2, r2, r0
        lsl r2, r2, #2
        ldr r0, =(rom + move_data + 4) @ move_data.pp
        add r2, r2, r0
        ldrb r0, [r2]
    
        cmp r3, r0
        blt dont_change_pp
    
        mov r0, r5
        mov r1, r4
        bl pokemon_setattr
        
    dont_change_pp:
        add sp, sp, #4
        pop {r4,r5}
        pop {r0}
        bx r0
    .pool
    
    pokemon_getattr:
        ldr r3, =(rom + 0x3FBE8 + 1)
        bx r3
    .pool
    
    pokemon_setattr:
        ldr r3, =(rom + 0x4037C + 1)
        bx r3
    .pool

    EDIT 1st June 2020: Added two other hooks which are needed to ensure the same behaviour is applied when the player skips the TM learning animation.
     
    Last edited:
    81
    Posts
    7
    Years
    • Seen yesterday
    Choice Specs [Ruby]

    Spoiler:


    Choice Scarf [Ruby]

    Spoiler:


    Light Ball [Ruby]

    Spoiler:


    I don't have the routine since I took the data from the mrdollsteak database and adapted it to ruby
     
    Last edited:
    760
    Posts
    15
    Years
    • Seen today
    Didn't see this documented anywhere, so I thought I should share it here.

    On the credits section in Fire Red:
    The maps shown in the credits section are determined by a table at 0x414588. It's a table with 13 pointers, starting at 0x4143e8. Every entry has a length of 0x20.

    The bytes that determine the starting point are as follows:
    0x3 = The map bank
    0x5 = The map number
    0x9 = X starting coordinate
    0xB = Y starting coordinate

    Byte 0x11 to 0x14 of the entry determines the direction in which the camera moves:
    00 00 01 00 = Down
    00 00 FF FF = Up
    01 00 00 00 = Right
    FF FF 00 00 = Left
    01 00 FF FF = Up-right Diagonally
    01 00 01 00 = Down-right Diagonally
    FF FF FF FF = Up-left Diagonally
    FF FF 01 00 = Down-left Diagonally

    That's all.

    Credits to Spherical Ice.
     

    RichterSnipes

    Not even a nibble...
    513
    Posts
    12
    Years
  • [FR] Remove TM/HM PP replenishing
    If you want to port the behaviour of TMs/HMs' interaction with PP from Gen V+ to FireRed, where teaching a move retains its current PP, assemble and insert the following routine:

    Spoiler:
    There's an issue with this ASM routine, and it's similar to something I recall happening years ago with a different piece of ASM code.

    If you press the B button to cancel out of the TM/HM "learning" animation, the PP amount for the taught move is completely filled up. I'm guessing that's not intended behavior?
     
    5,256
    Posts
    16
    Years
  • There's an issue with this ASM routine, and it's similar to something I recall happening years ago with a different piece of ASM code.

    If you press the B button to cancel out of the TM/HM "learning" animation, the PP amount for the taught move is completely filled up. I'm guessing that's not intended behavior?

    Ah, I missed two other places where I need to hook. This is the updated routine, I have edited my original post with this too:

    Code:
    .thumb
    
    .equ free_space, 0x @ Replace with your desired address
    .equ move_data, 0x250C04 @ Replace with the address of your move data
    .equ rom, 0x08000000
    
    .org 0x124F48, 0xFF
    branch1:
        ldr r1, =(rom + hack1 + 1)
        bx r1
    .pool
    
    .org 0x125FC4, 0xFF
    branch2:
        ldr r1, =(rom + hack2 + 1)
        bx r1
    .pool
    
    .org 0x1260B4, 0xFF
    branch3:
        ldr r1, =(rom + hack3 + 1)
        bx r1
    .pool
    
    .org free_space, 0xFF
    hack1:
        mov r1, r0
        lsl r1, r1, #0x10
        lsr r1, r1, #0x10
        mov r0, r5
        mov r2, r4
        bl set_move_and_pp
        ldr r0, =(rom + 0x124F56 + 1)
        bx r0
    .pool
    
    hack2:
        mov r0, r9
        ldrh r1, [r0, #0xE]
        mov r0, r6
        mov r2, r5
        bl set_move_and_pp
        ldr r0, =(rom + 0x125FD0 + 1)
        bx r0
    .pool
    
    hack3:
        mov r2, r0
        lsl r2, r2, #0x18
        lsr r2, r2, #0x18
        mov r0, r4
        mov r1, r5
        bl set_move_and_pp
        ldr r0, =(rom + 0x1260C2 + 1)
        bx r0
    .pool
    
    set_move_and_pp:
        push {r4,r5,lr}
        sub sp, sp, #4
        mov r5, r0
        mov r4, r2
        mov r0, sp
        strh r1, [r0]
        lsl r4, r4, #0x18
        lsr r4, r4, #0x18
        mov r1, r4
        add r1, #0xD
        mov r0, r5
        mov r2, sp
        bl pokemon_setattr
    
        add r4, #0x11
        mov r0, r5
        mov r1, r4
        bl pokemon_getattr
        lsl r0, r0, #0x18
        lsr r3, r0, #0x18
    
        mov r0, sp
        ldrh r0, [r0]
        lsl r2, r0, #1
        add r2, r2, r0
        lsl r2, r2, #2
        ldr r0, =(rom + move_data + 4) @ move_data.pp
        add r2, r2, r0
        ldrb r0, [r2]
    
        cmp r3, r0
        blt dont_change_pp
    
        mov r0, r5
        mov r1, r4
        bl pokemon_setattr
        
    dont_change_pp:
        add sp, sp, #4
        pop {r4,r5}
        pop {r0}
        bx r0
    .pool
    
    pokemon_getattr:
        ldr r3, =(rom + 0x3FBE8 + 1)
        bx r3
    .pool
    
    pokemon_setattr:
        ldr r3, =(rom + 0x4037C + 1)
        bx r3
    .pool

    Thanks for letting me know, and if there is anything else I've missed please let me know!
     
    Last edited:

    RichterSnipes

    Not even a nibble...
    513
    Posts
    12
    Years
  • Ah, I missed two other places where I need to hook. This is the updated routine, I have edited my original post with this too:

    Spoiler:

    Thanks for letting me know, and if there is anything else I've missed please let me know!
    That seemed to do the trick. Thank you so much! This is an incredibly helpful complement to the hacks using infinite TMs.
     
    Back
    Top