

The more important benefit is that randomizing the timing means that fleets won’t get into any repetitive movement cycles when faced with unfortunate starting conditions. The benefit is twofold – first off, performance is better (though the number of fleets is usually low enough that it could be done every frame if need be). To achieve this, fleets set their desired angular orbital velocity to the average of their neighbors, effectively matching speeds as the de-overlapping is completed.įinally, these calculations are all performed at randomized intervals, instead of on every frame.

looking for stately orbiting, not a scramble. The next step is to minimize the recurrence of overlapping – again. Like cars going down the right side of the road without having to talk about it. The smaller fleets go down, and the larger fleets go up, just due to the nature of the logic. This results in 1) larger fleets generally going to a higher orbit, where there is more room, and 2) cooperative behavior without explicit communication between fleets.

If the neighbor is smaller, the fleet moves to a higher orbit if smaller, to a lower one. So, in addition, each fleet looks at its nearest overlapping neighbor. Of course, at some point there could be too many fleets regardless of anything we might do, but still, it’s possible to do better. Using just the above was almost good enough, but fell short when there were too many fleets for an orbit to hold, leading to endless jostling. While that produced quicker separation, it also felt too hectic – we generally want stately orbiting, not chaos. The important part is that the actions of the fleets will not conflict with each other.Īn initial version of the algorithm made fleets in the back of the pack move backwards, as well. The fleet then figures out the average location of these neighbors, and moves forward more quickly along its orbit, but only if the average location is behind it. The effect is that fleets that are already at the front of a pack will pull forward, while other fleets will continue along their slower-paced orbits. That’s easy enough – just a distance check with some padding. The first order of business is for a fleet to get a list of neighbors that are too close for comfort. The calculations are also performed by each fleet independently, but designed so that effectively cooperative behavior emerges when all the fleets apply the same behavioral rules. So, what’s actually involved in getting this behavior? While nothing here is terribly complex, there is a surprising number of pieces. The other day, encountering a particularly egregious case, I wrote a quick algorithm for the fleet AI to use to avoid overlapping other orbiting fleets as much as possible. This isn’t a huge problem in terms of game mechanics, but it’s still occasionally inconvenient and just messy to look at. The orbits of some well-to-do colonies can get quite crowded, with fleets overlapping each other and being difficult to pick out. In Starsector, fleets will often orbit a planet for some time – trade fleets offloading cargo, patrols preparing for duty, and so on. I will, of course, continue to write regular-style blog posts as well. This blog post is a bit different than usual – instead of talking about a major new game mechanic, I’d like to instead take a quick – but in-depth – look at something relatively minor, but that I thought was interesting.
