[XP] Advanced Pathfinding

Started by ForeverZer0, May 30, 2011, 04:00:31 pm

Previous topic - Next topic

Vexus

Maybe but having an extra event per npc/monster that require pathfinding would be a huge load of work as I'm trying to do a lively town with npcs doing their things during the day before night.

The easiest solution I found was the wait thing in the event which shouldn't give me problems right?

Got events tied with your time script could that cause some conflictions?

Thanks.
Current Project/s:

ForeverZer0

At what exact point does the error happen? When the event collides with something, as soon as you come out of battle, as soon as the player gets away from the enemy, etc.?

And no, the time script should have no bearing on actual events.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Vexus

After killing the enemy but it doesn't happen often.
Current Project/s:

Heretic86

Another verifiable bug.

Recalculating a path because something moved in the way of the originally recalculated path seems to cause pathfinding to fail if it is run again a 2nd time, regardless of shifting map.  Problem also appears to be intermittent, but occurs about 90% of the time.

Ok, heres what I did.  New project, no script conflicts, no other scripts.  Made a semi complex route for the player to move to using pathfind(3, 12, $game_player), and put some random events moving around so the path would have to be recalculated a 2nd time.  It does complete successfully the first time.  But, try to pathfind again, and it immediatly returns as invalid or impossible, regardless if the path is being blocked or not.
Current Scripts:
Heretic's Moving Platforms

Current Demos:
Collection of Art and 100% Compatible Scripts

(Script Demos are all still available in the Collection link above.  I lost some individual demos due to a server crash.)

ForeverZer0

Increase "$game_map.collision_retry"
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Heretic86

Ok, I bumped it up a little...

I changed it from 35 to 100, then tried again a few more times, and ended up at:

@collision_retry = 350000000000000


and it still does it.
Current Scripts:
Heretic's Moving Platforms

Current Demos:
Collection of Art and 100% Compatible Scripts

(Script Demos are all still available in the Collection link above.  I lost some individual demos due to a server crash.)

ForeverZer0

Is the destination coordinates passable the moment when the call is made?
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Heretic86

It goes back and forth, so the player waits for the event to move out of the way, then eventually does finish.  However, once finished, which works great, and the path is completely clear, if I try to pathfind again, it seems to totally fail.  I figure its something I have set wrong, just cant see why once it finishes, and try any pathinfinding at all, 2nd attempt wont start.
Current Scripts:
Heretic's Moving Platforms

Current Demos:
Collection of Art and 100% Compatible Scripts

(Script Demos are all still available in the Collection link above.  I lost some individual demos due to a server crash.)

ForeverZer0

Quote from: ForeverZer0 on April 20, 2012, 11:10:00 pm
Is the destination coordinates passable the moment when the call is made?


I don't mean the first call, but following ones.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Heretic86

Yes.

I even went so far as to clear out all of the events that move in the players way on the 2nd attempt.

By the way, thank you for supporting your script.
Current Scripts:
Heretic's Moving Platforms

Current Demos:
Collection of Art and 100% Compatible Scripts

(Script Demos are all still available in the Collection link above.  I lost some individual demos due to a server crash.)

ForeverZer0

Hmmm.
Upload me your demo where it fails, and I'll see if I can find anything.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Heretic86

Current Scripts:
Heretic's Moving Platforms

Current Demos:
Collection of Art and 100% Compatible Scripts

(Script Demos are all still available in the Collection link above.  I lost some individual demos due to a server crash.)

ForeverZer0

Its because at the time the call is made, there is no possible path that can be followed that will take the character to the destination.

Take a look at this fantastic example I slaved away at and made:
Spoiler: ShowHide


If the calls is made when the events block the path like that, the system begins searching for a path to the destination, but it can never get further than its small area up top where it is blocked into, therefore the pathfind is unsuccessful.

You can try a few things.
The easiest would be to not create situations like that. Its an automated search algorithm written in Ruby, not true intelligence, therefore stupid little things like that can screw it up.

Second, although I have not tested it, would be to increase the range in the script call. Just because it is allowed a range of error does not mean that it will quit the second it gets within it; it will still try to reach the exact target.

Third, and this is flirting with disaster a bit, and risking a hanging script would be to call the pathfind again as a failure proc. You will definitely want to test this solution vigorously if you decide the other two won't work and are going to use it.

I'll see if it is a viable option to provide some type of fix for this without breaking the scripts normal functionality, maybe some type of "at least go as far as you can" type procedure for characters to follow.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Heretic86

Ok, let me ask this way then.  Im not too concerned that if a path is totally blocked that it fails.  That makes perfect sense.  But on the 2nd go, shouldnt that failure proc reset so it says to try it again?  On the 2nd go, even when all the events are cleared, an unobstructed pathfind call says it failed.  Thats where Im having difficulty...
Current Scripts:
Heretic's Moving Platforms

Current Demos:
Collection of Art and 100% Compatible Scripts

(Script Demos are all still available in the Collection link above.  I lost some individual demos due to a server crash.)

ForeverZer0

This is what you have in your example:

pathfind(2, 12, $game_player)


You aren't defining any type of proc to run when it fails.

I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Heretic86

I realize that, because I am not sure what to do when it fails to "reset" the failed property, so when pathfind is called again, it does try instead of immediately returning that it failed.  Is that even something I can do? 

pathfind(3, 12, $game_player, reset_fail_proc())
Current Scripts:
Heretic's Moving Platforms

Current Demos:
Collection of Art and 100% Compatible Scripts

(Script Demos are all still available in the Collection link above.  I lost some individual demos due to a server crash.)

ForeverZer0

I think I see.
I don't remember super good, but it may be that the Procs don't get setup if the initial call fails. I made them more for once the pathfind is already in process. I don't even think any data gets added to a Game_Character's "paths" variable if the first call fails.

The best advice I can give is to avoid these situations, but in case you want to try it, here is an EXTREMELY ugly hack that introduces risks all kinds of bugs and crashes if things don't go according to plan.

class Pathfind
 
  alias freeze_my_game_if_event_dont_get_the_fuck_outta_the_way calculate_path
  def calculate_path
    freeze_my_game_if_event_dont_get_the_fuck_outta_the_way
    if !@found
      Pathfind.new(@goal, @character, @range, @success_proc, @failure_proc)
    end
  end
end


I haven't tried this at all, but you can see what it does. If it can't find a path, it creates a new Pathfind object. It will continue this until a path is opened or the game crashes. If you wanted, you could add a some simple counters to prevent repeated attempts that might prevent a freeze, but at the same time they won't guarantee success.

I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Blizzard

I have had the same issue in Blizz-ABS. I handled it in such a way that I created a progressive algorithm where you queue paths that you need to be found and then it would calculate 200 nodes (I actually don't remember the actual number) per frame for all of them together. That way lag would be avoided, but sometimes the path would not be found immediately in the same frame so enemies may stop for a short moment, especially if the path could not be calculated since there is a roadblock. I just wanted to throw in this idea/possibility to handle this problem in a constructive way.
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

Heretic86

@F0...

Ok, I think I found something...

On line 242:
      @character.force_move_route(@route) if @character.paths.size == 1


... after having to make an adjustment, a new path is added to the paths[] array so the above line doesnt force_move_route, and immediately comes back as if it has completed.

Does that help at all?
Current Scripts:
Heretic's Moving Platforms

Current Demos:
Collection of Art and 100% Compatible Scripts

(Script Demos are all still available in the Collection link above.  I lost some individual demos due to a server crash.)

Heretic86

Okay there Cookie Monster (F0's current avatar), I fixed this little problem.  Simple one liner.  A Cookie Monster walks into a bar, sits down next to a Master Scripter and says "    @character.paths = []", ah, nevermind, wrong kind of one liner...

class Pathfind

  attr_reader   :route                 
  attr_accessor :range   
  attr_reader   :goal
  attr_reader   :found
  attr_reader   :character                               
  attr_accessor :success_proc         
  attr_accessor :failure_proc         
  attr_accessor :target   
  attr_accessor :collisions       
 
  def initialize(node, char = -1, range = 0, *callbacks)
    # Set the character. Can either us an ID or an instance of a Game_Character.
    # A value of -1, which is default, is the Game_Player.
    if char.is_a?(Integer)
      @character = (char == -1) ? $game_player : $game_map.events[char]
    elsif char.is_a?(Game_Character)
      @character = char
    end
    # Set forcing flag. Will be disabled for recalculating on the fly.
    @forcing = true
    # Heretic - Clear any existing paths from previous pathfind calls
    @character.paths = []
    # Call a public method, since this method may need to be used again,
    # and "initialize" is private.
    setup(node, range, *callbacks)
  end


Added code is Bolded.  This is for anyone else that might experience this minor glitch in an otherwise fantastic script.

Here is what happens.  Any time any event is set to pathfind more than once, and has to recalculate during path execution of the first pathfind call, extra paths are calculated and added to the @paths array, but not cleared.  Thus, the 2nd time that same event is set to pathfind, it will automatically fail to execute because of "@character.force_move_route(@route) if @character.paths.size == 1" finding that more than one path is in the @paths array.  It will reset for Events when maps are changed, but once $game_player has to recalculate, it fails across all maps.

@F0 - I know I am persistent about fixing stuff, but I havent offended you at all, have I?
Current Scripts:
Heretic's Moving Platforms

Current Demos:
Collection of Art and 100% Compatible Scripts

(Script Demos are all still available in the Collection link above.  I lost some individual demos due to a server crash.)