Inside the Mind of a Drone
All three drone types- fighters, bombers, and scramblers- use the same AI system. The differences in their behavior just come from different parameters used in them. They all share similar priorities such as avoiding obstacles, destroying their targets, and sticking with their flight (and ultimately squadron, wing, and fleet).
Above all else a drone ship should avoid crashing into things. It looks silly when two ships just run into each other or when one smacks right into an asteroid or mothership. It's also very frustrating as an admiral to lose ships because your pilots are idiots. So, first priority: stay alive.
Whenever a drone AI updates it finds everything in the surrounding area that it could collide with and checks if it has to worry. If the object in question has a complex shape like a mothership, then it uses a simple ray-cast and calculates where the crash would occur if it kept its current heading, then it turns away from that point. If it's something less complex then it's probably another drone ship or an asteroid, in which case (counter-intuitively) things get a little more complicated.
In this case, both the drone and the other object are likely moving at high speeds, which means that a collision could come sooner, so it has to avoid more. To make sure that it doesn't spend all its time avoiding it performs a simple check to see how long it will be until it's a certain distance from the target. At first there seems to be a lot of math that goes into this check, but it boils down to a simple quadratic equation test returning between zero and two time values. Zero means that at the current velocities there will never be a collision. With two times it takes the minimum positive one, and with one time it only uses it if it's positive. Assuming there is a time and it's within the near future, the drone simply turns away from the object in question.
On the Prowl
The next most important task is to make sure that the enemy doesn't stay alive. As many of you already know, the trick to defeating just about any enemy is to shoot at it until it dies. But there's another problem here: what to shoot? There's so many options! And so it's a matter of priorities. If the drone already has a target, but it doesn't seem very appealing anymore then it just lets it go. If there is a target, and it's still worth pursuing, then the target selection section is skipped.
For selection, whether the old target was dropped or if the drone just never had one, it needs to search. It queries the world for all enemies within its sight range and evaluates them for the highest priority. Closer enemies make better targets than far ones. Enemies in front of the drone are better to attack than those behind it. This is also where some of the behavior variation comes into play. Bombers assign no priority to other drones; they only go after hard points or bigger targets. Scramblers prefer to attack targets that aren't already disabled.
If the drone has picked a new target or if it just had one all along, then it proceeds to attack. The basic idea here is to find out where the target is moving relative to the drone, aim for that point, and shoot. This is mostly just math, but there is some variance. The drones do not shoot at every opportunity, otherwise the sheer number of projectiles would bring the system to its knees. Instead they just randomly fire every several frames. Secondly, their aim is not perfect. Early in development this was unintentional, but one day I noticed that it was far worse than we had anticipated. In the moments after I discovered the glitch in our intercept calculation code hilarity ensued. The drones all had perfect aim and nearly everything would be obliterated in a minute. The player was lucky to survive for four seconds. Luckily a quick random offset later and everything was A-okay.
Once the drone has the whole "not exploding" thing down and can't find any targets to engage, it takes on its final task: staying in formation. Galactose is a very visual game, so if nothing else flying in formation looks really cool, especially compared to a flying mass. This formation flight typically happens when a squadron is idling and waiting for orders or when its on its way to engage the enemy. We had originally implemented a typical flocking algorithm with separation, cohesion, and alignment, but it just didn't look exciting. The same functions can be accomplished but in a more orderly fashion if you know exactly where each ship belongs.
The formation each squadron takes is essentially a two tier flying V. Each flight organizes itself with the leader in front and the others on the sides. Then the squadron leader's flight takes the front and the other flights line up behind it. To accomplish this each 'V' group sorts itself in a list of left-most from the leader to right-most. This list is then split in half, and each side sorts itself again; this time along the forward direction of the leader. The front-most left and right drones line up behind and beside the leader. Then the next closest two line up on their respective sides behind them, and this continues until all ships are assigned a spot in the formation.
Wrapping Up (and a New Playtest Build!)
There's a few other minor things I didn't mention above such as controlling throttle or how the drones act when "disabled", but there's only so much you can fit into single post. I hope you've enjoyed this, or at least found it mildly thought provoking, because it's one of my favorite parts of writing Galactose!
More importantly however: I have good news! We've got a new playtest build out! It's mostly tweaks and fixes as the new features are still under development, but it's most definitely worth checking out. ☺