• 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?".
  • Forum moderator applications are now open! Click here for details.
  • 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
  • Age 24
  • 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