Sentiant's Auto-Evo Algorithm

Glucose decrease doesn’t need to be added to the simulation. Microbes already eat clouds of glucose, causing them to permanently disappear from the environment.

Currently I am adding an arbitrary amount of glucose to the patch each timestep to ensure that the glucose never completely runs out. This is because predation isn’t a thing yet, so heterotrophs would just die when the glucose runs out.

I’ll address how the simulation handles environmental compounds in a future update.

3 Likes

THE ANT ARMY HAS ARRIVED

1 Like

A few days ago I added enviromental variables to the simulation: Enviromental gases like oxygen and CO2 can now change the rate at which microbes can run their processes, affecting how much food they need, and whether they’re able to survive at all (with any amount of food).
Vice versa, microbes are able to affect their enviroment: Photosynthesisers produce oxygen and consume CO2, Aerobic microbes consume oxygen and produce CO2, etc.

This seems to have caused, to put it lightly: ‘Complete Fucking Chaos’.
Populations wildly swing all over the place, no equilibrium ever appears, and I have yet to find a scenario that doesn’t end with everyone dying at some point. I could keep trying to balance this forever, but I believe that’s pointless: This isn’t some wild outlier, it’s an inherent symptom of the way my (and Nick’s) algorithm is built.

We go through the whole scenario month by month, and just sort of hope that after a certain amount of months an equilibrium population will just show up. Every month we also change the amount of compounds and enviromental variables of the patch based on the kind of creatures present, and the amount of creatures changes based on the enviroment present, and it’s a loop. Do you see how quickly this could spiral out of control?

That’s why I’ve decided to do two things:

  1. Change my algorithm with a rather weird assumption: Microbes do not directly affect their patch while the population algorithm is still running. Patches are large and ancient, and they do not undergo dramatic changes on a month-by-month basis. For example: If a microbe eats a cloud of glucose, the next month that cloud will simply respawn, no permanent change having happened. If a microbe produces oxygen, that will be ignored by the population algorithm. Changes to the patch can still happen, but they happen over the course of entire editor cycles, not months.
    This has some advantages. It makes point 2 (see below) easier to implement. It vastly reduces the amount of chaos in the system. And it makes for a much more player-friendly experience. When players sees in the editor that ‘Glucose: 4%’, they can be confident that that number will stay for at least this editor cycle. They do not have to take into account that glucose could suddenly drop to 0% halfway through running the auto-evo algorithm when they are making their microbes.

  2. I will (at some point, probably once the discrete version is done) convert the population algorithm into a continuous function, that can be solved directly for the equilibrium population, where Births = Deaths.
    Previously I considered this an optimisation, to be done in case the current approach took to long to calculate. Even if we ignore that: yes, it will almost certainly take too long to calculate, I now see that this is not an optimisation but a neccesity. Finding an equilibrium population by calculating the population every month from some starting condition is ridiculous to begin with. If I want to find the equilibrium population, then I must calculate the equilibrium population. Not some incidental stuff that may or may not end up being the equilibrium population.

I might be busy impementing point 1. for a while, but after that I’ll see you in the next update. There, we’ll run the new and shiny population algorithm for a couple of patches that are actually in the game, and see how different species do in different patches.

EDIT: I should add that 1. will not revert the fact that microbes have a limited amount of phosphate and ammonia to work with, because in my model microbes are simply seen as little bags of compounds within the patch (just like compound clouds). A microbe could be built by taking 2 ammonia and 2 phosphate out of a cloud, then die depositing 2 ammonia and 2 phosphate back into a cloud. That’s not considered a ‘net change’ to the patch anymore than taking some ammonia from one cloud and moving it to another is a ‘net change’.

8 Likes

Time for another update:
Today I implemented point 1. from the above post. No compounds (enviromental or not) can be permanently added or removed from the patch anymore. No more burning all the glucose. No more dumping CO2 in the atmosphere. No more blindsiding the player with Great Oxygenation Events. Party’s over.
I also converted all the biomes from the real game into my simulation. This means that we’ll now be able to run scenario’s in different biomes, like the coast or the vents.

Here are some results, in this case we put P. Metabolosomus (1 hex of metabolosome) and a cyanobacterium (cell wall, 1 hex of thylakoids) into the pangonian coast patch:


As you can see a couple things changed:

  1. We have succesfully prevented most of the chaos resulting from stuff like food shortages and oxygenation events. Both graphs seem to have a fairly logical progression from the starting population to an equilibrium.
  2. The equilibrium takes much longer to reach. In fact technically it is never reached, as the species populations are now asymptotic (it’s just that we round the population to a whole number). In this case it took about 40 months to reach equilibrium, where before it took only 12. It took about 2.5 seconds to simulate all of that for just 2 species. This is not as much of a performance liability as it seems: In the continuous algorithm it won’t matter much how many months we have to simulate, because we don’t need to loop over every month anymore, only the final month. Also see point 3:
  3. Long before equilibrium is reached we are already approaching it. This means we can ‘cheat’ by only simulating a fraction of the months needed, than just extending the graph a bit in the direction it was already going. This approximates the population we’d reach if we left the algorithm running for an infinite amount of time.

I’ll see you in the next update where we’ll be looking at a more exciting topic: the food web!

5 Likes

D: Some of us want to ruin planets in the microbe stage, sentiant.

1 Like

You can! It’ll just take multiple editor cycles.

every1 gangsta still someone finds a glitch to circumvent this

The amount of ants in this fourm is just Amazing

4 Likes

welcome
(To our community)

Welcome another ant!

Hello fellow ant.

Our brotherhood expands further

1 Like

Can mods still change people username and profile pics? it be cool to have an ant apocalypse like the goat apocalypse.

1 Like

The REVOLUTION is coming.

2 Likes

Perhaps this is because primordial Earth’s biosphere had more types of biochemical processes, which could have led to an equilibrium, whereas the current game doesn’t have that many types of processes, which could eventually be fixed (if only we had more programmers :-]).

Wouldn’t the cyanobacterium have lower population at the end since the heterotrophs would eat them for glucose? Unless that is part of the food update.

Just a sidenote: in your graph, we can see the numbers but it would be ideal if you named the axes and specified their unit if needed. Also the title should be a little more accurate than “Pangonian Coast”. I would have suggested to name it “Population variation based on environmental input (Pangonian Coast)”. This methodology would be useful since it makes the reading a lot easier.

When is the next update?

I doubt it. Adding more complexity to a system increases the amount of chaos. So by leaving out any processes that aren’t necessary to reach equilibrium we are actually increasing how predictable the simulation is. Adding more processes would just make it even harder to balance them all.

That is part of the food web update. And I should point out that even with predation, predators almost always have lower population than their prey. After all, even the best predator can only steal a fraction of their prey’s energy. Not all of it, and certainly not more.

I will do this from now on

@muppi
You can expect the next update tomorrow probably. I’ve done the math and figured out an algorithm already, I just have to implement/balance it.

4 Likes

Today I implemented predation into the simulation based on a foodweb.
The simulation now keeps track of who eats who, and then transfers compounds between species each timestep in accordance with that.

Every species now has two new behaviour parameters: Aggression tells them what percentage of the timestep they should spend hunting microbes, instead of gathering clouds. PreyPriorities tell them who to hunt.
During the time spent on hunting, a microbe looks for its prey using the same algorithm for gathering clouds. However, when a microbe finds its prey, instead of ‘gathering’ it, this merely creates an encounter.
During the encounter the faster microbe can choose whether to break off the encounter alltogether, to fight in melee (where both toxins and pilus/engulfment can be used), or to fight at range (where only toxins are used).

Why always the faster one? What about endurance predators? Or ambush predators?

In Nick’s simulation predators can still hunt prey that is faster than them, by running them to exhaustion or accelerating faster than them. I could also imagine a predator that hunts by catching its prey before they can even react properly, sort of like crocodiles. However, in the current game none of these predators exist. Acceleration, endurance and speed all rise in lockstep based on your microbe’s mass and its flagella. Thus the faster microbe will always be able to escape (to safety or to ranged combat) regardless of the scenario.

The fastest microbe will always make the decision that results in it getting the most compounds in the long run. If it chooses to fight, we calculate who wins in combat what fraction of the time.

How do we calculate who wins in combat what fraction of the time?

We give both microbes a survival score. A microbe’s chance of winning = score / (score + opponent’s score).
A microbe can increase his own score with defensive organelles like a better membrane, or lower his opponent’s score with offensive organelles like toxins and pili. Note that with this formula it is better to raise your own score if your chance of winning is under 50%, and better to lower the opponent’s score if your chance of winning is over 50%. In other words: if you’re a helpless prey who gets eaten to much, get defenses. If you’re a deadly predator who wants to kill prey even more efficiently, get weapons.

The exact formula for the score’s I determined mostly by my own experience as a long-time player of the game:

  • Toxins: -5 to opponent per prokaryotic toxin, -7 to opponent per eukaryotic toxin.
  • Pili: -10 to opponent for the first one, -5 for the second and third. -2 per pilus for any futher. They can also block toxins: +4 for the first pilus, +2 per pilus for any further, only to counteract subtractions from toxins.
  • Health: + Health / 10
  • Physical Resist: +(Health / 1000) per point of physical resist, only to counteract pili.
  • Toxin Resist: +(Health / 1000) per point of toxin resist, only to counteract toxins.
  • Engulfment: Counteracts your opponent’s entire health if you’re bigger than him.

When a microbe wins in combat, the compounds of the enemy (both the ammonia and phosphate they contain, and the average amount of compounds they would have gathered by now) are transferred into the winning microbe.
Naturally, we work with averages, so a species gets exactly: fights * (PWin * enemies compounds) - (PLose * Your Compounds). This results in predators stealing the compounds of their prey.

With this set up, I tested whether predation is worth it. In a new patch the answer is a resounding NO. There is so much ammonia, phosphate, and glucose available in clouds. Why would you ever want to fight for it if you could get it for free?
But in a more developed patch it becomes more interesting. For example, let’s say that cyanobacteria have taken over the pangonian coast. All the glucose is long gone and there are so many of them (say, 10,000) that trying to compete for ammonia and phosphate is pointless. What happens if we introduce P. Abyssus (two hexes of cytoplasm) into the patch with…

  • Agression = 0. They won’t be predators and try to subsist on clouds. There are no glucose clouds. They starve in the first timestep. Even if there were glucose clouds they only survive for about 5 timesteps and then die due to being unable to compete for ammonia and phosphate.
  • Agression = 1. They will spend the entire timestep slaughtering cyanobacteria until their entire glucose need is satisfied. By the around the 6th timestep every cyanobacterium has been killed. P. Abyssus realises it’s made a terrible mistake and starves to death.
  • Agression = 0.1. Now we’re talking. I actually bothered to make a graph of this:

    As you can see the population reaches an equilibrium with predatory P. Abyssus surviving because they don’t overhunt their prey.

This is great new but also kind of weird. In real life predators hunt until they’re satisfied, not until some evolutionarily acquired instinct tells them to starve themselves for the sake of the ecosystem. What we really need is some way to reduce the amount of prey a predator can hunt that doesn’t depend on the predator behaving nicely.
That’s why I’ll see you in the next update where I’ll be making a very crude version of Nick’s camouflage and detection system.

7 Likes

Time for a heckin’ triple post. Today I implemented detection as a way of softcapping predators in how many prey they can find.

First the math:
Most of this has been done for me by @NickTheNick , as I couldn’t find many errors in his math. Unlike Nick, I will not be covering multiple senses, since microbes in the current game have only one sense: chemoreception. This sense has a range, which I will determine manually for now as there are no organelles that influence this.

Next I stole the idea he stole from @tjwhale : using equations from Collision Theory (a theory in chemistry) to find how many microbes will run into how many things in a given amount of time. All I had to do was modify the equatino to work in 2 dimensions, as patches in the microbe stage are squares, not cubes:
Things detected per m2 per timestep = Population density * Thing density * sense range * Average speed of you and Thing.
Note that this formula works for any Thing that can be detected, so we can implement it for clouds too. Naturally clouds have a speed of 0.

Next we find the actual amount of things detected in the entire patch:
Things Detected = Things detected per m2 per timestep * Patch area.
Some of you may notice that there’s nothing preventing the Things Detected from being higher than the amount of Things in the patch. This is intentional: one Thing can be detected multiple times as the microbe swims past it. This will not allow microbes to eat more things than there are in the patch.
This formula is an area where I disagree with Nick. He says that the Things Detected should be multiplied by the amount of time spent hunting for that thing. However, this assumes that microbes only see things when they are specifically looking for them. I think it’s better to assume that, given that the formula assumes random movement like in chemistry, microbes are detecting things throughout the entire timestep. It’s just that they stop acting on that once they’ve had enough of the compound they’re detecting.

Finally we just tell the simulation that microbes can never hunt more things than they’re detecting, whether it’s clouds or prey.
Now let’s see what happens when we run the same scenario as last time, but turn P. Abyssus’ Agression back up to 1 (and give the microbes a sense range of 0.05 length units, 1/2000th of the entire patch):


You will notice three things about this.

  1. We succeeded in putting the system in equilibrium by softcapping predation. Predation no longer randomly destroys ecosystems :partying_face:
  2. I forgot to name the graph.
  3. The population of the predator is really tiny compared to the prey. This is partially just realism: There are more plants than animals on this planet. But it’s also because of the way energy works in this game. There is no way to convert prey into energy in the current game. This means predators have to live off, essentially, the stomach contents of their prey. I do not expect trophic levels above the 2nd to be viable unless the devs change this.
8 Likes

It’s been three days since the last update so I figured I’d update you on what I’ve been thinking about over the weekend.

I’m happy with the concepts implemented into the discrete algorithm. Obviously I could go on for ages adding stuff like storage, binding agents, more advanced behaviour, etc. But I feel that now all of the most important building blocks of an ecosystem are in place I’m better off prioritising other stuff, like:

  • Getting performance to the point where you could actually implement this in a game.
  • Calculating population in a continuous way instead of timestep-by-timestep.
  • Making the microbes in the auto-evo algorithm evolve.
  • Turning it into a real mod for the real game instead of a weird console application.

To take care of the first two issues (and make the other two possible) I’ve been trying to make the algorithm get to the equilibrium population more directly instead of stepping through every single timestep.

I devised two ways of doing this:

  1. We treat the timestep-by-timestep algorithm as a sequence of populations, and the calculation for getting the population on the next timestep as a recurrence relation. It would take a lot of boring math work, but I could then (theoretically) solve the recurrence to find a formula that takes in a number of timesteps and outputs the population on that timestep, without looping over every previous timestep to get there.
    Some calculus could then be used to find more interesting stuff. For example, if we find what happens when the length of a timestep → 0, then we could make a truly continous algorithm. And if we found out what happens to that when #timesteps → ∞, that would be the equilibrium population.
    Unfortunately this sounds very hard. And our algorithm contains a lot of minima/maxima/if-else stuff. Since you can’t know in advance what value will be smallest/largest/true at a given timestep, you have to calculate all of these things over and over for every possible case. That could end up taking even longer than looping over every timestep would have.

  2. Alternatively, we could ditch the timesteps alltogether. What makes me think of this is that a lot of the minima/maxima/if-else things I was talking about above are there to, essentially, cap the population at a certain level. A species cannot take more compounds than the patch contains, it cannot have a success rate higher than 100%, etc. So what if we just calculate what the cap is directly instead of bothering with what the population would actually be at a certain point in time.
    While this may sound like I’m throwing away all of my previous work to create a new algorithm, it’s not really like that. A lot of the math is still the same, we’re just rearranging the building blocks in a different way. I also like how this approach depends on more intuitive math, because my brain is, in fact, incapable of understanding anything above high-school level.

I think I’m gonna try approaching 2 first, and if that doesn’t work fall back on approach 1.

4 Likes