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

[FireRed] Using flags for script tiles

Telinc1

Weirdo Extraordinaire
168
Posts
10
Years
  • Preamble
    Script tiles are a really wonderful thing. They let you run scripts when the player steps on them, making them an indispensable tool for revealing your game's plot. They have one major downside, however: you have to use variables for them and that is not ideal for many cases. Say you want an event to happen once and then never happen again, e.g. Oak leading you to his lab in the beginning of FireRed. If you want to do something like that, you need to waste an entire variable of which you'll only be using two values (probably 0 and 1). Because they have a big capacity (16 bits), there's way fewer variables than there are flags. Wouldn't it be great if you could control script tiles with flags? Oh, hang on...

    Prerequisites
    You should know how to assemble a routine, insert it into freespace and make a pointer to it. Basic knowledge of binary is recommended. Software-wise, you need an ARM assembler (GAS) and a hex editor.

    The routine
    With this routine, you'll be able to use flags for script tiles without giving up support for variables.
    Assemble and insert into aligned freespace:
    Code:
    .text
    .align 2
    .thumb
    .thumb_func
    .global triggerflag
    
    main:
        ldrh r0, [r4, #0x6]
        mov r1, #0x80
        lsl r1, #0x8
        tst r0, r1
        bne flag
        ldr r1, var_load
        bl linker
        lsl r0, #0x10
        lsr r0, #0x10
        b check
    flag:
        mvn r1, r1
        and r0, r1
        ldr r1, flag_load
        bl linker
    check:
        ldrb r1, [r4, #0x8]
        cmp r0, r1
        bne skip
        ldr r0, [r4, #0xC]
        b execute
    skip:
        mov r0, #0x0
    execute:
        ldr r1, return
    linker:
        bx r1
    
    .align 2
        var_load: .word 0x0806E569
        flag_load: .word 0x0806E6D1
        return: .word 0x0806DDB9

    After that, go to 0806DD9C (6DD9C in a hex editor) and type 00 48 00 47 FF FF FF 08, replacing FF FF FF 08 with the pointer to the routine + 1.

    Using the routine
    By default, script tiles will behave the same they did before. If you want a script tile to use a flag instead of a variable, you set the flag number's most significant bit (for the laymen, that means add 0x8000 to it) and put in the result as the variable number for the script tile. Set the variable value to 0 if you want the script to run if the flag is cleared. Set it to 1 if you want the script to run if the flag is set. Other values will make the script never run (probably, I haven't tested this scenario). That's all there is to it.

    In case you're wondering, sacrificing the MSB of the variable field shouldn't affect anything, as the only safe variables (0x40000x40FF and 0x50000x51FF if you've added the variable extension routine) do not have it set, and neither do any of the safe flags (0x200–0x2FF and 0x9000x18FF if you've added the flag extension routine), meaning that you can use all flags and variables for script tiles.
    Edit: 0x8000–0x8016 is also a valid range of variables. I've never seen them used for script tiles before, seeing as they're just temporary (they hold things like LASTRESULT, PLAYERFACING, etc.). You shouldn't ever need them outside of scripts.

    If this kills the game somehow, nag me about it. Credit highly appreciated, but not required.
     
    Last edited:

    Trev

    [span="font-size: 8px; color: white;"][font="Monts
    1,505
    Posts
    11
    Years
    • Age 27
    • Seen Nov 15, 2023
    You can literally use one variable for the entire game to cover every single script tile. All you have to do is increase the value by 0x1 using setvar every time you want a script to not happen again, and just set alter the value for each script tile to align with the changes in the variable. This isn't even useful in an open-ended hack with no linear progression, since you can just use a few more variables to handle deviations from the main path. All this does is waste an already small number of available flags on something that variables can do with extreme ease.
     

    Telinc1

    Weirdo Extraordinaire
    168
    Posts
    10
    Years
  • You can literally use one variable for the entire game to cover every single script tile. All you have to do is increase the value by 0x1 using setvar every time you want a script to not happen again, and just set alter the value for each script tile to align with the changes in the variable. This isn't even useful in an open-ended hack with no linear progression, since you can just use a few more variables to handle deviations from the main path. All this does is waste an already small number of available flags on something that variables can do with extreme ease.
    I have considered and tried the first variant on my hack and it turned into a mess (thankfully I only did it up to the first Gym). The entire thing had to be completely linear and to this day I have a level script I can't remove, the sole purpose of which is just to simply increase the global variable in order to account for an event which was removed. The one variable approach is simply not useable if you want any kind of more complicated non-linear progression.
    Also, this routine is mainly meant to be combined with Jambo51's flag extension routine, which makes flags 0x900–0x18FF safe to use (that's a little over 4000 flags). When compared to the amount of safe variables (a little under 800 with the variable extension, not taking into account the ones used by the game engine), you can see just how much more efficient it is to use flags.
    That's just what I think. If you don't want to use the flag extension (I could think of a few reasons why you wouldn't want to), it is of course better to use variables. In the case of my project, this is better and I decided to release it in case someone else decides to use it too.
     

    Trev

    [span="font-size: 8px; color: white;"][font="Monts
    1,505
    Posts
    11
    Years
    • Age 27
    • Seen Nov 15, 2023
    About non-linear games:
    This isn't even useful in an open-ended hack with no linear progression, since you can just use a few more variables to handle deviations from the main path.

    In your situation, all you would have to do is go back to each event that uses the variable up to the one event you removed and then edit the value of setvar both in the script and on the tile properties itself down by 0x1 for each event in the order that it happens. Granted, it might be a bit time-consuming, but a.) what thing in ROM hacking isn't time consuming? b.) it's safer than accidentally altering core data by inserting this routine.

    It's up to an individual, ultimately, but it just seems highly unnecessary to me, since flags are extremely valuable for moving/hiding overworld sprites and wasting them on script tiles, even with expanded flags, seems like a bad idea. This might be useful if someone has a ton of branching storylines (like more than, say, 5), but otherwise this... doesn't really serve much purpose outside of fixing your own, individual problem. :v But, it's not my tutorial, so if you think that it's worthwhile to be here, it has a place. Someone might find some use out of it.
     

    Telinc1

    Weirdo Extraordinaire
    168
    Posts
    10
    Years
  • About non-linear games:


    In your situation, all you would have to do is go back to each event that uses the variable up to the one event you removed and then edit the value of setvar both in the script and on the tile properties itself down by 0x1 for each event in the order that it happens. Granted, it might be a bit time-consuming, but a.) what thing in ROM hacking isn't time consuming? b.) it's safer than accidentally altering core data by inserting this routine.

    It's up to an individual, ultimately, but it just seems highly unnecessary to me, since flags are extremely valuable for moving/hiding overworld sprites and wasting them on script tiles, even with expanded flags, seems like a bad idea. This might be useful if someone has a ton of branching storylines (like more than, say, 5), but otherwise this... doesn't really serve much purpose outside of fixing your own, individual problem. :v But, it's not my tutorial, so if you think that it's worthwhile to be here, it has a place. Someone might find some use out of it.
    I totally understand you. Not everyone can benefit from this, that's obvious. It could still be useful to someone other than me, just as you said.
    In my case, I couldn't change the scripts, because I had already released a demo version and changing the order might have had potential to break save files, which is something I don't like to do.
     

    BluRose

    blu rass
    811
    Posts
    10
    Years
  • i think this is pretty legitimate ahaha
    i always remember thinking that the whole var usage thing was tedious but ever considered using flags, rip me :P
     
    Back
    Top