The last couple of weeks have been focused on completing the AI. The biggest task was to make its rebuilding process more reliable. That is, when the AI fort is partially destroyed it must reconstruct the missing fort to the same blueprint. Previously it tried to build all the missing parts simultaneously. This sort of worked but because it paid no attention to build order pieces would fall off along the way and sometimes it would get stuck. It would also build struts and then not be able to afford the next one which kept it in place before it fell off.
I reworked this so that it keeps a list of which fort actions needed to be redone. Before making any new additions to the fort it checks this list and tries to build the earliest actions, and unchecks them as they are complete. If some actions are unable to be completed for some reasons then it skips over them temporarily and tries something further down the list. If it gets to the end of the list, even with some frustrated steps, it starts adding new structures again.
While in this process of rebuilding, the weapons system dials back the offensive in order to save resources. Each weapon type has a probability of being fired, so more expensive weapons are unlikely to be fired, but light weapons will fire frequently. It also avoids repairing lightly damaged struts. When rebuilding is complete the offensive and complete repair resumes.
When creating a new joint, the AI now saves up resources to build the bracing strut too. This prevents the AI losing struts while waiting for the resources to brace them. It would previously get stuck on this kind of problem.
Another issue is that the fort moves during gameplay as the structure is damaged or sways under its own weight; joints may not be where they were when the fort template was recorded. I’ve partially addressed this by making minor adjustments to new joint positions when the AI is told that a requested strut is too long or too short. I may have to move to relative joint placement, rather than absolute, but for now this is helping quite a bit. It may be useful to improvise some unscripted segments and attachments to span large gaps. From a programmer’s perspective this is fertile ground for experimentation – I’m having a lot of fun with this.
Each time a weapon opens doors to fire it has a chance of leaving the door open for the next shot. This means the next shot can happen a little bit sooner, but it leaves the weapon exposed in the meanwhile. This probability also varies by weapon type, so weapons slow to reload will generally close their doors.
I’ve divided up the weapons into light and heavy categories. Each category has a list targets in order of priority. Until now the AI would start at the top and work its way down. This ended up being too predictable and tedious, with some targets being attacked persistently. Now the AI calculates a random offset into this list based on a normal distribution. It starts from there and works its way down, meaning lower priority targets get some attention too. If it fails to find one then it starts one above the offset and works its way up. The result of this change is an apparently much more dynamic and unpredictable opponent.
Different weapons are able to penetrate a structure to different extents. The cannon can take out at least one layer of armor, the laser too. The armor piercing (AP) sniper doesn’t destroy the armor but it does damage weapons up to two layers of armor behind it. When the AI casts a ray to the target currently under inspection it passes a number of hit points to ‘spend’ on getting through the layers of structure. This allows the AI to focus on attacking devices that it has a chance of damaging. For heavy weapons, if it fails to find any such weaknesses it goes back over its list of priority targets and picks one without regard to direct structure penetration. Using this I can encourage weapons that won’t necessarily break through to try anyway. For example the mini-guns will attack doors of weapons hiding inside until they eventually break through.
To mimic the player’s grouping mechanism, I’ve added a weapon grouping affinity table. Each time the AI goes to fire a weapon it scans its other weapons. The weapon types have a certain affinity for being grouped with the lead weapon type; some groupings make more sense than others and these have a higher probability of being selected. The important grouping that I was aiming to achieve is the missile launcher with the swarming missiles: the swarm protects the missile in transit. It also works well for groups of similar weapons, such as mortars and mini-guns, or you might have the mini-gun soften up some armor before hitting it with a missile. If firing the group is unaffordable at the time then it doesn’t fire anything. In this way it chaotically saves up for firing expensive groups but also fires single weapons. Some weapons shouldn’t be fired alone very often, such as the missile launcher; it is expensive and vulnerable to total failure. There’s an additional probability for abandoning such actions.
AI forts are recorded for a specific team on one side or the other of the map, but often the maps are symmetrical. To leverage the work done recording forts on these maps I have allowed the fort to be mirrored. The AI will build an identical fort on the other side, just flipped about the midpoint of the map.
While this work has dramatically improved the quality of the AI, there are still some significant issues with it. For example, because it blindly follows the original build order, it can spend a lot of time waiting for resources when it would be smarter to connect to nearby mines that it has lost a connection to. There may be additional work that I can do to patch these holes, and I will have to write some guidelines for recording quality AI forts, but for now it feels like it is ready for being enjoyed by the public.
Below is a series of screenshots showing the AI taking cannon fire, suffering considerable losses to its structure, and then rebuilding the lost parts. It doesn’t have the requisite workshop and upgrade center to rebuild the mini-gun and mortar, but once rebuilding is complete as possible it starts using the grouped swarm and missile again.