{"id":4139,"date":"2009-08-20T09:45:09","date_gmt":"2009-08-20T13:45:09","guid":{"rendered":"http:\/\/www.shamusyoung.com\/twentysidedtale\/?p=4139"},"modified":"2009-08-20T11:19:37","modified_gmt":"2009-08-20T15:19:37","slug":"ai-follies-pathing","status":"publish","type":"post","link":"https:\/\/www.shamusyoung.com\/twentysidedtale\/?p=4139","title":{"rendered":"AI Follies: Pathing"},"content":{"rendered":"<p>Pathing (or path finding) is the process of getting some AI controlled entity to move from A to B.  It used to be that when people said &#8220;AI&#8221; they meant &#8220;pathing&#8221;.  The two terms were synonymous, because pathing was the only intelligent thing you needed the game to do.  We&#8217;ve come a long way and we need a lot more from our AI than just a trip planner, but the need for pathing is still there and it&#8217;s still a challenge.  <\/p>\n<p><strong>Getting From A to B<\/strong><\/p>\n<p><table width='384'  cellpadding='0' cellspacing='0' border='0' align='right'><tr><td><img src='https:\/\/www.shamusyoung.com\/twentysidedtale\/images\/ai_pathing3.jpg' class='insetimage' width='384' alt='Green: Optimal route.  Red: The area you would cover if you were to use the &#8220;stick to the right or left wall&#8221; logic of navigation.  Woefully inadequate by today&#8217;s standards.' title='Green: Optimal route.  Red: The area you would cover if you were to use the &#8220;stick to the right or left wall&#8221; logic of navigation.  Woefully inadequate by today&#8217;s standards.'\/><\/td><\/tr><tr><td class='insetcaption'>Green: Optimal route.  Red: The area you would cover if you were to use the &#8220;stick to the right or left wall&#8221; logic of navigation.  Woefully inadequate by today&#8217;s standards.<\/td><\/tr><\/table>We&#8217;ve needed AI entities to navigate a complex environment for well over twenty years so this is not new territory.  It&#8217;s not trivial to write code to do this, but it&#8217;s a fundamental task and there is an expectation that any system you write should be able to do <em>at least<\/em> this.  <\/p>\n<p>While most game enviroments aren&#8217;t quite as complex as a real maze, they might as well be.  They still have places where you can&#8217;t use a simple attractor.  (An attractor would be where the AI will simply run towards the goal.)  There will be room layouts or topography where you need to go south a bit if your ultimate goal is to the north.  Solving this is, in practice, the same thing as finding an optimal route through a maze.<\/p>\n<p>There are a couple of approaches to navigation:<\/p>\n<p>1) Geometry analysis.  The program has to analyze the geometry in the room, deciding what areas are passable and what the sensible routes are.  This can get to be really complicated.  Remember that AI doesn&#8217;t understand &#8220;furniture&#8221; vs. &#8220;hallways&#8221;.  It&#8217;s all just &#8220;shapes&#8221; to the AI.  It sees the shortest-distance path across the room requires it to go up a step, then down a step.  Except, that &#8220;step&#8221; is actually a footlocker, and people usually walk around those.  Humans <strong>can<\/strong> skip the two-step flight of stairs and hop up onto a deck or porch, but we usually take the stairs.  On the other hand, we&#8217;ll hop over a low fence or wall on the edge of a field rather than go around. But I won&#8217;t jump over a similar-sized &#8220;wall&#8221; if it&#8217;s actually the countertop island in the middle of the kitchen, or the dining room table.  If I walk around the yard, I walk on the level parts, and avoid the awkward feeling of traveling horizontally across the face of a hill. I&#8217;ll generally avoid walking in paces where I have to duck, and I walk around desks rather than crawl under them.  It becomes very hard to make the AI choose the right thing without a few hints from the level designer about whether this bit of geometry is a thing to be walked around, through, climbed over, or avoided.  Which brings us to&#8230;<\/p>\n<p><table width='448'  cellpadding='0' cellspacing='0' border='0' align='right'><tr><td><img src='https:\/\/www.shamusyoung.com\/twentysidedtale\/images\/ai_pathing4.jpg' class='insetimage' width='448' alt='The waypoint-based pathing in Unreal Tournament.  The level designer has placed nodes (the little apple or peach icons) around the level, and they were then analyzed and linked by the software to construct this system of routes around the level.  When the game is played, AI&#8217;s will travel along these routes. ' title='The waypoint-based pathing in Unreal Tournament.  The level designer has placed nodes (the little apple or peach icons) around the level, and they were then analyzed and linked by the software to construct this system of routes around the level.  When the game is played, AI&#8217;s will travel along these routes. '\/><\/td><\/tr><tr><td class='insetcaption'>The waypoint-based pathing in Unreal Tournament.  The level designer has placed nodes (the little apple or peach icons) around the level, and they were then analyzed and linked by the software to construct this system of routes around the level.  When the game is played, AI&#8217;s will travel along these routes. <\/td><\/tr><\/table>2) Waypoints.  These are invisible markers  set around the level by the designer that define the possible routes.  Generally, every bend or every intersection will have a waypoint. The AI can stand at one waypoint and look for another, or plan a trip through several waypoints.  This turns navigation into something very much like a Google Maps-type trip planner.  Waypoint-based navigation is much less work for the programmer, but it&#8217;s more work for the level designers (who must place them) and it makes the AI a little more rigid and mechanical.  Waypoint-based bad guys tend to follow the routes tightly, which makes them very predictable and exploitable. If you can reach a spot where the level designer didn&#8217;t think to put a waypoint you can confuse the AI, possibly exploiting it and unmasking its stupidity. You can fix this by having the AI leave these &#8220;rails&#8221; as needed, but the more they leave the rails the more generalized geometry analysis skills it will have.  If you want them to be really flexible and adaptable, you&#8217;ll basically end up writing <em>both<\/em> systems.<\/p>\n<p>Generalized systems are much harder to author.  (At least, I think they would be. It might not be so bad for general &#8220;deathmatch&#8221; arenas, but the more realistically cluttered the environment is, the harder this will be.  I&#8217;m still curious how they handle the &#8220;footlocker&#8221; problem in some of these games.) But it has the advantage is that your level designers don&#8217;t end up wrangling with AI and can focus on design.  Back in the day, Unreal Tournament way a waypoint game and Quake III Arena was a generalized game.  I don&#8217;t know that I could say the bots in one were better than the other at getting around.<\/p>\n<p>I&#8217;m pretty sure Left 4 Dead uses a generalized system and it seems to work really well. The zombies climb all over the insanely complex debris-strewn topography with ease.  Then again, they can get away with climbing over furniture.  They can take the direct-line route and aren&#8217;t expected to to the &#8220;smart&#8221; thing when crossing the room.<\/p>\n<p><strong>Finding B<\/strong><\/p>\n<p><table width='384'  cellpadding='0' cellspacing='0' border='0' align='right'><tr><td><img src='https:\/\/www.shamusyoung.com\/twentysidedtale\/images\/ai_pathing1.jpg' class='insetimage' width='384' alt='Once you find B, you still have to plan a sensible route to get there.' title='Once you find B, you still have to plan a sensible route to get there.'\/><\/td><\/tr><tr><td class='insetcaption'>Once you find B, you still have to plan a sensible route to get there.<\/td><\/tr><\/table>It&#8217;s no good being able to go from A to B if B itself isn&#8217;t a useful location.  If this AI is trying engage the enemy in melee combat, figuring out B is fairly straightforward: B is the position of the player. Now go hit him.  But if the AI is trying to <em>shoot<\/em> the player, then this is a complex question. In an open field, there will be hundreds of possible vantage points from which you <strong>could<\/strong> shoot at the player, but only a few will make any sense. Now instead of trying to reach the player, you must:<\/p>\n<ol>\n<li>Examine the battlefield and find every place I could stand and get a shot at my target.\n<\/li>\n<li>Disregard ones that are already occupied by allies.\n<\/li>\n<li>Now rate all of the points according to the criteria:  How long it will take to reach the point, how much cover the point provides, and how dangerous the route is to reach it.\n<\/li>\n<li>Note that there probably isn&#8217;t a &#8220;best&#8221; one.  It&#8217;s all a bunch of tradeoffs, with the importance of each attribute varying on the situation. (For example, if the AI is low on health it should rate dangerous routes very low.) Good luck with that.\n<\/li>\n<\/ol>\n<p>Before Half-Life 2 came out there was a preview gameplay demo floating around the net.  One of the most sublime moments in that video for me was the point there the player blocked a door with some furniture and the Metrocops ran to a nearby window to get a clear shot at the player.  Another moment that amazed me once I had the game was where the Strider fights the player in a parking garage.  The Strider is brilliant at moving to the right spot and then crouching to the right level to be able to get a clear shot.  Both of these are complex problems to solve, and the game handles it very well.<\/p>\n<p>Making things worse:  If the AI needs to <em>lob<\/em> projectiles at the player rather than simply <em>shoot<\/em> them.  This is a great way to induce weeping and gnashing of teeth for your AI programmer.  Now the pathing needs to make sure that B is a location with enough overhead space to allow for any of the useful firing parabolas. I have yet to see a game do this properly.  Generally, the projectiles simply pass through obstacles or (more commonly) the bad guy will stand there like an idiot and mindlessly heave projectiles into the obstruction.  <\/p>\n<p><strong>Dealing with Blockades<\/strong><\/p>\n<p><table width='384'  cellpadding='0' cellspacing='0' border='0' align='right'><tr><td><img src='https:\/\/www.shamusyoung.com\/twentysidedtale\/images\/ai_pathing2.jpg' class='insetimage' width='384' alt='The classic Starcraft frustration.  I tell my Ultralisks (blue things) to go up the ramp.  The first one gets hung up for just an instant as it brushes a marine aside. But! As soon as it stops, the second one sees the route up the ramp is blocked and immediately heads for the alternate path, taking a needless pounding from the units above along the way. If #2 had just waited for a moment, the two could have gone up the ramp together. The very worst was trying to get three or four siege tanks up a single ramp, which would result in a horrifying mess.' title='The classic Starcraft frustration.  I tell my Ultralisks (blue things) to go up the ramp.  The first one gets hung up for just an instant as it brushes a marine aside. But! As soon as it stops, the second one sees the route up the ramp is blocked and immediately heads for the alternate path, taking a needless pounding from the units above along the way. If #2 had just waited for a moment, the two could have gone up the ramp together. The very worst was trying to get three or four siege tanks up a single ramp, which would result in a horrifying mess.'\/><\/td><\/tr><tr><td class='insetcaption'>The classic Starcraft frustration.  I tell my Ultralisks (blue things) to go up the ramp.  The first one gets hung up for just an instant as it brushes a marine aside. But! As soon as it stops, the second one sees the route up the ramp is blocked and immediately heads for the alternate path, taking a needless pounding from the units above along the way. If #2 had just waited for a moment, the two could have gone up the ramp together. The very worst was trying to get three or four siege tanks up a single ramp, which would result in a horrifying mess.<\/td><\/tr><\/table>Two enemy soldiers want to shoot the player, who is hiding in a building.  Soldier A kicks open the door, stops in the doorway, and begins shooting.  Now, Soldier B is standing behind him, still outside.  What should he do?  Stand in line waiting for his turn?  Abandon his teammate and use a longer alternate route?  The answer, annoyingly, is &#8220;it depends&#8221;.  <\/p>\n<p>When an AI needs to pass through a choke point which is blocked, the resulting decision is infuriatingly difficult and complex.  It has to be able to appraise how long this traffic jam is going to last. A second? Several minutes?  Has the guy in the doorway just stopped for a moment or is he pinned down by gunfire?  (Or worse, does he want to retreat out of the room, and now <strong>you&#8217;re<\/strong> in the way, and the two of you are now stuck like <a href=\"http:\/\/www.youtube.com\/watch?v=sfI9e4BX0lU\">the Zax<\/a>.)  <\/p>\n<p>Once you have some sort of guess as to how long the logjam is going to last, you&#8217;ll have to weigh it against the time it will take to run the alternate route, which is itself a bit of annoying guesswork and approximations. <\/p>\n<p><strong>Putting it all together<\/strong><\/p>\n<p>This is where things go wrong.  The AI looks at the battlefield and sees six locations where it can shoot at the player.  Each location needs to be weighted according to these criteria:<\/p>\n<ol>\n<li>How advantageous position is.\n<\/li>\n<li>How long it would take to get there.\n<\/li>\n<li>How risky the trip to that location will be.  (This is very subjective.  A momentary dash over open ground is okay, but prolonged exposure in the open should be regarded as suicide.)\n<\/li>\n<\/ol>\n<p>All three of these variables are very hard to judge, and harder still to balance against each other.  (For example, a healthy AI can afford a little risk, while a severely injured AI needs to take into account that any further injury will probably be lethal.) It&#8217;s no good heading along a safe route to reach an optimal vantage point if the battle will be over by the time you get there.  It&#8217;s stupid to bolt for a great location if you&#8217;re just going to get cut down on the way.    It&#8217;s not good risking life and limb for a position that will only be slightly better than your current location from a tactical standpoint.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Pathing (or path finding) is the process of getting some AI controlled entity to move from A to B. It used to be that when people said &#8220;AI&#8221; they meant &#8220;pathing&#8221;. The two terms were synonymous, because pathing was the only intelligent thing you needed the game to do. We&#8217;ve come a long way and [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[66],"tags":[],"class_list":["post-4139","post","type-post","status-publish","format-standard","hentry","category-programming"],"_links":{"self":[{"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=\/wp\/v2\/posts\/4139","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4139"}],"version-history":[{"count":0,"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=\/wp\/v2\/posts\/4139\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4139"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4139"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4139"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}