I was thinking a bit more about the fleeing algorithm, trying to keep it simple, but effective.
Weights
To make a difference between enemies, you need to assign different weights to them: a brawler is obviously a more serious threat than a munchkin.
J_F_B_M suggests some simple weights (distance, health, maxHealth), but it’s better to define something more specific. I compiled a small table of the most common units and their main stats:
| type | health | speed | dps | range |
|----------|--------|-------|-------|-------|
| munchkin | 14 | 12 | 4 | 3 |
| thrower | 7 | 11 | 18 | 25 |
| shaman | 60 | 10 | 33 | 30 |
| scout | 75 | 12 | 24 | 3 |
| fangrider| 100 | 30 | 50 | 20 |
| ogre m | 120 | 5 | 36 | 3 |
| ogre f | 250 | 7 | 60 | 3 |
| skeleton | 300 | 7 | 38 | 3 |
| brawler | 500 | 4 | 150 | 5 |
I guess that the dps is a good basis for the weight, but it should be combined with the distance, range and speed: a brawler at 20 meters is harmless, but a few shamans at the same distance can be deadly.
I couldn’t come up with a formula that incorporates all this, but I’m working on it If you have any suggestions, share it with all of us! Probably a precalculated dictionary would be the best:
weightByType = {"munchkin": 4, "thrower": 18, ...}
weight = weightByType[enemy.type]
Walls
If you want to really flee, you should avoid walls too. As suggested above, you could give some weight to the wall, but I didn’t find an easy solution to do that. You could manually specify wall points on the map (e.g. every 5 meters) and assign a weight to them (=boring job), or you could try to detect walls with an algorithm (=probably an overkill). So what to do?
I think the easiest solution is to check if the calculated flee vector (let’s say 5…10m ahead) is “clear” (using isPathClear
): if it’s clear - go! If not, try to “scan” what’s ahead:
(Awesome paint skills here, too )
- green dot - hero
- red dots - enemies
- black arrow - calculated flee vector
- blue arrows - test vectors for “scanning”
- green arrows - possible flee vectors
This is still not fail-proof (e.g. corners), but I think it can be coded in a few lines (rotate the calculated flee vector 10…15 degrees until it’s “clear”), so it might be good enough.
[edit] Scanning in 0.2…0.3 rad steps (alternating left and right) seems to work OK.
If you have a more efficient and/or simpler solution, tell us!
To consider
-
Limit the calculation distance: anything further than 30 m could be safely ignored. For melee types this could go down to e.g. 10 m.
[edit] A more precise way could be to ignore enemies that are further than theirattackRange + speed/2
(see notes in next post) -
[edit] Define escape points: defining a few safe “escape” points per map should be simple, and could make the fleeing algorithm more efficient. (see following posts)
-
Special types: witches, warlocks, etc. Hard to calculate a dps for those - but it’s probably best to stay as far from them as possible
More…
Finally, here are some starting points for reading, if you want to go deeper in the subject:
Please it if you find this post useful! Thanks