The main purpose of this AI project was to try to create an interesting combat AI on a scale which I had not had a chance to previously. This meant that the AI would be using more data, AI hierarchies and finally more advanced behaviours.
To create the AI I used local knowledge of the world to drive movement decisions. To accomplish this I used Cover Nodes which were automatically generated via a tool I wrote. Finding edges of the navmesh adjacent to objects tagged as cover. These nodes described good places for the AI to go in the most general sense. These nodes also contained information on their tactical value; which due to time restrictions on the project ended up being limited to just height data. With this information, the AI was able to calculate relative tactical values of positions, whether the position was safe from enemies and whether the path to the position was safe enough to risk moving.
The AI hierarchy had a few jobs in the final project. The highest level of the hierarchy was the Squad Commander, its first job was to recalculate which cover nodes were safe or not for the squad under its command. It was also responsible for controlling data regarding the squads current objective. For example, the position the squad should move to after the objective and what targets are left in the current objective. Finally to create more variety in the AI behaviour it also had different squad movement methods which were calculated, these involved staggered movement in which the squad would take it in turns to move, either waiting for the first part of the squad to completely finish moving, or after a calculated time, depending on the distance required to move. The squad was able to move out as a whole as well.
The final part of the AI was creating the ability to break free from the hierarchy, in order to act independently from the squad commander, this was necessary to create a more object-oriented AI, where each soldier was responsible for its own behaviours, but continued using data from the hierarchy. This meant that they did not have to calculate on their own whether a cover node was safe to move to, but they were responsible for calculating if they themselves were flanked. As well as relative data values like the tactical value of a movement. The AI would also at this point start using a blackboard so that the squad could continue working as a whole whilst remaining independent.
Cover Node Knowledge /
The AI Commander Takes Knowledge of Cover nodes and enemies visible from them, in order to update the current internal representation, which the allied AI units use.
Click To Expand, Multiple Pictures
Tactical Advantage Calculations /
When acting independently, the unit AI uses its knowledge of safe cover nodes to find those that match minimum and maximum movement criteria and determines their tactical value.
This is calculated as a function of distance versus height, with height currently being the only deciding factor of tactical advantage.
Click To Expand
Movement Danger Calculation /
When acting independently, the unit will occasionally move, to create a more dynamic battlefield, ensuring that combat is not stale or overly static.
As part of this movement, the AI uses its knowledge of safe cover nodes and tactical advantage to ensure that it does not disadvantage itself with this movement.
It then follows this up with a warning flag system, which allows it to calculate paths and determine if the path is threatened by the opposing team, to avoid overly exposing itself.
Click To Expand
Flanking Attempts and Response /
When acting independently, the unit AI may find itself or its planned Cover point flanked. As part of this behaviour, the unit had two options: "Stand and Fight" or "Flee". The decision that is taken is determined by the nearest available safe cover, to ensure that the AI always has a valid response.
This behaviour provided some interesting results as pictured on the right.
Click To Expand, Multiple Pictures
During this project, I have learnt a lot about balancing the amount of data that the AI uses and the desired behaviours and decision making. Some of this learning has come from an opportunity to engage with an AI of this sort, and some from the issues that arose during the project, and this has come together to create the AI presented above.
One such example is shown in the development of my danger algorithms so that the AI would appear intelligent in its decision making, ensuring that it is interesting to watch, and portrays a level of decision making, that does not provide only perfect answers, but does not cause the AI to do something that appears illogical.
The hardest part of this project was balancing the movement and data handling around that, having had issues with Unity's navmesh agents and surfaces, and in hindsight, I would have saved more time implementing my own local avoidance steering behaviour.
A further issue that arose was the handling of flanking, the issue here was one of balance, if the AI was given too wide a range on its flee radius, it would run for so long that it appeared illogical, or as if it was trying to flee combat entirely as opposed to just its flanker. On the other hand, if the AI radius was too small and the AI failed to move when there was a cover point that appeared to be easy to get to (from the players perspective), it would detract from the feeling of intelligence I was trying to develop within the units.
My final thoughts on this project are that I planned to precisely to keep a good agile workflow. Whilst my planning followed the Agile methodologies that I have used during my game projects; I feel that I failed to maintain a good level of flexibility in regards to time planning and features. Which caused features that should have been removed or adapted for the health of the project remaining longer than they should have, which reduced the time available for tweaking and balancing. Regardless of the mistakes and surprise developments during the project, it did fulfil one of the most important aspects of trying something new, I learnt something.