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

[Other] Random Trainer and Safe RAM offsets

45
Posts
14
Years
    • Seen May 20, 2015
    So I am trying to completely randomize a trainer. Name, class name, sprite, Pokemon party etc

    So far I have successfully created a routine that would copy random pokemon from a pokemon table into the RAM, and have a trainer's party initially point to the RAM offset. (Specifically 0x203C000)
    I've had success with the above since I can modify the pokemon table I made (in ROM) and it dynamically adjusts itself.

    However, I would like to know if there is any way you could randomize a trainer.
    I am thinking of repointing the trainer table into the RAM but that won't work since all trainers shall then be modified.

    Also, what are the safe offsets that can be used in the RAM? is 0x203C000 safe? I've seen it used by other routines here in PC.

    :(
     
    45
    Posts
    14
    Years
    • Seen May 20, 2015
    I don't know what malloc is.

    I just tried writing at 0x203C000 and it was working, but are there any other routines that write in that offset?
    Also, how can I write to ROM? The address pointing to the Trainers table is in the ROM. I'm thinking of repointing the Trainers Table to an address in the RAM before calling a trainerbattle then repoint it back.
     
    417
    Posts
    9
    Years
    • Seen Nov 20, 2016
    I don't know what malloc is.

    I just tried writing at 0x203C000 and it was working, but are there any other routines that write in that offset?
    That should be safe. Actually not 100% sure, I was thinking of another address. Also, if you haven't seen it (although it doesn't mention 0x203C000 and therefore doesn't help with this question), this is a useful post: https://www.pokecommunity.com/showpost.php?p=6856053&postcount=193 It should be noted that 0x0202402C starts to hold the enemy mons. I'm not sure what specifically that means as I've never touched trainer battles outside of trainer editors, but it might be useful to look into it.
    Also, how can I write to ROM? The address pointing to the Trainers table is in the ROM. I'm thinking of repointing the Trainers Table to an address in the RAM before calling a trainerbattle then repoint it back.
    How do you write to read-only memory? Let me know if you figure it out. In the meantime...for your problem...it sounds like you're doing a lot of unnecessary repointing? Can't you just have the randomization handled in a normal way, then have that read off of the trainer table? Even if you could, why would you even want to "write to ROM?" Maybe I don't understand what you're asking.
     
    Last edited:
    45
    Posts
    14
    Years
    • Seen May 20, 2015
    EDIT: Thanks for that link, was really helpful

    ^ Ya that question was stupid.
    I know it was read-only memory.

    I was successful with randomizing the Party poke of a trainer
    Here are screenies
    Random Trainer and Safe RAM offsets

    Random Trainer and Safe RAM offsets


    Basically, I write to 0x203C000 from a table of Random Pokes that I made in the ROM.
    Using G3Tools, I repoint a trainer's party offset to 0x203C000.
    Tthe number of Pokes is dependent on the settings of the trainer and Pokes with custom moves require 16 bytes each (instead of 8).

    Now, that works perfectly.
    But I want to randomize a trainer too, the Name, Class Name, Sprite etc,
     

    Touched

    Resident ASMAGICIAN
    625
    Posts
    9
    Years
    • Age 122
    • Seen Feb 1, 2018
    I don't know what malloc is.

    I just tried writing at 0x203C000 and it was working, but are there any other routines that write in that offset?
    Also, how can I write to ROM? The address pointing to the Trainers table is in the ROM. I'm thinking of repointing the Trainers Table to an address in the RAM before calling a trainerbattle then repoint it back.

    I always think people should know a little bit of C before hacking a C game, but for some reason few people share that opinion.

    Malloc allocates a block of memory and returns a pointer to that block. You free the block later when you are done with it. Both malloc and free are available in FR and Emerald.
     

    Blah

    Free supporter
    1,924
    Posts
    11
    Years
  • EDIT: Thanks for that link, was really helpful

    ^ Ya that question was stupid.
    I know it was read-only memory.

    I was successful with randomizing the Party poke of a trainer
    Here are screenies
    Random Trainer and Safe RAM offsets

    Random Trainer and Safe RAM offsets


    Basically, I write to 0x203C000 from a table of Random Pokes that I made in the ROM.
    Using G3Tools, I repoint a trainer's party offset to 0x203C000.
    Tthe number of Pokes is dependent on the settings of the trainer and Pokes with custom moves require 16 bytes each (instead of 8).

    Now, that works perfectly.
    But I want to randomize a trainer too, the Name, Class Name, Sprite etc,

    Looking at your screenshots, you're using 4 bytes for each field in RAM. You can cut this down to 2 bytes by using strh/ldrh instead. It seems to me that you've placed a hook at the Pokemon generation routine. Make sure that this is only affecting Pokemon accessed through battle, because if you placed the hook at the wrong place, then you will randomize all Pokemon in the game in general. Anyways, you can achieve this by using registers instead of RAM blocks.

    As for your question about trainer randomization, if you have tables with the information, it's just a matter of setting up a hook. Trainer data is read from a table. The data is derived given flag ID + start of trainer table's offset. Call the random function to replace the flag ID and change the start of the table to your custom table. It's that easy, though you may need to make a few tweeks to the format of your table (or you'll need to edit the routine to read your table properly).
     
    45
    Posts
    14
    Years
    • Seen May 20, 2015
    Thanks but I really haven't tried hooking. (No idea)

    Actually, those were 8 bytes long per Pokemon that's why there are 24 bytes there, signifying 6 Pokemon.
    I copied the format used by the trainers, and have a trainer's party point at 0x203C000 which initially is blank (zeros).
    Before calling the trainerbattle command, I run my asm routine that copies n number of random pokes from a table where each Poke is represented in 8 bytes each.

    How will I be able to repoint the table of trainers into the RAM if the offset that references it is in the ROM??
     

    Touched

    Resident ASMAGICIAN
    625
    Posts
    9
    Years
    • Age 122
    • Seen Feb 1, 2018
    Thanks but I really haven't tried hooking. (No idea)

    Actually, those were 8 bytes long per Pokemon that's why there are 24 bytes there, signifying 6 Pokemon.
    I copied the format used by the trainers, and have a trainer's party point at 0x203C000 which initially is blank (zeros).
    Before calling the trainerbattle command, I run my asm routine that copies n number of random pokes from a table where each Poke is represented in 8 bytes each.

    How will I be able to repoint the table of trainers into the RAM if the offset that references it is in the ROM??

    As FBI said, hook into the routine that reads the offset and change how it reads the data from the ROM table. I'm pretty sure there are guides on hooking, but here is the basic principle:
    You patch a routine so that it branches to your code. Then do whatever you want in your code before branching back. The general idea is to start with something that performs the same instructions as you patched over (essentially doing nothing differently except branching). Then after you have achieved this you start changing things.

    Start by finding your chosen hook location, then patch over with
    Code:
    ldr rX, =(0xADDRESS + 1)
    bx rX
    [CODE]
    
    This will take up 8 - 10 bytes depending on the alignment of the patch address, so make sure you have enough space. Choosing a good hook location is imperative - try to stay away from patching over branches and function calls, this will introduce unnecessary complications. The easiest way to hook is to find an existing LDR and replace the address it loads, and then patch the next instruction to BX to that address.
    
    After this, you just have to write your code to replicate the instructions you patched over and then branch back to an appropriate location. Remember not to use registers that are critical to the operation of the original code. There are a number of intuitive techniques to finding "open" registers to hook in. If you find yourself unable to only use open registers, make sure you push and pop some around your hook code.
     
    Back
    Top