• 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] What happens to unused code after you've compiled it?

  • 19
    Posts
    4
    Years
    • Seen Jan 9, 2022
    Hi all! Still new to this business of ROM hacking. So to my knowledge, when I create a script in XSE and batch/compile it into a ROM, the compiler finds a good spot in the hexadecimal bits of the ROM to place the new script in. Right? That's why the compiler gives you a 'Script offset' value to place in AdvanceMap--to lead the game right to that newly compiled script? So if that's true... what happens to scripts that don't end up getting used? If I try to make a script:

    • Make new script
    • Test it
    • It doesn't work, rewrite script
    • Test again, this time it works

    What happens to that first now-unused piece of code? Do I have to manually go back through the hexadecimal bits of my ROM file and turn it back into 0's? So new scripts can be dynamically compiled in that slot? Or is there an easy button that says, "Push this to reset all currently unused scripts"? Thanks in advance for a knowledgeable answer back. You guys have been really good to me! 😁
     
    The unused codes remain there in the original location where you compiled it. You can overwrite those bytes if you want but it is not recommended to do so as you can accidentally end up removing bytes important for game data and/or parts of some other script, unless you are absolutely 100% certain in what you are overwriting/removing.

    Usually the ROMs have quite a huge amount of unused safe space, which makes it okay to make errors several time and recompiling the same script multiple times without removing the old ones. And it takes quite a while to run out of these free spaces and so removing/overwriting old scripts aren't necessary quite often.

    However you can still choose to remove them. One thing you can do is open the script in XSE with refactoring turned off (see in Decompile Options) and your ROM in a hex editor, something like HxD. You will see parts of the scripts in XSE with #org 0xoffset in the start and go to those offsets in HxD and manually fill the bytes from there with "FF"s. If you have overwrote all the bytes in that place with FF, then you have successfully removed the script from existence and that space is once again free to use to compile another script. However, the issue is how many bytes you should replace with FF and how you can ensure that only the unwanted script is gone.

    In XSE, if you press F1, you can see that each command has a corresponding byte and there is a portion that explains how many bytes it takes for that command to be written. You can use these info. For example, the command setflag has a byte 0x29 and it needs 3 bytes. Of course because when you write something like 'setflag 0x828' in XSE and then compile it, the game translates it into three bytes: '29 28 08'. The first 29 tells the game that a flag needs to be set and the next two bytes tell the game which flag to set. Notice how the 0x828 becomes 28 08, you take two pairs of numbers and flip the pair of numbers. Another example is how 'goto 0x08AB69CD' becomes '05 CD 69 AB 08'

    The point is, if you have a script like this that you wanna get rid of:
    #org 0x168CAE
    compare 0x4056 0x0
    if 0x1 call 0x8168CBA
    end

    #org 0x168CBA
    sethealingplace 0x1
    return

    then going to 0x168CAE in HxD will show you these specific bytes: 21 56 40 00 00 07 01 BA 8C 16 08 02 and in 0x168CBA, you will see: 9F 01 00 03
    You can check byte by byte how the bytes correspond to the XSE commands but you can do this in short. You can see that the command 'compare' has a byte identity of 21, so '21 56 40' definitely means 'compare 0x4056' and 'end' is represented with a byte 02. Thus, if we replace all the bytes from 21 upto that 02, the entire first part of the script i.e. the part under #org 0x168CAE will be gone.

    Another way thing to do is the following. But first look at two different way to write the same script:
    Spoiler:

    The first way is how max times we write our scripts. XSE finds spaces starting from 0xA30000 and places the scripts in safe empty places converting them to bytes. However if you write the script like the second way, XSE puts the script at the location 0xA30000 forcefully regardless of whatever there was in the first place. You can use this to overwrite things that already exist in a certain address. And in my opinion: this is more dangerous to do than removing scripts with HxD mentioned above and must only be done if you are over 9000% sure about doing something this way.

    However, it is still handy if you want to make small byte changes. Say, there is a huge script where one line says: fadesong 0x1AB which means the background music fades to song no 1AB. But lets say, you dont want it to play song 1AB and instead want 10C to be played. So, you can open the script in XSE with refactoring turned off, goto the line with fadesong 0x1AB and replace it with fadesong 0x10C and click compile. Voila! You changed part of a script without taking up another big chunk of space! You can use it to fix these kinds of error in your codes. Like, say you accidentally put 'compare 0x4050 0x69' but you wanted to put 'compare 0x4050 0x2', etc.

    Sorry if this turned into a little too big of an essay xD I get carried away when I am talking about XSE :P
     
    Sorry if this turned into a little too big of an essay xD I get carried away when I am talking about XSE :P

    You've come to my aid once more! Don't apologize--if anything, I really appreciate this in-depth explanation. I like that you don't sugarcoat anything for a noob like me! Helps me learn a lot more quickly 😁 You've most definitely answered my inquiry. But, to follow up, now I'm curious: do you know just how many times you can slip up and "overwrite" code until you run out of space? I currently have three copies of a Fire Red ROM. One's for working on and experimenting with, one's going to be the "complete project" (only inserting the 100% tested code from the first copy), and the last is going to stay completely vanilla so I can compare my hack to the base game. Is that a good system? Or should I not even bother with that many backup plans? Thanks again for your time!
     
    You've come to my aid once more! Don't apologize--if anything, I really appreciate this in-depth explanation. I like that you don't sugarcoat anything for a noob like me! Helps me learn a lot more quickly 😁 You've most definitely answered my inquiry. But, to follow up, now I'm curious: do you know just how many times you can slip up and "overwrite" code until you run out of space? I currently have three copies of a Fire Red ROM. One's for working on and experimenting with, one's going to be the "complete project" (only inserting the 100% tested code from the first copy), and the last is going to stay completely vanilla so I can compare my hack to the base game. Is that a good system? Or should I not even bother with that many backup plans? Thanks again for your time!

    That definitely is a good system. Though time consuming, it does work. The only thing needed to be checked here is that the "experiment ROM" is up-to-date with the "complete project". Though I wouldn't bother doing this (since a ROM has a lot of free space, about 268,435,456 bits), you can do that if you feel comfortable.
     
    I'd just like to say the method of compiling scripts that I use:

    - Make a script with code that I want (first time most scripts won't work or will have some sort of error, or you'd like to delete it because you changed your mind)

    - If the script isn't the way we'd like it to be, there is a simple command in XSE that allows you to delete a script on a specific offset. This is useful because if we kept on compiling new scripts without deleting old ones, the space in the rom would get occupied with all those previous scripts that we don't need anymore. While using #dynamic 0x800000, XSE is looking for free space in this area, and since the first script was compiled at 0x800000, the second one would go to another free offset (0x800100 for example).

    Now on to the actual command, I'll use #dynamic 0x800000 for this example:

    #dynamic 0x800000
    #org @start
    lock
    faceplayer
    messagebox @t1 0x6
    release
    end

    #org @t1
    = Hi.
    '------------------- This is a simple script that you can assign to an NPC, let's say we want to remove it without compiling the slightly modified script after we changed it (because we want it to say something else)

    You can create a new window in XSE and type this. After typing it you save it and compile it when you want to delete the script.

    #removeall 0x800000

    '-------------- This will remove all data of the said script on that location, and the space can once again be used to write whatever you want there.
    The modified script:

    #dynamic 0x800000
    #org @start
    lock
    faceplayer
    messagebox @t1 0x6
    release
    end

    #org @t1
    = Hi. I am an NPC!

    '-------------- And the modifed script is written at 0x800000
     
    Sorry to revive such an old thread. I'm new to rom hacking and I recently learned of the "#removeall" command in XSE and it's definitely a life saver. Before I thought that if you compiled a script there was no way to remove it unless through HxD which if theres data written in the next block after the end of your script it would be almost impossible (at least for me cause I'm new to this) to find exactly where the script data ended to remove it. So I had to keep at least 2 backups of my rom at all times so I wouldn't "waste" free space. But thanks to "#removeall" I don't have to worry as much about wasting free space with scripts.
     
    Back
    Top