Pathfinding

mordor3

Villager
Member
Joined
Jun 18, 2013
Messages
14
Reaction score
0
First Language
English
Primarily Uses
Thanks.  I'll be doing further testing over the next few days.  So far it's looking good.  As long as the user is unable to identify any serious issues or able to "cheat the game" with mobs stuck on corners or poor pathing I'm satisfied with it.

Projectile's can be set to "Through".  All mob projectiles are set this way.  However, for the player all the walls in the game would need to be thicker than the longest projectile to prevent killing mobs through walls.

One good byproduct of the current setup is during the single "move toward player" movement mobs will avoid the projectile if possible.  This often means they will dodge a single projectile which looks really nice.  This has to be very limited though or you can spam projectiles forcing the mob to go back and forth.
 

CodeEmpress

Villager
Member
Joined
Feb 3, 2014
Messages
21
Reaction score
0
First Language
English
Primarily Uses
greetings, is it possible to use this script to be used on an event to go to another event? like npc to npc?
 

Venima

Treasure experiences and sensations, not progress.
Veteran
Joined
Oct 8, 2013
Messages
128
Reaction score
48
First Language
English
Primarily Uses
N/A
Of course, just enter the event's x and y coordinates as the target location. I think maybe $events[id].x or something along those lines. I can't remember how the events are stored.
 

CodeEmpress

Villager
Member
Joined
Feb 3, 2014
Messages
21
Reaction score
0
First Language
English
Primarily Uses
on the event ID:003 I put these code and the trigger is player touch...

and it didn't move.. where did I go wrong? or maybe I need to add something?

find_path($game_map.events[1].x, $game_map.events[1].y,)

what I wanna do is that there are 2 npc approaching each other
 
Last edited by a moderator:

Venima

Treasure experiences and sensations, not progress.
Veteran
Joined
Oct 8, 2013
Messages
128
Reaction score
48
First Language
English
Primarily Uses
N/A
Player touch means the player has to touch the event for it to do the action. Could you provide a screenshot of your event code with this line?
 

CodeEmpress

Villager
Member
Joined
Feb 3, 2014
Messages
21
Reaction score
0
First Language
English
Primarily Uses
here is what I did...]

if I change the game_map.events with just number it works... same as with game_player.x and game_player.y ..

but using game_map.events.. no luck.. what did I miss? D:

thank you for your reply D:
 
Last edited by a moderator:

Venima

Treasure experiences and sensations, not progress.
Veteran
Joined
Oct 8, 2013
Messages
128
Reaction score
48
First Language
English
Primarily Uses
N/A
Ahh, I think I recall, you need to set the distance to 2 or something. Because the target event is blocking the path so it can't reach it? Something along those lines.
 

CodeEmpress

Villager
Member
Joined
Feb 3, 2014
Messages
21
Reaction score
0
First Language
English
Primarily Uses
yah someone made me realize it 8D! and thanks too for the replies! gonna come back here again if I wanna ask something!
 

Diretooth

Lv. 25 Werewolf
Veteran
Joined
Mar 10, 2013
Messages
1,231
Reaction score
444
First Language
English
Primarily Uses
RMMV
I've noticed this script has a problem that another similar script (Khas' pathfinder) has. When you set it to 'true' to wait characters, it doesn't wait, rather, events keep moving along while the 'waited' script call is still running. (Example: I set the player character to move from one set of coords to another, true enabled, and have the word fuzzball ready to be stated when the character is finished moving. However, the moment the movement starts, 'fuzzball' appears.
 

Venima

Treasure experiences and sensations, not progress.
Veteran
Joined
Oct 8, 2013
Messages
128
Reaction score
48
First Language
English
Primarily Uses
N/A
I've noticed this script has a problem that another similar script (Khas' pathfinder) has. When you set it to 'true' to wait characters, it doesn't wait, rather, events keep moving along while the 'waited' script call is still running. (Example: I set the player character to move from one set of coords to another, true enabled, and have the word fuzzball ready to be stated when the character is finished moving. However, the moment the movement starts, 'fuzzball' appears.
Did you use it as a move route? Did you set the move route to wait? Did you make sure repeat was not checked?

Either way there's a work around. You can put at the end of the move route a set switch on (this will be activated after the move is complete). Then create a common event which triggers as a parallel process (or autorun if you wish) that triggers by the switch you've set. You can then put whatever you want in there. Remember to turn the switch off again at the end of the process. Also, it is important to note if you want to change a self switch belonging to that event, I believe you can access those remotely through a script call too: $game_self_switches[[@map_id, 12, 'A']] = true. Change the 12 to the event id and you're good to go.
 
Last edited by a moderator:

Firebrand

Warper
Member
Joined
Aug 6, 2014
Messages
2
Reaction score
0
First Language
Hungarian
Primarily Uses
Is there any way to give the script more processing power?

My NPC's objective is to catch the player, so the script is on Repeat.

Whenever the player getting too far in the labirinth, the game starts lagging.

I set the game's process to run on a single core only, but it's only uses 40-50% then the lags start.

Is there any way to make the script to use the full power of a single core if neccesary?
 
Last edited by a moderator:

Venima

Treasure experiences and sensations, not progress.
Veteran
Joined
Oct 8, 2013
Messages
128
Reaction score
48
First Language
English
Primarily Uses
N/A
Is there any way to give the script more processing power?
No, because it is a script. This is the inherent problem with interpreted languages like Ruby. Technically it can be improved but it would take me weeks to figure out how to code that, since it would require referring to objects I don't understand.

I set the game's process to run on a single core only, but it's only uses 40-50% then the lags start.

Is there any way to make the script to use the full power of a single core if neccesary?
I'm confused why you set it to a single core, (are you thinking of low end computers? Because I don't recall the last time I heard a computer that only had a single core).

Regardless, the percentage is an average over a period of time. The reason it lags is because it isn't running all the time, only once a step, so the average processing is not very high, but the actual processing ends up alternating between 100% and 20% or something. So in reality it is actually using all the processing.

My NPC's objective is to catch the player, so the script is on Repeat.

Whenever the player getting too far in the labirinth, the game starts lagging.
Ok, with a bit of smartness you can improve the amount of processing required. Let me explain why first:

When the script is on repeat, every single step it recalculates the entire path to the player. It requires more processing the further it gets from the player.

The benefit of recalculating each step is to find new shorter paths to the player and to update based on the player's new location. However, it takes a heck of a lot of processing.

So the way to solve this is to change the frequency of recalculating based on the distance, that way it will have a roughly smooth amount of recalculations throughout.

This is one way to do it:

Step 1. Create a separate event run by parellel process that is accountable for your chasing event. Give it no image and put it somewhere out of the way.

Step 2. Create some conditional branches in this event and have it check the distance between the chasing event and the player. To do this you can either use eventing and assign variables the x and y coordinates of them and subtract to find out the distance (player.x+player.y - event.x - event.y), or you can use a script query in the conditional branch and write "Point.new(player.x,player.y).distance(Point.new(event.x,event.y)) < 10" for example. 

Each conditional branch should check a whether the player is less than a certain distance, for example the first < 10, the second < 20, the third < 30 if you want three. 

Step 3. Within the first branch you want to set your chaser event's moveroute to find the player on repeat. This way it is accurate if it is near the player. After the moveroute event you want to put a wait event for about 60 frames, so that the parallel processing event checks again in a little while.

Step 4. Within the next branches you want to do the same thing except that the moveroute is not on repeat. Again you want to put a wait event, only for about 120 frames for the second branch, 240 frames for the third etc.

Step 5. Make sure your last branch has an else condition and put your last moveroute and longest wait in there.

If it lags when it gets close to the player, you know to reduce the distance of your first conditional branch, so maybe < 5 instead. Give this a go and let me know how well it works. There is another way of doing it that is probably more reliable to be efficient, but it's more work.
 
Last edited by a moderator:

Firebrand

Warper
Member
Joined
Aug 6, 2014
Messages
2
Reaction score
0
First Language
Hungarian
Primarily Uses
Venima,


Thanks for the answer, and sorry for the late reply.

I'm confused why you set it to a single core, (are you thinking of low end computers? Because I don't recall the last time I heard a computer that only had a single core).


Regardless, the percentage is an average over a period of time. The reason it lags is because it isn't running all the time, only once a step, so the average processing is not very high, but the actual processing ends up alternating between 100% and 20% or something. So in reality it is actually using all the processing.
I thought RGSS3 only use 1 core from the CPU, because it's an old scripting language. Whenever I open my task manager and run the game, I see only 1 core spinning up, that's why I modified the affinity, to prevent the OS switching the processing between the 4 cores, so I can get a clear picture about the CPU usage.

Ok, with a bit of smartness you can improve the amount of processing required. Let me explain why first:


When the script is on repeat, every single step it recalculates the entire path to the player. It requires more processing the further it gets from the player.


The benefit of recalculating each step is to find new shorter paths to the player and to update based on the player's new location. However, it takes a heck of a lot of processing.


So the way to solve this is to change the frequency of recalculating based on the distance, that way it will have a roughly smooth amount of recalculations throughout.


This is one way to do it:


Step 1. Create a separate event run by parellel process that is accountable for your chasing event. Give it no image and put it somewhere out of the way.


Step 2. Create some conditional branches in this event and have it check the distance between the chasing event and the player. To do this you can either use eventing and assign variables the x and y coordinates of them and subtract to find out the distance (player.x+player.y - event.x - event.y), or you can use a script query in the conditional branch and write "Point.new(player.x,player.y).distance(Point.new(event.x,event.y)) < 10" for example. 


Each conditional branch should check a whether the player is less than a certain distance, for example the first < 10, the second < 20, the third < 30 if you want three. 


Step 3. Within the first branch you want to set your chaser event's moveroute to find the player on repeat. This way it is accurate if it is near the player. After the moveroute event you want to put a wait event for about 60 frames, so that the parallel processing event checks again in a little while.


Step 4. Within the next branches you want to do the same thing except that the moveroute is not on repeat. Again you want to put a wait event, only for about 120 frames for the second branch, 240 frames for the third etc.


Step 5. Make sure your last branch has an else condition and put your last moveroute and longest wait in there.


If it lags when it gets close to the player, you know to reduce the distance of your first conditional branch, so maybe < 5 instead. Give this a go and let me know how well it works. There is another way of doing it that is probably more reliable to be efficient, but it's more work.
 
Going to try this out with a big labirinth to see what happens. I wonder if Step 3's constantly repeating pathfinding will stop if condition not met.
 
Last edited by a moderator:

Venima

Treasure experiences and sensations, not progress.
Veteran
Joined
Oct 8, 2013
Messages
128
Reaction score
48
First Language
English
Primarily Uses
N/A
I thought RGSS3 only use 1 core from the CPU, because it's an old scripting language. Whenever I open my task manager and run the game, I see only 1 core spinning up, that's why I modified the affinity, to prevent the OS switching the processing between the 4 cores, so I can get a clear picture about the CPU usage.
I see... yes you're right about that one. I wasn't aware but yes it can only handle one process at a time, no parallel processing. Good to know.

Going to try this out with a big labirinth to see what happens. I wonder if Step 3's constantly repeating pathfinding will stop if condition not met.
Ok, the next best thing you can do is create your own "node" map. Basically you place events at regular locations around your labyrinth, this is so that your chaser only pathfinds to the next node and is never more than say 15 moves away from one. You then create a list of these nodes that the player walks over (player touch). You can then pathfind to each of these in turn until the list is empty. While the list is empty you pathfind to the player.

The challenging part about this is how to create the list. You can make a list via scripting, that's the easiest way if you know the language well enough. The other way would be to keep two game variables, the first is the event id that the chaser is pathfinding to, the second is the event id that the player last "walked over". What you then do is each time the player walks over a "node", you swap the locations of it and the event whose id is one more than the last. Best way to explain this is with an example I think:

So say you have a 4x4 grid of node events, whose ids are the numbers say from 5-20 (there's 16 of them). Your chaser is closest to node 5, so chaser's variable is 5. You also set the player's variable to 5 to begin with. The player now moves over node 9, so you swap the locations of node 9 and node 6 (5+1) and set the player variable to 6. If the player then moves over say node 13, you swap node 13 and node 7 (6+1) and set the player variable to 7. Your chaser can now pathfind from node 5 to node 6 to node 7 to follow the path of the player. Each time the chaser finishes a path he checks if his variable is the same as the player or not; if it is pathfind again to the player until collision, otherwise he adds 1 to his variable and pathfinds to the next node. Now when you're incrementing you're going to have to add a special condition for when the player and chaser go beyond the last node, node 20. You add a conditional branch just after incrementing: if node==21, set node to 5. From here your chaser should continue to chase the player following his path via the nodes. 
 
Last edited by a moderator:

Dangime

Villager
Member
Joined
Aug 31, 2014
Messages
23
Reaction score
2
First Language
English
Primarily Uses
Is it possible to use this script to move an event that looks like a ship over water? Currently the method I'm using works just fine for land based events. Anyway to specify water based events instead?
 

Venima

Treasure experiences and sensations, not progress.
Veteran
Joined
Oct 8, 2013
Messages
128
Reaction score
48
First Language
English
Primarily Uses
N/A
I believe there's no special case (in terms of movement) for water except you cannot move between water and land, so yes, naturally. If it doesn't work, you can do one of two things. Edit the pathing in your tileset editor so that water can be treated as normal, or check the ship event's 'through' property.
 

Blue001

Veteran
Veteran
Joined
Jan 13, 2014
Messages
231
Reaction score
112
First Language
English
Primarily Uses
RMMV
I have events set up to move 1 space, every time the player moves. I really want a more intelligent movement from my NPCs who are trying to get to the player as they always get stuck on walls.

This seemed to be a perfect script to solve my issue, but... after looking at this, I'm at a loss as how to make them pathfind only 1 space closer, and stop, until called again.
 

TheoAllen

Self-proclaimed jack of all trades
Veteran
Joined
Mar 16, 2012
Messages
5,594
Reaction score
6,525
First Language
Indonesian
Primarily Uses
RMVXA
I have events set up to move 1 space, every time the player moves. I really want a more intelligent movement from my NPCs who are trying to get to the player as they always get stuck on walls.

This seemed to be a perfect script to solve my issue, but... after looking at this, I'm at a loss as how to make them pathfind only 1 space closer, and stop, until called again.
I have a simpler solution. Just let you aware of the alternative

http://forums.rpgmakerweb.com/index.php?/topic/35677-theo-pathfinding-and-event-chase-player/#entry352982
 

Venima

Treasure experiences and sensations, not progress.
Veteran
Joined
Oct 8, 2013
Messages
128
Reaction score
48
First Language
English
Primarily Uses
N/A
I have events set up to move 1 space, every time the player moves. I really want a more intelligent movement from my NPCs who are trying to get to the player as they always get stuck on walls.

This seemed to be a perfect script to solve my issue, but... after looking at this, I'm at a loss as how to make them pathfind only 1 space closer, and stop, until called again.
Before I begin, do look into TheoAllen's solution, it may be exactly what you're after :)

Now then, to be clear on what you mean, I'll answer both contexts for: "Pathfind only 1 space closer"...

If you mean move one space closer and stop, there is I believe a common event that can be called after every step taken (I've used it for playing sounds and things). In this common event all you need to do is clear the move-route. If the event stops moving altogether by doing this, that probably means the common event is called first.. so then experimenting with the wait command and parallel processing or using a variable counter for each time the common event is called might fix that. To be clear on how this in theory works: the move-action 'find_path' inserts after it: the move-actions required to follow the path, which the event then naturally follows. What you're doing is after it's made a move, clear the move-route.

However, if you mean literally draw a path from your event to the player until the path reaches a length of one, this isn't a path. The same effect would be to tell it to "move towards the player". Even if you want this, I would follow the instructions above if you don't want it to get stuck behind walls.

The problem you 'might' have is lag. Intelligent functions combined with scripted languages works out to a lot of processing power, unfortunately. If you don't have lag though, then no worries ^_^
 
Last edited by a moderator:

Blue001

Veteran
Veteran
Joined
Jan 13, 2014
Messages
231
Reaction score
112
First Language
English
Primarily Uses
RMMV
The problem you 'might' have is lag. Intelligent functions combined with scripted languages works out to a lot of processing power, unfortunately. If you don't have lag though, then no worries ^_^
Lag shouldnt be an issue really... I only ever have 8 enemies on a map at once. And they only move the moment you do. (Like in some roguelike games, like dungeons of dreadmore, if you know it.)

Basically, to better explain... when the player moves one space, I force them to stop and wait 30ms before being able to move again, (sort of like taking a turn) and during that time, the enemies also move one space, in an attempt to get to the player. The normal "move toward player" event works to a point, but sometimes the enemy will just stand against a wall between the player and the enemy, rather than trying to move around the wall and find a route to the player. Your pathfinding script would work perfectly for me, if it had an option that was the opposite of the current "stop X spaces from player", and instead, had a "move x spaces" toward player option. So I could just pop in a 1 to limit how far they could travel in a single call of the move route.

My maps are all tiny, too, less than 50x50 so again, lag shouldn't be an issue when determining paths.

Ill try and give your script a go with the parallel process interrupt idea you suggested.
 

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Posts

Latest Profile Posts

Are we allowed to post about non-RPG Maker games. and, if so, would any of you be interested in a short, proof of concept type non-euclidian puzzle game?
I should realize that error was produced by a outdated version of MZ so that's why it pop up like that
Ami
i can't wait to drink some ice after struggling with my illness in 9 days. 9 days is really bad for me,i can't focus with my shop and even can't do something with my project
How many hours have you got in mz so far?

A bit of a "sparkle" update to the lower portion of the world map. :LZSexcite:

Forum statistics

Threads
105,883
Messages
1,017,232
Members
137,607
Latest member
Maddo
Top