So I made a post in the Discord a while ago but it ended up being way longer than I expected (should have seen it coming) so I’ll put my thoughts here, in a hopefully more digestible format, instead.
Recently, I’ve been thinking a lot about how auto-evo could be implemented, particularly the population aspect. However, I eventually ran into a dead end so I’ve decided to just post what I got.
Designing auto-evo is… a monumental task, obviously. But even though I’m not really a programmer or a maths person, for some reason I felt like I could help, hopefully at least a little bit, by trying to figure out how to build what would be part of its foundation: a system that takes a bunch of different species and the environment they all share, compares their capabilities and behavior, and calculates each species’ population and relationship with others.
Before I begin, just to make sure we’re all on the same page: I’m working under the assumption that auto-evo will have to be very targeted, fairly “intelligent,” and rather decidedly not very Darwinian. Obviously it’s possible to simulate the evolution of life with actual natural selection – plenty of games and programs have done that – and yes, it does seem like it would be a shame to say that Thrive is an evolution game without any actual evolution…but Thrive’s scope is so big and so different that cheating unfortunately seems necessary.
We’re not simulating a small play area where organisms live, die, reproduce and mutate in real-time, like in games like Species: ALRE and Ecosystem (which are interesting in their own right, don’t get me wrong)…we’re simulating an entire planet (possibly not actually planet-sized, but still very large) which will eventually be covered in possibly hundreds or even thousands of species.
Even tactics like giving each species 5 or so random mutations and choosing the most beneficial will eventually become inefficient as more species arise. Plus, it’s easier to add a random organelle to a 2d, hexagonal cell, without any concern for body shape, and have it be beneficial, but on a larger scale, truly beneficial mutations will end up being extremely rare, and NPC evolutions will be suboptimal and aesthetically unpleasant as a result. Again, actual evolution isn’t guided by an intelligent force toward a certain goal, but after a trip to the editor and a jump millions of years into the future, I don’t think it’s unreasonable to have the game say “this is what this species evolved into over that time.”
Concepts -- these will be linked, or broken down, later in the post
^ https://www.desmos.com/calculator/rb9uugyzcl
The first step I took was trying to figure out how different species would fill up an ecosystem, given a limitless supply of food and nutrients.
Imagine an empty patch where the soil is always sufficiently saturated with nutrients, which two different plant species are in the process of taking over:
Each frame, a pixel is added to one growing member of each species, until its shape is complete, after which it will place a single new pixel somewhere else in the square. This is the final result:
We end up with 24 3-pixel green plants and 14 5-pixel cyan ones, with green plants taking up 63.16% of the population and cyan ones taking up 36.84%.
Their growth can also be visualized by placing a number of horizontal “bars” together into rows; each row represents a species, each of its bars sized according to how quickly they grow. A vertical line scans through these rows, and every time it passes a bar, it adds a member of the respective species to the environment until the overall carrying capacity is reached:
Here the green plants take up 62.5%, the cyan ones, 37.5%.
We don’t actually have to simulate this exact method though, I found a way to directly calculate (what should be?) the same result.
First, I start with a big purple line, representing the total amount of nutrients in the patch’s soil. This one is 125 units long.
Then I defined 4 different plant species, represented by the red, yellow, green, and blue bars (the size of each shown in the upper left, also corresponding to each bar’s length in pixels. The red “2” is a typo, it should say “3”)
(The manual placement of the colored bars above the purple line isn’t part of the calculation, it was just so I could compare the calculations with the manual result. Furthermore, the numbers to the bottom-left, underneath the purple line, measure the number of (manually-placed) bars in each color, their combined size in pixels, and their percentage of all individuals in the patch.)
I found that, by dividing the number of nutrients (125) by the number of different species using them as a food source (4), and then dividing that number (125/4 = 31.25) by the length of each species’ bar, I could arrive at a result very similar to the manual one.
So, basically every species gets an equal portion of the environment, but each one still ends up with a different population based on how much energy they need to survive and reproduce – think the difference between grass and trees.
Going back to the two-imaginary-plant-species, with 125 units of nutrients, this results in 20.8333 green plants and 12.5 cyan plants. (62.5% and 37.5%, again)
I then added “herbivorous” “animals” to the mix, by repeating the same idea, except this time using their prey’s populations calculated in the previous step. (note the weirdness with pixel sizes and dividing numbers here…I had to expand the plants’ lines so the animals’ bars would be visible, making them appear 6 times larger than their actual size in units.)
I divided each food source between a number of different animal species; the animal represented by the tan-colored 8/6-pixel bars eats three plant species, sharing most of them with other animals, while the one represented by the pale blue 4/6-pixel bars gets the last plant to itself.
By adding the results of all the food sources together, we find the total population for every species in the patch.
Note that some animals are just as numerous, if not more so, than the plants they eat. This isn’t necessarily unintended behavior; these may be small animals, easily sustained by eating relatively small portions of the plants, exceeding them only in number, not biomass. Think small parasites eating the leaves or wood of a large tree.
So what can this be used for? Not much, at least not anywhere near its current state. The picture painted by this model is terribly imperfect. Every species does not have its food source, at a constantly ideal amount, served to them on a silver platter, especially not animals, and especially not animals that eat animals.
In this model, the plant populations remain unchanged by predation by the animals, and the environmental nutrients are not used up by plants, nor would they be returned by organism death and decomposition. Different species relying upon the same food source do not face any competition from each other – and competition is a very important part of evolution.
And the fact that ecosystems are cyclical makes this effect very difficult to calculate. Plants may leech nutrients from the soil, making their actual carrying capacity lower than if the soil always had as much as it could possibly offer 24/7 like it does here. Meanwhile, herbivory would lessen these plants’ impact, while carnivores eating herbivores would lessen their lessening of these plants’ impact.
Here’s an example of how each member of an ecosystem impacts the others:
Each colored rectangle represents a species, while the colored circles represent species that positively or negatively affect their population (and the circles inside of those circles represent species that affect their populations, and so on)…
For instance, this plant species’ population is negatively impacted by predation by herbivores (yellow), which rely on the plants for food, and have their own population affected by the carnivores (gray) that eat them.
Meanwhile, the plant species gets its sustenance from the nutrients in the soil, which is replenished by decomposing species of many kinds, but is affected by the population of plants growing on it, which itself is negatively impacted by predation by herbivores, which rely on the plants for food, and have their own population affected by…
And this is without considering the competition that occurs when two species occupy the same niche, where one will end up being driven extinct by the superior competitor, and the fact that all this will need to be able to be seen and understood by the player in time so they can adapt and plan accordingly.
I think what we need to do is find something which, given all of the species, their stats, niches, and relationships, and the environmental conditions, estimates reasonable populations for every member of the ecosystem (as well as a list of “issues” or “setbacks” for each organism, which the player or auto-evo may want to pay attention to) without having to simulate multiple iterations (likely costly?) in hopes that the populations will balance out…which is where I’ve been stuck so far.
I wish I were better with math.
So I’ve mentioned that I want to find a nice, static “equilibrium” in spite of predation and competition and such, but in real life, populations are not static! They fluctuate quite often, like how prey populations boom following a decline in their predators, after which their predator’s population rises before both eventually drop due to starving/dying to death until the cycle begins again.
I wondered for a bit whether something like this should be represented in Thrive too, but though it would be cool, I feel like it might be best to shy away from it.
For one, the timespan of a single “incarnation” (or gameplay/swimming period, whatever we want to call it) is likely way too small in most cases to see these changes happen in real-time. Furthermore, there are many points where, as mentioned before, predators are unable to sustain their numbers with the current prey population. It would be very unfair for players to be spawned into these points, where statistically their chances of surviving and reproducing are slim, in a game that expects them to survive and reproduce.
The populations could be averaged to give the player a more fair chance, and to ensure that solely their skill and the effectiveness of their organism’s design determine whether they can get through. These averaged values might never appear at the same time in the normal population oscillations, but the game might not even know those to begin with? I really don’t know, and also I feel like this is about to get in the territory of seasonal variations and which things should change through them, so I’ll abandon this train of thought for now.
Here’s some more thoughts on how competition and predation would effect populations:
I went in to making these concepts under the assumption that being driven to extinction by predation would be possible, but after some second thought I’ve realized it’s probably unlikely in most cases? If a predator species relies upon a prey species for food, then its population is tied to theirs, and it’s likely both will find a relatively comfortable balance. (or both will dive straight down to 0 and go extinct, which usually we’ll want to avoid)
Still, in some cases it may still happen: a prey species may reproduce too slowly to make up for its deaths, and its predators may eat them all before they have time to face the consequences, or the arrival of an invasive species can drive them to extinction. (The mechanics of which i’m not too sure of, so I’m kinda worried i’m picturing this all wrong)
Usually though, a species’ adaptations against predators aren’t to avoid extinction, but rather to enable those equipped with them to survive longer than those who are not.
Parasitism, even if it rarely kills a single individual, may harm organisms’ fitness and ability to reproduce.
Competition, meanwhile, can very quickly lead to species’ extinction; when two species share the same niche, one will eventually have to die out. Population decline due to competition or other factors (like mass extinctions) probably shouldn’t be instantaneous though, especially not for the player; so either such things should take two or so generations to happen or auto-evo shouldn’t be allowed to treat the player like any other species.
Changes in the player’s population could be more gradual than usual, so they have time to prepare. In instances where it somehow immediately drops to 0, there can be brief “shields” in place to allow it to hover at a very low value for a few generations, hopefully giving the player a chance to make a comeback.
Also, new species could be less likely to compete for the player’s niche than they would any other, so the player isn’t constantly spending most of their time desperately defending their niche instead of advancing forward through the stages.
The impact of these safeguards could be lessened, or disabled entirely, on harder difficulties.
Here’s some more ideas on food webs I drew on my whiteboard. Most of it’s the same stuff I went over already, i.e. predator-prey and competitive relationships within ecosystems, however I did also think about how different forms of each species, as well as their corpses and waste, could be counted as individual food sources, in order to properly include organisms who may undergo a metamorphosis that massively changes them, and to facilitate scavenging and decomposition.
(Also, this part represents a general way to abstract organisms to make them easier to plug into auto-evo):
The upper drawing represents the organism itself in the flesh, including 100% of its organs, joints, senses, behavior, and tissues, just as the player would see it in the editor.
The middle drawing represents a “profile” of the organism, giving some more simplified stats (but not terribly so!) indicating its abilities, such as its stature, mobility in different environments, defensive capabilities, camouflage, and things like that. These are what will probably be compared by auto-evo in order to measure different matchups between species, and estimate issues harming them.
Finally, the bottom drawing represents all the information from the profile (and other organisms’ profiles) being used to create a few variables representing things like a species’ success at predation and its ability to create offspring from the food it gains, which would be used to calculate the actual populations in an ecosystem. (right now I have no idea how any of this would be done. sorry)
Back to math!
In order to figure out how an ecosystem would balance itself over time, I created this:
^ https://www.desmos.com/calculator/rb9uugyzcl
It’s not quite a solution to the problem I was looking for, but it helped me visualize it a little bit better. You can change each organism’s variables (its population per every one unit of its food source, and the deaths in its prey in the next iteration for every one unit of the current population). Also notice how adding another organism (by switching to another graph by hiding/unhiding the folders) changes the average population of all the other species involved.
Here’s an example of how a parasitic (or really small predator) species might look:
The “meece” (yellow line) are parasites of the “ferms” (green line). There are 3 meece per ferm, however each mooce only has a minimal impact on the ferm population since there’s only so much a small predator can do.
However, if you turn that last number up…:
Bad Things Seem To Happen
The position of those dotted horizontal lines is given by the average of the last 2 iterations of each population, but these graphs won’t be approaching anything any time soon
Finally, I experimented a bit more with the math, and noticed the populations were definitely approaching certain numbers in particular:
But even though it felt like I was super close, I couldn’t figure out where exactly they were coming from, so I eventually gave up for the time being.
That’s about all I can provide for now, but (unless you all decide on a better course of action, which… yeah) once this step is done, our next step might be designing a “profile” system, which would contain an abstracted overview of each organism, which full organisms would be converted into in the editor, which would then go on to be used in calculating and building the ecosystem.
Next would be a system to identify issues by looking at organisms’ profiles and the patch they’re in, in order to aid both the player and auto-evo. (issues would include things like “this species is competing for your niche” or “this species is hunting you” or “your temperature tolerance isn’t well suited to the current environment”)
And finally, the most difficult step will definitely end up being the system that reads these issues, takes a look at the organism’s profile, decides what would be a good adaptation (though not necessarily perfect, and not necessarily done all the time) and then somehow applies those changes to the actual, physical organism itself.
…Whew.
I don’t know how much of this is possible, or feasible, and I kinda feel bad suggesting so much when I can offer so little. Again I’m not really a programmer so some of the shortcuts I’ve suggested might be unnecessary and maybe the performance cost isn’t as bad as I imagined! Maybe all this isn’t actually that good of an idea and I missed a post where someone already figured it out and did much better than me. But either way, auto-evo is looking like one of the hardest problems…ever, so I hope we’re up for it.