Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm implementing a multi agent A* algorithm on a tile map. Agents move only in the X and Y axes. I avoid collisions between them by checking where the others are when calculating paths.

It works fine except the situation where agents have to pass the same tile from different directions. In situations like this, an optimal solution would be for one agent to wait for the other to pass:

Sample situation

Also, if there's no northern corridor, then pathfinding fails.

How could I implement such an algorithm?

share|improve this question
2  
The answers to How to build a "traffic AI"? are relevant here. –  Anko Jun 16 at 10:12

6 Answers 6

up vote 15 down vote accepted

You can start by letting the pathfinding fail. On failure, choose a random time in the future to re-try pathfinding. Some low level networking protocols work that way, and quite well. What you have to do is build paths one at a time, and mark as used all the tiles an agent will pass through. When further paths fail the random timer to restart will help spread out the new path searches and break up looping failures.

The second part of your problem could be handled by returning two paths. The first path is the regular return, even if it fails from a block. The second path is a path that completely ignores all the agents. You can then use the knowledge gained from these two paths to decide whether waiting or taking the long way would be better. The heuristic for that decision will take some work, but it's better than not trying anything at all.

In the very bad case where your agents are getting blocked a lot by single width corridors like this you may have to add safe spots to stand where agents can quickly path to and wait for their real path to open up (so the agent doesn't just wait and block a corridor).

share|improve this answer

Rather than solving your problem, here's a way to take the lemons and make lemonade.

Many years ago a friend of mine was working on a very well-known FPS which had precisely the problem you describe: a constrained area would have a number of AI characters who had particular desired positions, and the path-finding algorithm was constantly bumping them into each other. In particular, the player would, say, throw a grenade into a small room full of enemies, and the AI characters in the area would each try to run to their exit, but run into each other, and end up pausing, turning around, hitting someone else, turning around, and so on. This looks very unrealistic.

Attempts to build a better pathfinding algorithm that could run successfully given the tight computational budget failed. So instead of solving the pathfinding problem, my friend added a very cheap check to the AI: if an AI has bumped into another AI twice in a short time period, stop trying to find the exit and instead take cover. So now what happens is, the PC lobs the grenade and sees a bunch of enemies run for the exits. Those that hit each other, turn around, and it looks like they realize they can't get out, so they duck and cover their heads right before they blow up. This is both realistic-looking and highly satisfying to the player.

Is there some similar way you can turn the disadvantage of your collision-producing algorithm and turn it into an advantage?

share|improve this answer
1  
+1 I like this, it's subversive and completely functional =) –  Patrick Hughes Jun 17 at 4:00

I usually find it best to augment A* pathing with other forms of path finding for other localized scenarios; unit avoidance is usually one of them, especially in a world where there are multiple agents moving simultaneously and thus creating dynamic blockers).

Generally, an edge-following technique can work for this. When you are following a path an encounter a blocker that wasn't part of the original path computation, you basically pick a direction (clockwise or counterclockwise) and try to traverse the blocker by travelling around it in that direction. If you can't, you wait for the blocker to resolve itself (although this can result in a deadlock).

You can also implement the ability for units to path co-operatively; that is, a unit can ask another unit to move aside slightly so it can "squeeze past" the blocking unit. This doesn't work well in a tile-based game where you are restricted to tile-based movement, though, because you can still deadlock in single-width corridors like your example. In that case you can provide for the units to ask eachother to "switch places," which results in resolution most of the time. Occasionally this leads to units leapfrogging eachother, though.

"Unit avoidance" is a fairly common topic when discussing pathfinding in games, there are a lot of hits out there for it. In particular you may want to check out this question on the "flow field" pathfinding used in Supreme Commander 2. RTSs usually run into this problem a lot and solve it in all sorts of interesting ways.

share|improve this answer
    
This exactly - there seems to be a very common perception that pathfinding means A*, and that's just not so. –  Steven Stadnicki Jun 17 at 15:14

If you have a turn based/tick based movement system than you could create a 3D graph where each transition moves the agent into how the map would look in the future. Then have each agent claim the tiles they would be on in that point in the future and mark them as inaccessible. Each agent then has an extra option of "ẅaiting" to the next tick as a 3rd way to transition through the graph. This will be harder on your system but should give you better results than waiting randomly. Even better if you allow 2 agents to communicate bt having one of them send a message of "I want to pass you" if it's shortest path passes through that agent, the reaction could then be to check if the agent is waiting during that time and if it is then letting it move to a tile that does not cross the path of the other agent (else repath that agent).

share|improve this answer
    
here is a paper that talks about that time cube: www0.cs.ucl.ac.uk/staff/D.Silver/web/Applications_files/… and here is an implementation: allseeing-i.com/ASIPathFinder –  rakkarage Jun 18 at 21:58

When using an algorithm like A* you have the greatest latitude in working with the cost heuristic.

In this particular case you could adjust the heuristic to increase the cost of movements that take an agent close to another agent, the problem there is you would likely end up with both trying to take the upper route, and you could end up with them oscillating back and forth between paths as they close on each other depending on the exact timing.

Another possibility is to track agents intended routes and adjust costs upward along other agents intended paths. This effectively allows agents to coordinate with each other to a limited extent. The main issue here is if all the routes are blocked out path finding may keep failing for whichever agent moves last.

In the case where there is only one path, then path finding will either fail or they will advance on each other until they deadlock.

If neither of those are good enough then you need to start keeping track of time when calculating your cost as well. The cost for the second agent should be the amount of time it takes for the first agent to get clear plus the normal traversal cost, in that way your agent would be able to decided correctly when to wait versus taking the other path.

Taking timing into accord can be significantly more effort, so most people settle for tweaking the level layout and cost values until things are good enough.

share|improve this answer

Normally I would adivse you to use steering behaviours to solve problems like this during path-following. And you still might to take a lot at those to get inspiration for grouping behaviour. But unfortunatley it is not really directly applicable for simple tile based movement.

Since you already have a working collision avoidance for most situations, lets focus on this particular one. I guess you are re-doing the pathfinding each time an agent wants to move, or else I can't see how they react to others moving during their move. Secondly I guess those agents are friendly to each other.

You suggest one agent waiting for the other one and I would advise you to do exactly that. Give the agents a way to access the paths of the others, search for the first tile of your own path that is not part of the other path and go there. Problems with this technique may be:

  1. How do you decide if there is another acceptable way around the other agent or not? You dont want to wait for the other agent if there is space enough to go around him. A pathfinding failure when considering the other agent is a clear sign of the situation you want to fix, but in the example you brought up there wont be a pathfinding failure. But you can - with a little bit of calculation - decide if the alternative path A* gives you just goes around the other agent in a small circle, or uses a totally different path like the northern corridor.

  2. I don't know how far an agent can travel during one round/operation, but if that is not far enough, or if all agents are moving parallel, both agents would decide to wait on the other end of the path. This can be fixed by signalizing the other agent that you free up his path.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.