I got two big AI algorithms implemented this week. Originally, I had planned to have the searching and chasing algorithms combined in one, but it turned out to be easier to do if split into two separate algorithms.
With the chasing algorithm, the AI will remember where the target was last seen and which direction it was moving in. The AI will then move to this tile and continue chasing in the direction the target was last seen escaping in. If no new visible contact is made with the target, the AI can start checking doors or side corridors it moves past, while continuing to chase in the direction it suspects the target may have run off in (if the target could have escaped in two different directions, for example, and one of these directions was outside of the AI’s line-of-sight at the last ‘waypoint’, the AI will continue on in this direction, as the target would likely already have been spotted if escaping in the direction that wasn’t hidden from the AI).
The searching algorithm is a bit simpler: the AI will just choose some random waypoints within a certain distance from the central search tile, then go to these in turn, stand there for a moment and look in different directions before moving onto the next waypoint.
With both of these algorithms, I ran into an issue when the AI’s path was blocked by a locked door. The AI character would just stand there indefinitely. So I also implemented a procedure for checking if an AI’s path is blocked by a locked door or non-moving character – and then abandoning the chase or moving to the next search waypoint if blocked.
The overall structure that governs each AI character’s behavior is made up of separate orders. A character will usually start off with just 1 order, for example patrolling an area, standing at a counter or just walking across the map. Certain events can cause a character to get a new order, such as when a patrolling guard spots the player. Instead of overwriting the old order, this new order is just stacked on top so the character now has 2 orders (the orders for each character are just stored in a dynamic array). When executing orders, the code always executes the last order in a character’s order stack. And when the current order is done (if the guard has lost track of the target he was chasing, for example), this order is just removed and the previous order becomes top of the stack again – meaning that the guard just returns to his previous order and goes back to patrolling.
It works really well and isn’t all that complex coding-wise, so I’m pretty happy with this solution. I haven’t really read up on AI programming theory, so this may all be pretty basic or incredibly stupid, but hey, it works for me!
I’ll probably be making a new development video demonstrating the new AI stuff in a week or so. Stay tuned for that.