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

Development: The Follow Me Script

Jambo51

Glory To Arstotzka
736
Posts
14
Years
    • Seen Jan 28, 2018
    I talked to Jambo, and he wants us to do a complete reboot of the project. His method, even though it worked, was very "clunky", and he is convinced there is a better way to do things. So, when I find some time, I'll be looking into it.

    As a further to this, if you don't manage to find a better way, I'll release my code to you guys. Seem fair?
     

    karatekid552

    What happens if I push it?....
    1,771
    Posts
    11
    Years
  • As a further to this, if you don't manage to find a better way, I'll release my code to you guys. Seem fair?

    Definitely fair. Since you have already done this, do you have any good ideas on alternate approaches? Your way involved writing directly to the OAMT states and manipulating the other sprite each frame. I have had thoughts of hacking the createsprite command so that it creates and then maintains a sprite one tile behind the player. On a warp, since there is no last tile, it wouldn't be loaded until the player steps off. And, if the player doubles back, then just swap their positions.
     

    Shiny Quagsire

    I'm Still Alive, Elsewhere
    697
    Posts
    14
    Years
  • Definitely fair. Since you have already done this, do you have any good ideas on alternate approaches? Your way involved writing directly to the OAMT states and manipulating the other sprite each frame. I have had thoughts of hacking the createsprite command so that it creates and then maintains a sprite one tile behind the player. On a warp, since there is no last tile, it wouldn't be loaded until the player steps off. And, if the player doubles back, then just swap their positions.

    What I was thinking is to just store the player's previous map coordinates every time they are changed and create/modify an overworld sprite accordingly. Because that's all the follow-me system really does is move where your player last was before.
     

    sab

    Now too much of a life.
    999
    Posts
    15
    Years
  • What I was thinking is to just store the player's previous map coordinates every time they are changed and create/modify an overworld sprite accordingly. Because that's all the follow-me system really does is move where your player last was before.
    That's what I was thinking, hence my extremely basic script posted a back on page five, but it has some problems. You'd also have to store when different types of motion were used, e.g. ledge jump, surf, etc. You'd also have to worry about things like warping. The coordinates would be located in the wrong place right after a warp unless you hid the sprite directly after a teleport. It seems to me like you'd also have to store all of the previous comparisons that were used for the player, then use them again, or just recalculate it entirely.
     
    Last edited:

    Blah

    Free supporter
    1,924
    Posts
    11
    Years
  • That's what I was thinking, hence my extremely basic script posted a back on page five, but it has some problems. You'd also have to store when different types of motion were used, e.g. ledge jump, surf, etc. You'd also have to worry about things like warping. The coordinates would be located in the wrong place right after a warp unless you hid the sprite directly after a teleport. It seems to me like you'd also have to store all of the previous comparisons that were used for the player, then use them again, or just recalculate it entirely.

    I would just omit surfing and warping for now. Once the more basic things are done, a warp can be solved by just calling the original code again with a new set of parameters. As for surfing...**** surfing.

    EDIT:
    My bad algorithm (I didn't bother to check if someone came up with this already, sorry):
    Have 4 variables change every time the player takes a step depending on the direction of the step. Darthatron and I had something that ran everystep and changed a variable, so this is easily possible. Something like:
    Player up: var1 is 0x1
    Player down: var2 is 0x1
    Player left: var3 is 0x1
    Player right: var4 is 0x1
    Note var 1,2,3,4 are set to 0x0 after the following sprite is moved.
    Now the sprite following the player is always behind the player, so set it to be Player (coord X-var3 + var 4) (coord Y-var2 + var1)

    This way we do 4 variable writes and 4 variable reads per step (not much right?). We can also figure out which walk animation to apply to the sprite too depending on which var is 0x1. Also if the player is just turning around, this doesn't move the sprite following him.
     
    Last edited:

    karatekid552

    What happens if I push it?....
    1,771
    Posts
    11
    Years
  • I would just omit surfing and warping for now. Once the more basic things are done, a warp can be solved by just calling the original code again with a new set of parameters. As for surfing...**** surfing.

    EDIT:
    My bad algorithm (I didn't bother to check if someone came up with this already, sorry):
    Have 4 variables change every time the player takes a step depending on the direction of the step. Darthatron and I had something that ran everystep and changed a variable, so this is easily possible. Something like:
    Player up: var1 is 0x1
    Player down: var2 is 0x1
    Player left: var3 is 0x1
    Player right: var4 is 0x1
    Note var 1,2,3,4 are set to 0x0 after the following sprite is moved.
    Now the sprite following the player is always behind the player, so set it to be Player (coord X-var3 + var 4) (coord Y-var2 + var1)

    This way we do 4 variable writes and 4 variable reads per step (not much right?). We can also figure out which walk animation to apply to the sprite too depending on which var is 0x1. Also if the player is just turning around, this doesn't move the sprite following him.

    I actually really like this, however 8 calls to the var decrypter every frame may be a lot. Idk. In which case, we could just use one var, and set bits, not bytes, or simply use a byte of RAM (which will be super fast to read and write to.)
     

    Blah

    Free supporter
    1,924
    Posts
    11
    Years
  • I actually really like this, however 8 calls to the var decrypter every frame may be a lot. Idk. In which case, we could just use one var, and set bits, not bytes, or simply use a byte of RAM (which will be super fast to read and write to.)

    You're right, the bits would be easier. Though I should mention it's every step, not frame :)
     

    Blah

    Free supporter
    1,924
    Posts
    11
    Years
  • Right, that is true. Now we need to find the routine that moves the player. Then we can branch it and use it to move other NPC's also.

    I think you're thinking too deeply into it. We don't need to branch from any player movement routine. We can simply branch from the routine that runs every step. If we branch from there, and know X,Y that the sprite needs to be at as well as the animation the sprite needs to do, then the problem is solved. It's been a while since I've done any ASM work, but the algorithm steps would be something like:


    --Stuff--
    --Start of routine per step--
    -- Branch @code --
    --Rest of routine per step -- (note this is stuff used by the game)
    -- Stuff --


    -- @code --
    step 1: assign variables in accordance to algorithm
    step 2: calculate x and y of sprite (note we don't need current sprite x and y, just player's x and y which is stored and easily locatable)
    step 3: move sprite to x/y and do animation <-- hard part? I think you should make a subroutine for this tbh.
    step 4: reset vars to 0
    step 5: return safetly

    EDIT: 06D5E8 was where the routine that activates every step was at. Well, I think it was there atleast :P
     
    Last edited:

    karatekid552

    What happens if I push it?....
    1,771
    Posts
    11
    Years
  • I think you're thinking too deeply into it. We don't need to branch from any player movement routine. We can simply branch from the routine that runs every step. If we branch from there, and know X,Y that the sprite needs to be at as well as the animation the sprite needs to do, then the problem is solved. It's been a while since I've done any ASM work, but the algorithm steps would be something like:


    --Stuff--
    --Start of routine per step--
    -- Branch @code --
    --Rest of routine per step -- (note this is stuff used by the game)
    -- Stuff --


    -- @code --
    step 1: assign variables in accordance to algorithm
    step 2: calculate x and y of sprite (note we don't need current sprite x and y, just player's x and y which is stored and easily locatable)
    step 3: move sprite to x/y and do animation <-- hard part? I think you should make a subroutine for this tbh.
    step 4: reset vars to 0
    step 5: return safetly

    EDIT: 06D5E8 was where the routine that activates every step was at. Well, I think it was there atleast :P

    No. This won't work easily. You see, sprites are drawn by pixel, not the X/Y blocks. The reason I want to use the original move player routine is because it will do all of those calculations for us. Converting pixels to blocks will be a pain in the butt. Trust me, I have seen the way Jambo did it, and that involved directly moving the sprites in the OAM registers, which are done by pixels. While this does work, it is what we want to avoid.

    "step 3: move sprite to x/y and do animation <-- hard part? I think you should make a subroutine for this tbh."

    Why write our own? The game already has one. Let's use it.
     

    Blah

    Free supporter
    1,924
    Posts
    11
    Years
  • No. This won't work easily. You see, sprites are drawn by pixel, not the X/Y blocks. The reason I want to use the original move player routine is because it will do all of those calculations for us. Converting pixels to blocks will be a pain in the butt. Trust me, I have seen the way Jambo did it, and that involved directly moving the sprites in the OAM registers, which are done by pixels. While this does work, it is what we want to avoid.

    "step 3: move sprite to x/y and do animation <-- hard part? I think you should make a subroutine for this tbh."

    Why write our own? The game already has one. Let's use it.

    Nonono, not make our own "move sprite" subroutine. I mean make our own subroutine that determines which "move sprite" to use (I.e which animation/direction). Catch my drift?

    Edit:

    "step 3: move sprite to x/y and do animation <-- hard part? I think you should make a subroutine for this tbh."
    I say we just run a script here that contains a single applymovement command on the following overworld.
    So the routine determines which applymovement script to run (possible? I think it is).

    EDIT2: Also if we were just using the original Player move routine then you'd still have to do calculations since the sprite is always BEHIND the player.
     
    Last edited:

    karatekid552

    What happens if I push it?....
    1,771
    Posts
    11
    Years
  • Nonono, not make our own "move sprite" subroutine. I mean make our own subroutine that determines which "move sprite" to use (I.e which animation/direction). Catch my drift?

    Edit:

    "step 3: move sprite to x/y and do animation <-- hard part? I think you should make a subroutine for this tbh."
    I say we just run a script here that contains a single applymovement command on the following overworld.
    So the routine determines which applymovement script to run (possible? I think it is).

    EDIT2: Also if we were just using the original Player move routine then you'd still have to do calculations since the sprite is always BEHIND the player.

    First, I want to see how the game moves the player. Maybe it is just an applymovement. In which case, we can simply write a routine which stores the past two movements of the player, and we read from the second one to determine the next movement of the follower.

    Here, set a break on the applymovement routine. See if it runs when you walk. It probably doesn't, but it is worth a shot.
     

    Blah

    Free supporter
    1,924
    Posts
    11
    Years
  • First, I want to see how the game moves the player. Maybe it is just an applymovement. In which case, we can simply write a routine which stores the past two movements of the player, and we read from the second one to determine the next movement of the follower.

    Here, set a break on the applymovement routine. See if it runs when you walk. It probably doesn't, but it is worth a shot.

    That actually sounds like a nice way to do it. Actually even if there is a small delay between the little sprite following, that'd still be a good first step. Wanna try it?
     

    Blah

    Free supporter
    1,924
    Posts
    11
    Years
  • Sure. In fact, a small delay would be cool, since it will look more realistic.

    Yeah, a delay is nice, but I want it to be smooth in the end. Where if I hold down the up button the hero continuously moves up rather than move up once, wait for sprite to catch up, move up again...sorta thing. Basically we don't want a lagging feeling.

    I'm a little cramped this Friday with academic activities, so lets try to get working early Saturday morning.
     

    daniilS

    busy trying to do stuff not done yet
    409
    Posts
    10
    Years
    • Seen Jan 29, 2024
    I have had an idea about how to do this. First, we have to assign a high, unused number to the following sprite. Then we have to create a branch to a subroutine directly after the hero proceeds to move. This is what it will look like, in this specific order:
    • Following disabled check
      Spoiler:
    • Surfing/biking check
      Spoiler:
    • Ledge jump check
      Spoiler:
    • Skip following and hidesprite check
      Spoiler:
    • Skip following check
      Spoiler:
    • Applymovement
      Spoiler:
    • Sprite existance check
      Spoiler:

    Another subroutine gets called AFTER the hero sprite has been moved. The only thing it does is making the following sprite face the player.



    I haven't tested it out myself, because I lack the ASM skills to do this. I may also have made some very stupid mistakes in this. However, I hope this helps towards creating a fully-working follow me script.(Or should I say routine?)
     

    karatekid552

    What happens if I push it?....
    1,771
    Posts
    11
    Years
  • I have had an idea about how to do this. First, we have to assign a high, unused number to the following sprite. Then we have to create a branch to a subroutine directly after the hero proceeds to move. This is what it will look like, in this specific order:
    • Following disabled check
      Spoiler:
    • Surfing/biking check
      Spoiler:
    • Ledge jump check
      Spoiler:
    • Skip following and hidesprite check
      Spoiler:
    • Skip following check
      Spoiler:
    • Applymovement
      Spoiler:
    • Sprite existance check
      Spoiler:

    Another subroutine gets called AFTER the hero sprite has been moved. The only thing it does is making the following sprite face the player.



    I haven't tested it out myself, because I lack the ASM skills to do this. I may also have made some very stupid mistakes in this. However, I hope this helps towards creating a fully-working follow me script.(Or should I say routine?)

    Your ideas sound good, but I think you are over complicating it. If the player move like I think it moves, then we just need to log movements, and apply them to a sprite following him. At that point, only a var is needed as to log the event number of the sprite to move and a boolean to say if it is active. This would eliminate the need for ledge, hidesprite, and existence checks. Until we know how the player moves, we can't move forward on this.
     

    ep!c

    Banned
    124
    Posts
    11
    Years
    • Seen Jan 4, 2015
    This would be much easier, if GBA would allow multithreading :P
    I give you a tip: calling the scripthandler instead of ASMing everything
    (like getplayerpos or applymovement), you save much time with it.
     

    karatekid552

    What happens if I push it?....
    1,771
    Posts
    11
    Years
  • This would be much easier, if GBA would allow multithreading :P
    I give you a tip: calling the scripthandler instead of ASMing everything
    (like getplayerpos or applymovement), you save much time with it.

    My goal is to do something of this sort, but first we need to know how to player moves. Then I can move the other character based upon the player's movements. I don't want to only use scripting commands because that can get clunky.
     
    Back
    Top