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've been building a rogue-like for more than a year now, and so far I've only ever implemented very simple monster behaviour - such as moving toward the player when he's in the line of sight, and attacking.

I would like to implement fleeing behaviour for certain monsters that realize they're outmatched.

I have these priority based behaviour types for monsters:

  • Flee
  • Attack/Defend
  • Investigate (event)
  • Socialize / Explore / Patrol

The only code I have for fleeing is a flood fill routine which attempts to find tiles which "look" like they are doorways leading to corridors. The question is, how can I improve this to stop it from finding such tiles that deceptively look like doorways, but actually lead to dead ends?

share|improve this question
1  
It's okay if the mob runs into a dead end, just make it Go out with a Bang. :) –  Cyclops Aug 30 '11 at 13:33
1  
I glanced over this title really fast and read it as, "How to prevent a monster from stabbing himself in the back till dead?" –  Nick Wiggill Aug 30 '11 at 15:06
1  
Whatever you do, don't make it too effective. It'll be fun for the player to outsmart enemies and trap them in corners. –  jhocking Aug 30 '11 at 15:08

4 Answers 4

up vote 4 down vote accepted

One thing I've done in the past is add a cornered state to the enemy. Put yourself in the shoes of the fleeing enemy. It is scared, it is hurt, it is fleeing and trying to just get away! Perfect mindset to get yourself cornered, which can be really fun for the player.

Once cornered, the enemy can do different things, ideally depending on the personality of the enemy itself:

  1. They can cower and duck into the corner and wait for death. Only really works if you can convey those emotions. A single-character rogue-like enemy probably can't convey that without text or something. From here, the player could decide to leave the enemy alone, showing compassion. Could be really neat if the enemy then becomes passive. Or if healed, even become an ally of the player.
  2. They could go into a blind rage and launch a last-ditch attack against the player, or unleash some kind of escape spell or skill; such as a squid squirting ink, or a lizard playing dead.

These are really more interesting than avoiding the corner in the first place. And are probably faster to compute, which will let you spend those cycles elsewhere.

But if you MUST avoid the corners at least a little, the best way I've found is to discourage walking down tight lanes. Simply check the 8 spaces that are 2 spaces away from the enemy. Such that if the enemy is on space (9,9) check spaces: (7,7)(11,11)(7,11)(11,7)(7,9)(9,7)(9,11) and (11,9). If any of these are open, check the 4 spaces around that space too. Weight movement in those directions according to the number of spaces you see. In a rogue-like, the walls are rarely even that far away, and this will encourage the enemy to stay in the same room.

Nothing is more annoying than an enemy that runs off down a long corridor, regardless of that corridors termination, and leaves the player to have to chase it down.

share|improve this answer

If your flood fill extends further, it will necessarily distinguish between dead ends and exits that lead further. The bigger the area you search, the more accurate it will be.

Alternatively, during the creation of your levels, you may want to annotate exits, so that they can be explicitly searched for. Find the nearest one and plot a path to it. Plotting paths can be done with the A* algorithm.

Another way of using the A* algorithm would be to pick a random point elsewhere in the level and plot a path to it. If it's reachable, that path would constitute an escape route. If it's not, you can try a different point. Ideally, you would attempt to plot a path to the exit from the level, as that would definitely be a viable escape route.

share|improve this answer
    
+1 for suggesting a concrete flight destination target. You do not need to follow the whole path through, only just enough for the creature to 'feel' safe. You could also designate hiding places for the creature to flee to. Make sure the creature runs for a hiding place outside the range of the player. –  ghost Aug 30 '11 at 12:09

The developer of Brogue wrote an interesting article about how he uses what he calls "Dijkstra Maps" to accomplish this and other things: http://roguebasin.roguelikedevelopment.org/index.php/The_Incredible_Power_of_Dijkstra_Maps

Basically, you run a variant of Dijkstra's algorithm to set a weight to every cell in your map. If you calculate one of these based on your player location, it provides a map of the quickest route from the player (or somewhere near the player) to any other point on the map. The global minimum will be the furthest point away from the player, which will necessarily be somewhere that wasn't blocked by a dead end.

It's probably not the most efficient solution, but on roguelike-sized maps it seems to perform fine, and there are a lot of other cool applications for it that he mentions in the article.

share|improve this answer

Basically, a dead end is a path where you can't go back to your starting point without turning back, so I think checking for that may be a simple solution, maybe not the best.

Another solution coming to my mind would be to mark dead end entry tiles with a flag.

share|improve this answer
    
A corridor 1 tile wide would pass your "is dead end" test. –  tenpn Aug 30 '11 at 13:21
    
Not if you use a nav file. –  Whiskas Aug 30 '11 at 13:31

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.