- 119
- Posts
- 15
- Years
- Mt. Silver
- Seen Aug 4, 2024
So I have tried the best I could to figure this out by myself, but unfortunately to no avail. What started as a relatively simple XSE script has made me delve into the depths of RAM memory - which I, admittedly, do not fully understand. Help would be highly appreciated!
In short, I want the player to receive a Pokémon, which carries the (nick)name the player gave to the Rival in the introduction. (I won't go into detail exactly why, but let's just say the Rival naming sequence becomes the starter nicknaming sequence.) As I do not master ASM yet, I would like to try to do this fully in XSE. This post shows how to rename an obtained Pokémon to the Player's name through a simple XSE script. It does so by copying the bytes of the Pokémon's OT to the Pokémon's nickname.
This seems to work fine. I would like to do the same, but instead of the Player's (OT's) name, it would copy the Rival's name. I thought I could achieve this by finding the location of the Rival's name and replacing the offsets referring to the OT (in bold in the spoiler above) in the script with the offsets of the Rival's name. However, it does not seem to be that easy. I don't know which offsets to copy the bytes from.
This post contains a list/map of the RAM offsets, including the Rival's name. It explains that it is stored in the so-called Dynamic Memory Allocation (DMA) and that the actual offsets change all the time. An excerpt of the post is included below. A simple addition of 0x03005008 + 0x000039D4 = 0x030089DC is not succesful because the actual DMA pointers change while the game is running.
But perhaps there is a much easier solution. In this post, the user has a similar question but suggests it can be bypassed using "copyvar to 0x8005 or something" in XSE. But for this I still need to know the location of the variable containing the Rival's name...
I am pretty confused at this point. Is there an accessible point where the Rival's name is stored, which can be identified and copied? Given the frequency with which the name is invoked throughout the game, and with [rival] in message boxes, I would be surprised if this wasn't somehow possible. Many thanks in advance, and apologies if I missed something obvious!
---
PS: Other posts I used and thought could be relevant, but didn't want to go through in this post:
Bulbapedia information about the save data structure . It mentions the following:
This post by FBI which mentions the Rival's name is located in the EWRAM, which has offsets ranging from 0x02000000 to 0x0203FFFF.
This post contains an ASM script on renaming the Rival in the overworld. I can't read ASM, but it doesn't seem like any of the mentioned offsets can be used in the script. I have tried it with 0x03005008 which was unsuccesful.
Edit: This question is resolved, with thanks to DrFuji below.
In short, I want the player to receive a Pokémon, which carries the (nick)name the player gave to the Rival in the introduction. (I won't go into detail exactly why, but let's just say the Rival naming sequence becomes the starter nicknaming sequence.) As I do not master ASM yet, I would like to try to do this fully in XSE. This post shows how to rename an obtained Pokémon to the Player's name through a simple XSE script. It does so by copying the bytes of the Pokémon's OT to the Pokémon's nickname.
Spoiler:
Changing a Pokemon's nickname to the player's name is pretty simple to do through copying bytes in the the game's memory and easily be done in XSE. Here's a script that will give the player two Bulbasaurs and change the first one's name to the player's name:
Code:#dynamic 0x800000 #org @start setflag 0x828 givepokemon 0x1 0x1 0x0 0x0 0x0 0x0 givepokemon 0x1 0x1 0x0 0x0 0x0 0x0 copybyte 0x0202428C 0x02024298 copybyte 0x0202428D 0x02024299 copybyte 0x0202428E 0x0202429A copybyte 0x0202428F 0x0202429B copybyte 0x02024290 0x0202429C copybyte 0x02024291 0x0202429D copybyte 0x02024292 0x0202429E writebytetooffset 0xFF 0x02024293 writebytetooffset 0xFF 0x02024294 writebytetooffset 0xFF 0x02024295 end
In this script I'm copying the original trainer name from the Pokemon's data and overwriting the nickname data. As the trainer name can only be a maximum of seven letters we then need to pad the last three letters with 0xFF just in case the Pokemon's name is longer that that. If the Pokemon was traded it will have the trader's trainer name but it should be fine in 99% of cases. If the Pokemon you're trying to assign the name to isn't the first one in your party you will have to add 0x64 to each of the pointers for each Pokemon until you reach the party member you want to nickname. You could also give a Pokemon a static name just by using the writebytetooffset command if you wanted a Pokemon to have a specific name that wasn't the trainer's.
This script is designed for FireRed but it can be ported over to Emerald like this though I haven't tested it:
Code:copybyte 0x020244F4 0x02024500 copybyte 0x020244F5 [B]0x02024501[/B] copybyte 0x020244F6 [B]0x02024502[/B] copybyte 0x020244F7 [B]0x02024503[/B] copybyte 0x020244F8 [B]0x02024504[/B] copybyte 0x020244F9 [B]0x02024505[/B] copybyte 0x020244FA [B]0x02024506[/B] writebytetooffset 0xFF 0x020244FB writebytetooffset 0xFF 0x020244FC writebytetooffset 0xFF 0x020244FD
Hopefully that's what you're after!
This post contains a list/map of the RAM offsets, including the Rival's name. It explains that it is stored in the so-called Dynamic Memory Allocation (DMA) and that the actual offsets change all the time. An excerpt of the post is included below. A simple addition of 0x03005008 + 0x000039D4 = 0x030089DC is not succesful because the actual DMA pointers change while the game is running.
Spoiler:
MA - Dynamic Memory Allocation
Very important are the DMA save pointers at:
Here's the DMA structures. The memory positions are relative to the memory addresses that are saved at those DMA save pointer locations above. The DMA pointers change while the game is running, often when leaving buildings or exiting certain menus.Code:0x03005008 saveblock1_mapdata 0x0300500C saveblock2_trainerdata 0x03005010 saveblock3_boxdata
Sav1
Code:... 0x000039D4 rivals_name: .byte 8 dup(?) ...
...
Spoiler:
I have ASM code that needs to access a certain variable in the DMA, namely 0x4011, but as you probably know the actual location of this variable in the RAM changes all the time. I could (probably) get around this by using copyvar to 0x8005 or something before callasm-ing (as XSE script is evidently able to bypass this BS), but as this might not be an option in the future I wanted to know how seasoned ASM coders got around this, and the location of the IWRAM DMA cache (which contains pointers to each variable protected by DMA).
---
PS: Other posts I used and thought could be relevant, but didn't want to go through in this post:
Bulbapedia information about the save data structure . It mentions the following:
Spoiler:
Code:
RSE FRLG
Offset Size Offset Size Contents
N/A 0x0BCC 8 Rival name
Spoiler:
First of all, you'll notice that there are two sections of WRAM, which have been labeled. One is 32KB and the other is 256 KB. The 256KB of EWRAM is what's available for your game to use for its RAM data. For example: the save structures, player name, rival name, NPC states, malloc calls ect are all placed in this 256 KB RAM slot we call EWRAM.
This post contains an ASM script on renaming the Rival in the overworld. I can't read ASM, but it doesn't seem like any of the mentioned offsets can be used in the script. I have tried it with 0x03005008 which was unsuccesful.
Spoiler:
...
Code:
...
place: .word 0x080568E1
ramlocation: .word 0x03005008
standard: .word 0x00003A4C
actualroutine: .word 0x0809D955
rivalname: .word 0x08FFFFFF
Edit: This question is resolved, with thanks to DrFuji below.
Last edited: