This project started out of a desire to explore component based design and emergent behaviors. One of my favorite experiences in gaming is setting up a complex scenario and watching it unfold — either through Rube-Goldberg contraptions of games like The Incredible Machine or through god games like Startopia, Dungeon Keeper, Darwinia and their ilk. While a complete game like Startopia was outside of my scope for a hobby project, a simulation of a predator-prey relationship wasn’t.
Each agent, or ‘boid’, is built from a series of components such as renderable, positional, perception, and behavioral. The green boids are capable of perceiving their three nearest neighbors — red or green, but are otherwise blind to the world. Their behavioral components are wander, align, separate, group, and flee which are balanced by an overall ‘brain’ component. A green boid separated from friends will heavily emphasize the wander component’s input, while a boid that finds itself close to a red boid will be driven more heavily by the flee behavior.
Red boids, however, are much simpler minded, consisting of only wander and separate behaviors. Like their analogous zombies, they wander aimless, grabbing at any prey that gets too close. They feel a weak desire to separate to prevent bunching, which would impair their ability to catch prey.
When a red boid collides with a green one, there is a chance that the boid will be converted. This process can take up to a second before it is triggered, giving the boids a chance to escape their plight. Inevitably, they are all devoured.
A surprisingly complex set of behaviors arose in the green boids. Because they can only see their neighbors, they tend to be much more confident (or blind) in crowd situations. The boids on the edge of the crowd will start to flee, but those in the middle of the crowd who are surging with the crowd can’t see what is going on and stumble into the red boids. They are the first ones turned into red boids. Later, when only a few boids remain, it is difficult not to sympathize with the loner green boid who is trapped in a ring of red boids, and whose escalating flight reaction brings it closer and closer to the red boids.
Finding the three nearest neighbors for 300 boids is an exponential problem if approached naively by checking the distance to every other boid. There are a few solutions to this problem with various levels of development complexity. In this case knowing the exact set of closest boids wasn’t necessary and I wanted to keep the code complexity low. The boids are sorted by their x-axis location (which is fairly simple, as they are generally in the same order between any two sequential frames), and the perception component scans alternately left and right down that list, checking the y components of the boids relative to its own until it fails to find any closer boids. It’s not guaranteed to find the absolute closest three boids, but it’s fast, easy to implement, and not distinguishable in the simulation.