The AI demands for this project were intense. I needed to create an AI system that handled a large number of unique units, each with multiple attacks and abilities. This system also had to be flexible enough to allow for designers to make large changes after I moved on from the project and it had to be lightweight enough to handle large unit counts on mobile. In addition to all that, each unit had to control similar to an action game character when selected by the player.
The first issue to solve was how to create a complex system complex enough to handle the large variety in unit behaviors, abilities, and attacks while keeping things flexible enough to allow for rapid large design changes after testing. Due to the contract, I had to limit the amount of code changes needed during testing as I would only be on call for light bug support by that time.
To accomplish this I used a combo of the concurrent and hierarchical state machine methods to create a fully modular system that could easily be changed just through simple editor input. The system ended up using multiple layers of root scripts each of which had a number of related behavior scripts underneath them. No piece aside from the base root was required to function so designers were able to mix and match the different behaviors to change them to their hearts content.
The attacks and abilities were also broken up into smaller module components, allowing for complete reworks of characters without any programming needed.
In order to keep the system as lightweight enough to run on mobile, rather than using a standard update method I setup a tick system in the Unit Root. This had a set amount of time between each AI update call. This time period was varied between each unit to be sure that all of the units didn’t update at once and potentially cause a slow down. Only a few specific functions were allowed to run every frame.
In order to scare off lag on mobile, the biggest optimization I made was to the AI’s update system. Rather than have each unit run through it’s decision process every frame, I created a tick system which allowed me to tell the AI how often it was allowed to update. To keep all the AI from updating at once and possibly causing a slowdown, I staggered each unit’s tick times. With the exception of some time sensitive functions, everything in the AI system ran on some sort of tick.
The final large issue with this system was allowing the player to take over any unit and have direct control over attacks, movement, etc. like in an action game. To do this I implemented a behavior enumerator. When a unit was in PlayerControlled mode, it would have a different set of speed, attack time and other variables so that the player would be able to make quick maneuvers and feel as if they’re controlling an action game character rather than an RTS unit.
