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

[Pokeemerald] Applymovement vs A* Algorithm for Pathfinding

8
Posts
6
Years
  • Age 30
  • Seen Nov 22, 2022
THIS RESEARCH IS UNDER DEVELOPMENT, SO IS NORMAL THAT IS FULL OF BUGS


Hi, I am quite new in the world of disassembly but I am working in some research fields:

This is one of my recent ones: The use of Artificial Intelligence to perform the applymovements automatically and online in-game.
It contains an implementation of a Dijkstra algorithm with informed heuristics (A*) that can make easy some Applimovements in the scripts:
https://github.com/J2M2/pokeemerald/tree/path_planner

4bb840f9e7b151bb732a3a44f7f44183.png
5f904ffb09689b0ff1a44c489e318187.gif


Adding an obstacle in the map editor changes the trajectory without change the script!
836e0e60d6f6d5d98896afa703b87cbe.gif


Features:
  • A new command for scripting moveobjecttopos(ObjectID, X, Y, facing)
  • Shortest path computation between the initial and final position
  • The NPC's facing at the end of the movement can be chosen
  • Obstacle and field objects avoidance
  • Works in terrains with different elevations and bridges
  • Easy to customize between Uniform Cost Search (Dijkstra), Greedy Best First Search, and A*
  • Easy to execute, just a line of code
  • Able to solve mazes

Usage:
Instead of use applymovement OBJECT_ID, sequence_of_movement you can just use moveobjecttopos OBJECT_ID, X, Y, FACING
With:
OBJECT_ID: The ID of the object (same as applymovement)
X and Y: the goal position
FACING: The orientation of the ObjectEvent at the end of the movement (0: down, 1: up, 2: left, 3: right)

1yVD67x.png
thingy-gif.4305

It finds the shortest path between the current position of the NPC (or player) and the goal position and is able to cross bridges and use elevations

ezgif-com-gif-maker-2.gif

It also can plan the movement of the player​

Known issues:
  • It is new research, so the code can be full of bugs and memory errors (use under this warning!!)
  • In open worlds may experiment overflow of memory and collapse (working in solution)
  • For long movements (far away from the screen) it is possible that doesn't take into account some minisprites
  • Maximum path of 200 steps
  • Sometimes report problems with waitstate 0 when two consecutive movements are performed

Contributing:
  • Help is needed in order to make the algorithm more robust and efficient in-memory consumption (for a detailed explanation of the code see below)
  • Feel free to use and find and report bugs. I think is the best way to contribute.
  • I am more experienced with C++, MATLAB, Python language code for search algorithms

Spoiler:
 
Last edited:
106
Posts
11
Years
Would this work if the destination was updated dynamically? I.e. An overworld Pokémon chasing a player (à la the wild area), where the player would be changing postion as the NPC navigates.
 
8
Posts
6
Years
  • Age 30
  • Seen Nov 22, 2022
Would this work if the destination was updated dynamically? I.e. An overworld Pokémon chasing a player (à la the wild area), where the player would be changing position as the NPC navigates.

Well, at the moment the system first plans offline (i.e. plans the route at the beginning of the movement) and then executes it (like an applymovement). It could be possible to get the position of the player and make a mapscript that is always moving the minisprite to that square (and play with some options like in follow me). It could be an interesting idea to work with. Although at the moment I am more concerned about solving more the efficiency of the code and the memory usage.

About dynamic changes, when calling the command it takes the current information of the map elements, that is to say, if the NPCs have moved, the code will notice it. However, if during the movement of the overworld something changed (a mini blocks the route that has already been planned during execution) it might not take it into account.
 
106
Posts
11
Years
Well, at the moment the system first plans offline (i.e. plans the route at the beginning of the movement) and then executes it (like an applymovement). It could be possible to get the position of the player and make a mapscript that is always moving the minisprite to that square (and play with some options like in follow me). It could be an interesting idea to work with. Although at the moment I am more concerned about solving more the efficiency of the code and the memory usage.

About dynamic changes, when calling the command it takes the current information of the map elements, that is to say, if the NPCs have moved, the code will notice it. However, if during the movement of the overworld something changed (a mini blocks the route that has already been planned during execution) it might not take it into account.

That's amazing. This is actually incredibly useful, especially for open-world stuffs. Thank you!
 

Blah

Free supporter
1,924
Posts
11
Years
I had used a similar system in a dexnav implementation to determine if the player had a path to the hidden Pokemon. What I found is that, when a path doesn't exist, this causes noticeable FPS lag -- especially if you're evaluating a path frequently (as suggested with dynamic changes). However, when used in a scripted environment (where you know a path exists), this is very useful.

For dynamically evaluating paths, you can run this in a task. Then evaluate until g(n) = C, where C is a small constant. What that would do is cut the processing time and move the object closer to it's target without needing to evaluate the complete path. Again, this is if you know a path exists. If a Path doesn't exist, depending on C, this would cause your NPC to strafe back and forth like a maniac :)
 
8
Posts
6
Years
  • Age 30
  • Seen Nov 22, 2022
I had used a similar system in a dexnav implementation to determine if the player had a path to the hidden Pokemon. What I found is that, when a path doesn't exist, this causes noticeable FPS lag -- especially if you're evaluating a path frequently (as suggested with dynamic changes). However, when used in a scripted environment (where you know a path exists), this is very useful.

For dynamically evaluating paths, you can run this in a task. Then evaluate until g(n) = C, where C is a small constant. What that would do is cut the processing time and move the object closer to its target without needing to evaluate the complete path. Again, this is if you know a path exists. If a path doesn't exist, depending on C, this would cause your NPC to strafe back and forth like a maniac :)

Well the implementation of the A* algorithm just returns a FALSE in case no path is found (it is a finite process) and in this case, the NPC doesn't move and the script continues. However, in really big maps the algorithm could take too much time to realize that there is no feasible path and this can generate that the screen freezes for a few seconds (or even more time) making weirds noises, and then continue the code normally. It won't move weirdly if there is no solution.
 

Blah

Free supporter
1,924
Posts
11
Years
Well the implementation of the A* algorithm just returns a FALSE in case no path is found (it is a finite process) and in this case, the NPC doesn't move and the script continues. However, in really big maps the algorithm could take too much time to realize that there is no feasible path and this can generate that the screen freezes for a few seconds (or even more time) making weirds noises, and then continue the code normally. It won't move weirdly if there is no solution.

You misunderstood. The suggestions above were ideas of how to avoid the few seconds of lag and their drawbacks, not about the current implementation.
 
Back
Top