Crash Course in Population Dynamics (Abridged)

This is a shortened version of the Crash Course in Population Dynamics with only the most important posts kept.

Part 1

In this thread (depreciated link) I've been explaining how the compound system will work (summarized here (depreciated link)). I'm now going to take one step back and explain how the compound system fits into the simulation of a community of species which inhabit a biome.

Population Dynamics crash course

First though, I need to explain what I mean by population dynamics, as it's not something I expect many people will be familiar with. I'll try and give a crash course, but this sort of thing is taught in the final year of an ecology degree, if at all, so it's fairly advanced. The maths I'll use isn't quite as advanced, and you should have encountered most of it by the end of high school if you didn't drop maths. Note that units are very important in population dynamics, so I'll be paying a lot of attention to them. I'll give more reasons why when it's appropriate, but for now it's enough to say that the overall value for the rate of change of a population must be measured in individuals per unit time. I'm going to use years as the unit of time for now, but these equations can ussually be scaled to any time-scale easily enough.

The population dynamics of a particular species summarises all the influences on that species population level into a single rate of change, and we use this rate to calculate how that population changes at each point in time.

Exponential growth

At its most simple a population is influences by just two factors: birth and death. Birth (b) is measured in individuals per individual per year, that is, the number of babies each individual is expected to give birth to annually, its effective unit then is 'per year', or year^-1. Death (d) can also be measured in individuals per individual per year, which represents an individuals average yearly chance of dying (effective unit: year^-1).

Now we combine these rates. Our population at time t is x(t) (unit: individuals), and our rate of change is dx/dt (individuals per year). Our first equation is:

dx/dt = b x - d x
dx/dt = (b - d) x
rate of change = births per year - deaths per year

This is an ordinary differential equation (ODE), which describes the rate of change of a variable according to its current state. In effect, the rate of change of a population can be written as a function of the current popoulation and the current time, where birth and death are constant parameters. Note that in our equation we don't use the current time, this is something we'll introduce much later.

dx/dt = f(x,t)

We can integrate this function to find the population at any time t. Given a starting population of x(0)=1 at time t=0, we can calculate:

x(t) = t0 exp(t (b - d))

I'm not going to explain how you integrate an ODE, becuase doing so very quickly becomes impossible as the equation becomes more detailed, so that in reality you almost never actually do an integration (and we certainly won't be able to in Thrive).

Instead what we do is simulate the progress of the ODE, or system. This means that you iteratively calculate the population x(t+1) at a future time, based on the population at the current time x(t), until you get to the time your interested in. The most basic method of doing this is the Euler method:

x(t+1) = x(t) + f(x(t),t)
x(t+1) = x(t) + (b - d) x

What we can see from this last equation is that the population will increase or decrease depending on the ratio of births to deaths. If birth rate is higher than death rate, population will increase, if lower, population will decrease. What perhaps isn't so obvious is how the population will increase or decrease. Becuase the rate of change is multiplied by the current population, the rate of change will be higher if the population is higher, so that growth becomes exponential (as hinted by the equation for x(t)), growing ever faster all the way to infinity:


Similairly, if death rate is higher, the population will decrease, ever more slowly, until it goes extinct (x=0):


As can be seen in the above equations, birth rate and death rate combine to define the population growth rate (r, unit: individuals per individual per year, effectively: year^-1) in a very simple way:

r = b - d

We'll use this simplification below.

Carrying capacity

In reality, populations don't grow to infinity. That's becuase theres never enough resources to support an infinite population, in effect every population is limited to a particular carrying capacity (K, unit: individuals) within its environment. That is, the maximum number of that individuals which can be sustained indefinately. If the population rises above this capacity (which is possible), it will eventually fall again as individuals starve due to a lack of food or other resources. The equation for this is:

dx/dt = r x (1 - (x / K))

The first part of this equation (r x) is equivelant to our previous system (r = b - d; r x = (b - d) x), the second part (1 - (x / K)) is new. To see how it behaves it's easiest to calculate the value of dx/dt (= f(x,t)) for a few values of x, we'll assume for now that K = 1:

x = 0:
dx/dt = r 0 (1 - (0/K)) = 0
Theres no population to grow, so the population stays steady at 0.

x = 0.1:
dx/dt = r 0.1 (1 - (0.1/K)) = 0.1 r - 0.1^2 r = 0.1r - 0.01r = 0.09r
So long as r > 1 (equivelant to: b > d) the population will grow, albeit fairly slowly.

x = 0.5:
dx/dt = r 0.5 (1 - (0.5/K)) = 0.5 r - 0.5^2 r = 0.5r - 0.25r = 0.25r
This is actually the fastest rate at which the population can grow or decline (except when the population is far above the carrying capacity, which rarely happens in reality).

x = 1:
dx/dt = r 1 (1 - (1/K)) = 1 r - 1^2 r = 1r - 1r = 0
The population is at the carrying capacity, and will not grow any further.

x = 1.5:
dx/dt = r 1.5 (1 - (1.5/K)) = 1.5 r - 1.5^2 r = 1.5r - 2.25r = -0.75r
The population is above the carrying capacity, and will fall until it reaches that carrying capacity.


Now, it's also possible to see a few flaws with this model. For example, at x = K, f(x,t) = 0, no matter the value of r. In effect a population at it's carrying capacity cannot change, even if its death rate is far higher than its birth rate. This is becuase the model represents an over-simplification of reality. However, the model is still useful, and provides a few good insights:

r- vs. K- selection

r-selected species are those which have a very high reproductive rate, but relatively short lifespans. They are able to quickly increase their population, especially after a disaster or other event destroys part of it. Conversely, they tend to die off quickly as well, so that when resources are scarce, their population will quickly fall to a lower level. In a chaotic environment, their population levels tend to continually rise and fall, without ever really stabilising. They tend to produce huge numbers of offspring, but make little to no investment in their survival (e.g.: small eggs with very little energy reserves, no parenting), which therefore have a very low survival probability. Effective reproduction relies on the sheer number of offspring produced, not their quality.

K-selected species are those which have relatively long lifespans, generally with a relatively large body size, and a relatively lower reproductive rate. Their populations are very resilient to change, and tend to react very slowly. This means that when disaster wipes out part of the population, it can take a very long time to recover. However, it also means they can smooth over the oscillations of a chaotic environment, holding their population relatively steady, without booming or busting as much as an r-selected species. They tend to produce a relatively small number of offspring, but invest significant effort in their survival (e.g.: eggs with large energy supplies, or in the extreme case of mammals and sharks the offspring are actually carried within the parent until they 'hatch', extended parenting), so that each offspring has a much higher chance of survival. Effective reproduction relies on the quality of offspring, and each one is fairly precious.

Equilibria and stability

This model has two equilibrium points, extinction (x* = 0), and population saturation (x* = K), x* represents an equilibrium value of x. This means that for most parameters values (exception: r = 0), the population will approach one or other of these equilibria depending on the parameters, and initial conditions (x(0)), as time increases to infinity. Equilibria can be described as either stable or unstable (or occasionally semi-stable, or even neutral, but that's for a later lesson).

Crudely, stability is defined as: if, when simulated in forward time, a point near x* remains near x*, or converges to x*, then x* is considered stable, (also called an attractor). If the point diverges from x*, x* is considered unstable (also called a reppeller). Note that in more complex systems the point can travel a very long way away from x* before returning and eventually converging, but for most of the examples we'll use it'll be fairly obvious whether an equilibrium is stable or not.

If r > 1, extinction (x*=0) is unstable, and population saturation (x*=K), is stable. If you start with 0 population (x = 0 = x*), then you will always have 0 population, however, if you have even the tiniest fraction more than 0 (e.g.: x = 0.000001 > x*), then x will diverge from x*, the population will grow up to the carrying capacity, and therefore extinction is unstable. Similairly for population saturation (x*=K), an initial condition of x(0) = K = x* will neither grow nor decline, but any other value of x (> 0) will eventually converge on x* = K, so that x* = K is a stable solution, which attracts nearby trajectories.


That's enough math for one day, hopefully most of it made some sense. If not, let me know and I'll try and improve my explanations, also let me know if I'm going too slow. If anyone is especially interested let me know and I can tell you a lot more, as well as recommending a few good books. This (population dynamics), along with the math involved (nonlinear dynamics), is what I do for a living (for minimum wage, mind you :roll:), it can be absolutely fascinating, is an incredible tool for understanding nature and the world around you, and, sooner or later, will cause a complete brain-meltdown…

It can also be nicely summarised by one of my favourite quotes: "all models are wrong, but some are useful" (George E. P. Box)

Next lesson: I'll introduce a second species, and look at how predator and prey interact with eachother.

edit: replaced the figures with some of my own, for a more consistent style.

Part 2

Thanks. I basically agree that birth and death rates are the important part, and that they are whats evolved by auto-evo, but thats still a vast oversimplification of what we actually need to do (I'll be covering this in the next two lessons). As we've seen in the auto-evo discussion before, it's not enough to say 'species a reproduces faster', we need to know why (higher fertility, better survivability of offspring, more succesful feeding?).

Using the birth and death rate, and a survivorship curve, is a very good way of summarising a species population dynamics, it's just doesn't provide enough detail to get interesting auto-evo'd species. It's probably a good way to represent a players species fitness to them though.

I also largely agree with the use of generations, but more for use with auto-evo (for timing mutations) than reproduction. One of the nice things about ODE's is that we can simulate them over a period of time, and find out whats happening in that entire period, without too much calculation. i.e.: while we might only update population numbers every generation, the changes is the result of individuals born thoughout the whole generation. I'd also like to see different species able to reproduce at different times, but I suspect your definition of generation isn't as strict as mine, so that works anyway.

In effect what you say is correct, but I'm more interested in working out how particular mutations affect birth/death/survivorship, and how the traits which are mutated affect the population dynamics. More on that in a few lessons time.

Next lesson below, note that I wrote this last night, before reading scio's post above:

Predator prey models

Right, now that we've covered some very basic examples, lets look at something more interesting. Rather than looking at one population, what happens when two interact?
The classic example is the Lotka Volterra Model, which deals with a predator (e.g.: fox) and a prey (e.g.: rabbit) species.

The equations are:
dx/dt = (a * x * y) - (b * x)
dy/dt = (-c * x * y) + (d * y)

Where a, b, c, d are parameters, x is the predator population, and y the prey population. I've chosen to name the variables x and y, but I could equally call them x(1) and x(2), which I will be using in future, but not for this example.

Theres actually a lot going on here, so I'll break it down into pieces:
(a * x * y)
This represents the increase in predator population as a result of it predating the prey. (x * y) is the encounter rate between the species, i.e.: how many times (per year) you can expect two individuals to meet. 'a' is the efficiency with which these predations are converted into more predator population (units: new individuals per encounter (individuals sqr) per year, effectively 1 per individual year).

- (b * x)
Loss of predator population via mortality, 'b' here is equivelant to 'd' in the exponential model in the last post (units: individual per individual per year)

(-c * x * y)
The loss of prey population due to predation, 'c' is the number of prey individuals lost per predation (units: 1 per individual per year). For readability, I would ussually define the ratio between c and a, rather than indivually defining them. So, rather than saying c = 0.8 prey individual dies per predation (not every hunt is succesful), and a = 0.1 predator individual is born (it takes a lot of food to feed a new infant), I would say c = 0.8, and A = a/c = 0.125 = 1/8 predator individuals are born per prey individual killed (A units: individual per individual). The above equations would then be:
dx/dt = (A * c * x * y) - (b * x)
dy/dt = (-c * x * y) + (d * y)

+ (d * y)
Gain of prey individuals from reproduction. In this model we assume that the preys reproduction is exponential, with no limitations.

The result looks something like this:


Whats immediately obvious is that the populations fluctuate. They don't increase to infinity, or decrease to extinction (though with different parameters, either of those are also possible - if the predators over-hunt the prey goes extinct, then the predators have nothing to eat and also go extinct. If the predators aren't able to eat enough they go extinct, and the prey is able to increase exponentially). Instead, the populations enter a stable cycle: when there are lots of prey, the predators have lots of food so their population increases; this increased predator population depletes the prey population, which crashes; the predators then don't have enough food, so their population also crashes, at which point the prey population can increase again. This cycle is stable, and will carry on for all time (given the assumptions we've made). Interestingly, the results of this very simple model can be observed in actual data for many predator-prey species interactions in reality.

I'd also like to introduce another way to look at this data, a phase plot, which plots the trajectory of a model against its variables, rather than time. This lets you see the population level of one species for a given population of another. It also shows you how the trajectory either approaches a stable equilibrium point, or as in this case, a stable cycle (other possibilities, such as chaos, also exist) depending on the the model, its parameters, and your starting variables (initial value).


Here we can see that, as expected, the phase plot is a cycle. Note that the trajectory here moves clockwise, which can be made clearer by adding flow arrows to show in which direction the phase trajectory will move at any point in phase space, and how fast:


From this we can also see that the trajectory flows much faster in the bottom and right of the plot, where the populations are decreasing, than in the top left, where they are increasing.

I've introduced these plots mainly out of interest, I'll be using them in future to illustrate more interesting points.

Three species interaction

The main problem with this two species model is that we don't know where the prey gets its energy from, so to expand on it we'll add a third population, the resource (e.g.: grass), as a food source for the prey. The equations are very similair to those above:

dx/dt = (a * x * y) - (b * x)
dy/dt = (-c * x * y) + (d * y * z)
dz/dt = (-e * y * z) + f - (g * z)

As before, we have predators (x) reproducing by predating on prey (y), and losing individuals to mortality. We have prey reproducing by consuming the resource (z), and losing individuals to mortality from predation. An finally, resources reproducing at a constant rate 'f' (individuals per year) due to the constant energy input from the sun, and losing population to consumption by prey. We no longer have the potential for infinite growth, as each species now ultimately depends on the constant energy available from the sun for its population, and this energy is effectively shared between the species according to the parameters used (i.e.: how efficiently each species gets and holds onto that energy).


We can see here that there are no longer any stable oscillations, but rather that ther trajectories follow a damped oscillation before stabilising. Not quite so interesting as the previous model, but we'll fix that next time. Note that here the prey population is higher than the resource population, this isn't so realistic for rabbits and grass, but if we were intead looking at squirrels and oak trees it'd be far more reasonable. The phase plot shows the same information, but illustrates the lessening cycles:


I've only plotted the trajectory in the predator and prey axes above. It is possible to plot in 3D with the resource, but this actually makes the graph less clear.



This three species model is a *very* simple version of what I'm trying to develop for Thrive, but it includes a lot of important elements. The population of each species is now capped naturally (by the suns input energy), not by an arbitrary carrying capacity. Each consumer species is dependant on a lower trophic species for its energy, and suffers predation from higher trophic species. And most importantly, the stable population of each species is dependant on the values of the parameters which define how efficient each predation process is, and these parameters are what could effectively be evolved by auto-evo.

Now, the parameters we have now (a-f) are far too simple to be of any real use, it doesn't really mean anything if a fox becomes more efficient at hunting a rabbit, we need to know how (is it faster, sneakier, stronger, better camouflaged, more toxic…?), so there's still a lot more to build on top of this… all in good time.

Next lesson time I'll be looking at seasonal forcing, and what happens when sunlight is no longer constant (i.e.: stronger during the summer, weaker in the winter). I'm also going to be working on a *very* simple example of auto-evoing the parameters above to give you a better idea what I mean… no promises it'll work though.

Please let me know what you think of these… are they too long, too complicated, too slow? If you think anything needs a better explanation or more detail, please let me know. You've probably also noticed I did a lot less analysis of the examples this time, this is partially becuase as the models become more complex, the analysis becomes much harder to do, but also becuase I'm actually far more interested in developing the models than analysing them. I also didn't want to go too overboard on the graphs, even if they are relatively small files. If you want more analysis though, I'll happily add more.

Part 3

That's pretty much what I though you meant by generation, and actually works perfectly with what I had in mind. So, every generation, we update the population counts and run auto evo, based on information from the previous generation.

Using these models its actually very easy to see which mutations will be benificial, as well as by how much, so it should work very nicely for choosing benificial mutations and applying those (though there will be some randomness added). The models also *only* work with populations, they completely ignore the individual, which in our case is actually rather useful.

Actually, determining the effects on other species (within the same area/biome) is just as easy as determining the effects on the mutated species. However, as I remember the current auto-evo concept, species only react to mutations of other species in the previous time step, not the current one.

One thing I rather dislike about the models in the last post is how disconnected they are. Each species is affected only by its own parameters, whereas in reality they'd all be related. I think the easiest way I can explain the problem is that in the above model, energy isn't conserved. Taking just one interaction as an example:

dx/dt = b * x * y
dy/dt = -c * x * y

Which is the predation of y by x. If b is large and c is small, then we see a large rise in x's population for each y killed, whereas of b is smaller than c, we see a small rise in x's population for each y killed. The former is ok for something like a leafcutter ant predating a tree, the latter is more reasonable for most larger species (e,g,: for a lion, even a meal as large as a wildebeast will only partially feed a new cub). If we allow each species to evolve their parameter independantly, b will be maximized and c minimized, so that you get an unrealistically large increase in x for a very small decrease in y.

To make it more realistic, we have to make it a lot more complicated, by introducing a few new parameters:
s - the ratio of x's body size to y's body size (units: kg per kg, i.e.: none)
e - the efficiency with which x uses a kill (units: individual per individual, i.e.: none)
v - the proportion of hunts which are succesful (units: individual per hunt)
d - the proportion of encounters which lead to a hunt (units: hunts per encounter)

the equations now become:
dx/dt = ((e * v * d) / s) * x * y
dy/dt = -(v * d) * x * y

First, I should explain that this is still a simplification. 'v' encompasses many more parameters, such as relative speed, strength, stealth, toxicity etc. 'd' includes how sensitive creatures are, as well as how quietly they ussually move around, and perhaps how hungry they are. 'e' includes the proportion of y which can be digested by x, how effectively x defends its kill, how large a meal it can eat in one sitting, and how much of its own energy is used in feeding. 's' depends on a whole load of relatively obvious factors.

In effect, each of the above parameters is a compound parameter, itself depending on many more parameters. Both species have traits which affect all of these parameters. The prey species can, for example, evolve toxins to both reduce the success of hunts and make itself less digestable, reducing 'e', the predator can become more stealthy to increase 'v' and possible 'd'. Any changes to these traits will have effects on other areas of a species population dynamics, such as requiring more energy (or other resources), so every mutation has a trade off.

We've now also fixed the energy leak, though that's not immediately obvious. For a loss of 1 individual of y due to predation, x increases by 'e / s' individuals. 's' is easy to explain, as its the size ratio of of the two species, 'x' is 's' times bigger than 'y', so every individual of 'y' contains '1/s' times as much energy as an individual of 'x', so that the equations are ballanced in this sense. 'e' is actually an intentional leak (0 <= e <= 1), '1-e' of every kill is wasted, atleast by the predator, and lost, though we can add that waste into the environment for use by other species, such as detritivores.

… Now that I've written all that, I've forgotten what point I wanted to make with it. Something along the lines of the parameters for each species not being as nicely seperate as I showed above, but also that this doesn't actually matter, it's actually a good thing, as it makes the reactionary mutations we want in auto-evo automatic. If a predator increases its hunting effectiveness in one generation, the prey will be affected, and will be more likely to do something to reduce that hunting effectiveness in the next generation.

Finally, its not quite as clear cut as *only* being able to increase birth rate or decrease death rate, many mutations will change both, perhaps increasing birthrate and only slightly increasing deathrate. Looking back to the first post, remember that 'r = (b - d)', in effect, all mutations should increase r. This may also be a good point to say that r is one possible measure of fitness, something we've had a hard time calculating in the past, but may now be quite possible.

I've actually made some good progress writing a very naive auto-evo implementation using the three species model above. It's got a lot of flaws right now, but I know how to fix most of them, and will post some of the results, along with the next lesson, early next week.

Part 4

I've left this topic for far longer than I meant to… I had promised another lesson, and a naive auto-evo prototype over a month ago, and they are finally included below. Partially I've been distracted with work, but also by trying to coordinate the programming effort, which has sapped some of my motivation for other aspects of Thrive. To make up for that, I'll be concetrating my effort on Thrive on the compound and population dynamics systems for the next few weeks, both of which I find far more enjoyable, so expect quite a few more posts here shortly.

From here on I'll be developing two things simultaneously. Firstly, I'll continue introducing and explaining population dynamics theory, as I have done in the previous two lessons. In part, this is becuase I think many of you will be interested, but understanding some of this will also greatly help you understand (and contribute to) how I'll be using this for auto-evo. Secondly, starting in this post, I will be developing and auto-evo implementation by applying this theory to what we know about how we want Thrive to work.

Seasonal Forcing

Continueing on from my previous lesson (about 7 posts above this one) we ended with a three species model, representing a resource, a consumer and a predator. This is starting to look a lot like an ecosystem (though as Calli pointed out this is a food chain, whereas we eventually want a food web, with multiple species at each trophic level) with multiple species interacting with eachother, all eventually dependent on the environment (sunlight intensity). In another lesson I will look at expanding the number of species and their relationships (predation, competition, symbioses etc.), although how we do that should actually be fairly easy to imagine from what you've seen already. For now though, we need to look at the other half of the ecosystem: the environment, which up till now has been static. (Note that what we've considered so far, the collection of all species within an ecosystem, is known as the 'community')

In reality the environment is dynamic, with constantly changing levels of sunlight, dissolved nutrients, temperature etc. Building on the three species model, to keep things simple, we have only one environmental variable: sunlight intensity. Me and Scio had a long discussion over PM last month about how to calculate sunlight intensity for different lattitudes, times of year, times of day etc, but for the purposes of this lesson we'll keep it really simple:

S(t) = (1 + sin(t * pi * 2))

where S(t) is sunlight intensity at time 't', where one year corresponds to a change in 't' of 1. Effecitvely, S(t) is smallest when 't' is near a whole number (t = 0, 1, 2. i.e.: the start or end of a year), and greatest in between (t = 0.5, 1.5, 2.5, i.e.: the middle of a year). The results aren't particularly realistic, in the middle of winter S(t) = 0, and in mid-summer S(t) = 2, but they'll do for now.

EDIT - I've just noticed I should've used cos for this, as here we have summer around 0.25 and winter around 0.75, with spring at 0 and autumn at 0.5. That's not very clear, but it works fine for the simulation so I won't change it now.


Plugging this in to our previous three species model, there's only a small change, highlighted below:

dx/dt = (a * x * y) - (b * x)
dy/dt = (-c * x * y) + (d * y * z)
dz/dt = (-e * y * z) + f * S(t) - (g * z)

where 'f' is now the efficiency with which species 'z' converts sunlight into new individuals. The units to this are a little nasty: Sunlight intnsity can be measured as energy per unit area, ussually megajoules per square meter. 'f' then has units: individuals per (megajoule per square meter) per year, or square meter individuals per megajoule year. That doesn't seem to make much sense, so here's an interpretation: 'f' must incorporate both the number of individuals born per sunlight recieved (individuals per megajoule per year), and the area in which those individuals are being borne: given that 'f' isn't density dependant, we'd expect many more cells born in 100m2 than in 1m2. 'f' can then be described as a compound variable: f = A * g, where A is the area of our ecosystem (the area over which sunlight is being captured), and g is the efficiency with which this sunlight is converted to new individuals (individuals per megajoule per year).

A note on notation

Remember from the first lesson that dx/dt is actually a function of x and t:

dx/dt = f(x,t)

where 't' the time at which we're calculating f, and it is this 't' that is used when calculating S(t). Additionally (I'm not sure if I've explained this before), it's worth mentioning that the 'X' in f(X,t) isn't just the population of species x, it's actually a vector containing the population of each species, such that the above equation becomes:

dx/dt = dX1/dt = f1(X,t) = (a * X1 * X2) - (b * X1)
dy/dt = dX2/dt = f2(X,t) = (c * X1 * X2) + (d * X2 * X3)
dz/dt = dX3/dt = f3(X,t) = (-e * X2 * X3) + f * S(t) - (g * X3)

The three functions (f1, f2, f3) can also be expressed as a single function:

dX/dt = G(X,t)

using matrix calculus rather than the scalar calculus above. That's not something I'm going to show below, and it's not really necessary. Whats important is that you understand that each population is part of a whole, and each equation has information about the whole community, not just its own population. I'll stick to the notation used previoulsy for readability, just remember the 'set' of equations we're developing can be expressed just as easily as a single equation.

Right… unintended detour over, what happens when we seasonally 'force' sunlight intensity? The three species model developed last time settled on a constant equilibrium state. We would expect that this model doesn't, as it's conditions are continually changing, so that the target equilibrium is also continually changing:


What we see is an initial period of stabilisation, as before, followed by a fixed oscillation. This oscillation is stable, and can be considered a cyclical equilibrium (technically a 'centre node' equilibrium, as opposed to the 'node' in the previous model).


What is interesting is just how chaotic the initial stabilisation period is. It looks rather unpredictable, with the prey population jumping from low oscillations to high oscillations. While the eventual stable oscillations are rather dull, this period of chaos before stabilisation could make things far more interesting. Importantly, this stabilisation process will happen any time the system is changed by an outside force, such as a disaster, or to a much lesser degree, a mutation.

Density dependance

Introducing density dependance to the sunlight intensity term:

dx/dt = (a * x * y) - (b * x)
dy/dt = (-c * x * y) + (d * y * z)
dz/dt = (-e * y * z) + (f * S(t) * z * (1-z)) - (g * z)

changes the behaviour somewhat, with stabilisation being a little more interesting again, and taking much, much longer (over 500 years in this case), but the specific effects aren't quite interesting enough for me to explore here (I have more interesting things in mind!):


That's all the lesson for now, let me know if anything needs more explanation (I expect some of it does).


ow for the main event, my first, *very* naive auto-evo implementation. I'll make two disclaimers before you read much further: firstly, it doesn't really work, it has quite a few issues which I'm working on fixing, but it does show the basic idea. Secondly, I wrote the code for this, and produce the figures, over a month ago, so I'm a little fuzzy on how it actually works. Since then I've been working on a far more capable version, but as that's not quite done, and a lot more complex than this, I though I'd present the simple version for now.


The equations used are those from the non-forced three species model, except that I've changed the parameter names to be a little more descriptive:

dx/dt = (p_x * x * y) - (m_x * x)
dy/dt = (-m_y * x * y) + (p_y * y * z)
dz/dt = (-m_z * y * z) + e - (d_z * z)

p_x is the number of individuals gained by species x from predation, and m_x is the number of individuals lost to mortality (either natural, or from predation). 'e' is energy from sunlight. Note that the graphs below have an error, p_z should be m_z, and d_z is mortality of the resource due to natural causes.

Generations and parameter selection

The population levels are updated each generation, which in this case was 1 on the timescale, at each generation, each species also got to pick a mutation. The population dynamics you should be now be familiar with, so I won't say any more about it. To pick a mutation, each species looks at the fitness change which would result from changing each of its parameters. For example, species x can change p_x or m_x (for some reason, species z can also control e). To do this, it calculates the partial derivative of its own function (e.g.: dx/dt = f(x,t)) with respect to each parameter, e.g.: Df(x)/Dp_x. (note 'D' isn't the correct symbol here, but its the best i can do on a forum). I can't explain how partial differentials work here, but they're actually very simple, especially if you already understand ordinary differentials, so have a look at the wikipedia article for more information. In effect though, this partial differential tells you how changing a parameter will effect the rate of change of your population, or more simply, how a mutation to that parameter affects your fitness.

What happens next is fairly obvious, whichever mutation has the greatest effect on fitness is picked (if the effect is negative, the reverse mutation is applied). This is very simple, very crude, and exactly why this model is very naive, but it (sort of) works.


What you can see here (not very clearly) is that the predator increases p_x, the prey slightly increases p_y, then decreases m_y, and the resource decreases p_z (actually m_z) and then later d_z. As I said, this isn't clear, and it's been over a month since I produced it, so I can't explain it much more clearly. In short, each species does what it's expected to, but for the most part they only mutate one parameter, with only the resource switching to mutate a second parameter later on.


The problem, as explained in a previous post, is partially that theres no cost to any mutations, benifits from predation are maximised, and penalties from mortality are minimised, wheras in reality theres only so far you can do so. Moreover, while I prevent the parameters leaving the range 0.05 < p < 1, the program doesn't actually detect when a parameter is at that limit, so that it continues to try and change that parameter, when it would be more benificial changing another parameter. Finally, it isn't realistically possible for a species to continually mutate one trait, as it will quickly run out of genetic diversity in that area; there should therefore be a penalty to how much you can mutate each parameter, dependant on how much it has already been mutated recently. All of these are issues I'm addressing in the next prototype.


These first two plots show the same thing, but at different scales. As you can see the predator population increases to a huge number, and oscillates around 200, whereas the resource appears relatively stable around 20, and the prey oscillates around 0.2. These are huge differences in population levels, and a direct consequence of having no costs associated with mutations. The prey is able to get a huge amount of energy from the small number of prey, keeping its own population high, and the prey population low. This low prey population doesn't do much to harm the resource population, which also stays relatively high. This is a neat (if very artificial) example of a trophic cascade where the abundance of predators indirectly increases the abundance of resources.


These two plots are again the same as above, but over much longer spans of time, showing that the system does eventually stabilise.



All in all, the behaviour isn't that dissimilair to the earlier models, mainly becuase auto-evo only actually does something for the first 10 generations, after which the population is allowed to stabilise with somewhat different parameters than before. In reality, these mutations would take place much more slowly, and there would also be many more parameters to choose from, so that auto-evo acted for a far longer time span. Additionally, seasonal forcing as shown above would mean that the environment the species are adapting to would be constantly changing, so that selection pressure would act in different directions at different times. Basically, this has a long way to go before it becomes interesting, but I'm working towards that in the next prototype, which I hope to post sometime in the next week or two.

As usual, I'd be very interested to hear any comments or suggestions!

edit - forgot to mention, next lesson will be on age structured populations.

Part 5

Ok, I'm not sure anyones realised this, but a lot of the discussion on the last page has been had before, on the first two pages of this thread. The idea being discussed is slightly (and only slightly) different, but the problems are the same. I've watched you circle some of the solutions, but also create more problems, so I'll try and fix some of them. As a bonus, I'll even try to include that pseudo code hypo's so desperate for.


We're discussing multiple different systems here, they all interlink, but I think theres been some confusion about which ones we're discussing here and how they all relate:
Population dynamics - controls the number of individuals of each species in each location. That's pretty much it, but it ties into pretty much every other system below, making it seem far more complicated than that. It monitors/processes birth/death rates, transfer of compounds between species (predation), migration between regions etc.
Climate - controls temperature and light levels (among others) across the planet, which is fed into the population dynamics. Light levels affect the available energy, temperature may affect metabolism, but also survival chances.
Auto-evo - what we really seem to be discussing here, despite it not being an auto-evo thread (even if it is very closely linked). Auto-evo selects which species get to mutate, and decides which mutations to apply. That's it, details later.
Compound system - controls what compounds have what uses, which can be converted to eachother, etc. It's also the target of most mutations, either by making a process more efficient (by making an organelle better), or enabling a new one, or developing a new compound (toxin). Conceptually the connectiong between the compound system and pop-dyn/auto-evo is the simplest; technically it's probably the most complicated, I'll see if I have time to get into it here or not.

Stages of auto-evo

This has been mentioned here, but I'll mention it again to make the following clearer:
1 - The player plays for a while, auto-evo is basically idle, though we may pre- or post-process stuff from other generations
2 - A generation ends, either becuase the player reproduces and opens the editor window, or a certain amount of time passes, and we do an auto-evo step in the background
3 - Auto-evo is passed a list of all species populations and their current states
4 - It selects which of those species get to mutate. As discussed here (depreciated link), this could be one species, many species, or even all or none of them. The probability of each species getting to mutate is seperate, and dependant on multiple factors including their population size, selection pressure (i.e.: how unfit they currently are), reproduction rate etc. If the mutation of another species had a particular impact on a species in the last round (someone gave an example of a predator evolving and it's prey not getting a chance), the affected species gets a much improved chance this round. As the discussion here centers around how to select mutations, I'm going to ignore this step and assume that every species gets to mutate every generation for this post.
5 - We take the information about how each species performed last round and decide which mutation is best for it now. In some circumstances it may get to pick multiple mutations, but again for simplicity when explaining I'll assume it only gets one. This is what we're discussing here, so details later.
6 - All the mutations are applied. By doing this after step 5, the order in which species mutate this step has no effect on what they decide to do.
7 - We generate new meshes and animations as needed, and load back into the game.

Apart from the generation of new meshes and animations, all of this is computationally very cheap, and can be done in the background, with biomes the player isn't currently observing being processed while they're playing.

A note regarding 4 - some of the factors for picking who gets to mutate may now be used (in the microbe concept we're discussing in the other thread) to decide how many MP each species gets to work with, so we need to double check this and make sure we're not using the same factors.

Selecting a mutation

Dani's post was a pretty good explanation of the current system, except in one detail - how we calculate fitness. This has been our problem from the start, and we've made several attempts at solving it, and come pretty close. The solution (I hope - there's no way of knowing for sure until we actually test it) is what was discussed on the first page of this thread, and pretty much just been discussed again on the last page or two, with a few alterations.

I'm going to go over a few of the suggestions since my last post yesterday, some are pretty good, but others have flaws which haven't been pointed out yet.

I'll start with Calli's post last night and work from there. I'm going to ignore whatever questions were left unanswered up to that point, becuase whatever answers hypo was after, you didn't do a very good job of asking the right questions - probably why it keeps looking like we're not reading half your posts, becuase we're simply not seeing whatever question or point you think was implied.

hypoxanthine wrote:

1) creature chosen for mutation by whatever method you like
2) random genome parameter selected to mutate
3) random increase or decrease of this parameter
4) depending on the genome parameter modified, increase or decrease one of the population parameters for the species (say were using Seregon's split-parameter version of Lotka-Volterra, if the speed of travel is increased by lengthening of legs, which youd test by doing just one quick simulation to measure running speed, then youd increase one of the parameters that make up the overall efficiency of predator-prey-encounter conversion to predator-individuals, like the probability of hunt success)
5) run population dynamics
6) land player on planet
7) probability of creature appearance based on number from population dynamics (in some way i havnt decided on, also based on area of biome and another pop. parameter of distribution)

Here we're just applying a completely random mutation (3-4) and seeing what happens. Yes, we update the pop-dyn (4) so that it will have some effect on population levels, but theres no actual selection going on. That is, unless you expect pop-dyn itself to take care of that selection, which it isn't really designed to. Yes, poor mutations will lead to a loss of population, but that loss of population doesn't really feed back into what mutation is chosen, you'll just get loads of very random species, most of which will die out.
We'll eventually get a good species by blind luck, but we're missing most of the aspects that make genetic algorithms effective - species don't mate with eachother, they don't reproduce asexually to produce new species (except when sub-populations speciate, but that doesn't help here). Effectively this is an GA with no interaction between agents, also known as blind trial & error.

hypoxanthine wrote:

1) select rand species to mutate
2) select rand popdyn parameter and increase by small rand amount
3) each popdyn parameter change has a genomic interpretation. if you split the parameters up more, youll eventually get things like 'speed, stealth, etc.' so if you'd just increased the speed popdyn parameter for example, this would change the leg randomly, then run a simulation to determine if speed had increased and then hill-climb until it actually has. stealth? no simulation needed here probably - hill-climb to a set colour for the particular biome (simplistic i know). you can imagine what else there would be.

This is close, but backwards and a little poorly defined. What your saying is that we first pick a random pop-dyn parameter to mutate, then pick a random associated genome/phenome trait to mutate to achieve that mutation, and then test to see whether that genome mutation actually achieved the desired pop-dyn mutation… that seems like a hell of a lot of work compared to the exact opposite:

1 - select species
2 - select a genome trait to mutate
3 - test what effect this has on the pop-dyn parameters, and what affect this has (I'll get to this later in the post) on species fitness
4 - if it's positive, accept the mutation.

Ideally, I'd extend this to trying every possible genome mutation (or atleast a large subset), and picking the most favorable one. That is your hill-climbing algorithm: pick the best possible mutation at every step. How feasible this is depends on the size of the genome and the computation expense of testing fitness, neither of which we're sure of right now, but I'm fairly confident that this is atleast feasible.

hypoxanthine wrote:

imagine a predator mutates and is now much better at hunting. unless the great random mutates the prey in time, theres a significant danger of extinction

I mentioned this in step 4 of the auto-evo process above. When species get mutated is an entirely seperate issue to how they get mutated, so we'd have this problem regardless of the system. Except that we have a solution, discussed in the thread linked in 4 above.

hypoxanthine wrote:

a good fix for this might be to weight the probabilities of mutation for a species by its current population count (smaller population => greater selection pressures => mutants are selected for more strongly on an agent level => mutant allele frequency increases much more quickly on population level => so on population level, increase the mutation rate

Pretty good, and similair to whats discussed in the linked thread in 4.

hypoxanthine wrote:

how is this preference decided for each predator

Prey preference should be an evolvable trait. I think Scio mentioned that we will have a food web for each biome, so we know who is capable of predating on who, all we need to know then is to what degree each predation actually takes place. This is partially preference, partially both predator and preys abilities to detect and avoid/find/chase/kill eachother, and partially availability (the higher the population densities of both predator and prey, the higher the rate of 'collisions' between them, and the higher the interaction rate, regardless of whatever else either species does to modify that rate). The degree to which each predation actually occurs, and how succesful it is, affects the fitness of both parties, and that degree therefore also decides how much of an impact that particular interaction has on each parties fitness, and how important mutations affecting that interaction are.

~sciocont wrote:

We're not idiots.


~sciocont wrote:

In this way, instead of changing the form of an organism and figuring out the downstream effects, we change the properties of the organism and then mutate the form to reflect that. It gives us a lot more control over the form of the organism and thus an extra layer of insulation against the "ugly creatures" problem.

As nice as this sounds, doing it simply isn't trivial. If we're incapable of figuring out the downstream effects of changing an organism (as suggested here and elsewhere), how do we go about changing those downstream properties, then going back and finding modifications which have the desired effect? The latter is only possible if the former is, and the former is a lot less contorted.

~sciocont wrote:

One interpretation of your popdyn parameter change is to simply boost the population (in the next generation) of the individual selected for mutation by some multiplier (5% or something, we can tinker with it based on the orgs population as a fraction of the community (biome) population) and then find a parameter change that might increase population by that amount. One problem I see with this is that, unless we have many different popdyn parameters for each species, mutations will be more or less arbitrary. Of course, if we're modeling every meaningful two-species interaction, then we need only add the multiplier to one of these parameters and then we have a more specific needed mutation.

I'm interpreting this as "boost a species fitness by an arbitraty value, and then find a mutation which would justify this boost", and it has the same issues as mentioned above. The problem of not having many pop-dyn parameters really is a problem, and we can't expect to have meaniingful or interesting auto-evo with the very few parameters used earlier on in this thread. I mentioned as much then, but only said that we'd need more than 7. We will need a lot more than that, representing things as specific as organism speed, mass, metabolic rate etc. I'll get back to this idea later.

hypoxanthine wrote:

1. select a random organism to mutate
2. randomly mutate two organs (or other) in said organism (these can either harm or benefit organism, it does not matter, the only required part to this is at least one be beneficial.
3. run simulator with both mutations added multiple times.
4. take results and put successes out of a whole of the simulation. (delete if success is 0 out of total and restart, unless of course you wish to keep it for an extinction)
5.depending on how they do in said simulation will determine the overall population change.
6. back in the environment the results will be reflected by how the population changes.

Apart from mutating two traits/organs at a time (why?), I really don't see how this is at all different to what Dani explained on the previous page - you do a random mutation, test if it's benificial, accept or reject it. The only real addition is that the performance in the fitness tests now translates to a population boost (is this a boost to population, growth rate, or what? you don't specify). Simple as that may be, the net effect is that our population simulations no longer obey the conservation of energy. If we give species arbitrary boosts to growth rates, we're giving them energy which they're not obtaining from a source (predation/consumption of another species or photo/chemosynthesis). We could attempt to balance this arbitrary change somehow, but that gets complicated.

Daniferrito wrote:

Actually, i dont think selecting a random parameted to addjust would suffice. Modifying any part of an organism has usually more than one parameter affected, which usually is the energy it takes to create a new creature (as it either became more or less complex or big) and another parameter depending on the specific part.

Good point - another reason we can't choose one pop-dyn parameter to mutate, then look for a genome mutation to achieve that, there would be too many side effects, some of which may make an apparently positive mutation negative overall.

hypoxanthine wrote:

if your worried about then why not have associated populome (bugger this im coining this term now) changes for each genome change

Getting warmer…

hypoxanthine wrote:

instead of having just one genomic interpretation of a populome change, have more than one associated genome change.
e.g. populome change: speed increased => out of possible genome changes for this event: longer legs selected (then sim to ensure this actually does increase speed). => genome change: more energy required for movement etc.

…but your still working backwards.

~sciocont wrote:

This should mean that the data for the organism's abilities is stored separately from the data used for its physical model and AI behavior

Do you mean abilities as in speed, strength etc., which are effectively the result of it's physical genome (leg length, muscle mass etc.)? If so, yes, there should be three layers of data:
1 - the genome, which is mutated by auto-evo. We have no way of assessing how fit a genome is without looking further.
2 - the abilities, or phenome (phenome in a different sense to how i was using it yesterday), which are the result of the genome. These are the result of either mini-simulations, or calculations.
3 - the pop-dyn parameters, which are influenced by a species abilities. It's only from these, and their effect on r, that we can actually calculate fitness.

hypoxanthine wrote:

so, as weve discussed, its effectively a hill-climbing algorithm. that immediately gives us a problem because hill-climbers are greedy, so they tend to get stuck

Yes, hill climbers get stuck, that's the advantage of GA's/simulated annealling/swarm sims etc. Simulated annealing may help, but all that really does is allow negative mutations at a small random chance. We already do this by having genetic drift - a small random change in a random trait. Also, I think your suggesting running this at every generation, effectively attempting multiple mutations until we either find a good one or give up and accept a bad one. If we allow this to go on too long, it would be simpler and a lot more efficient to simply try all mutations and pick the best one, or with small random chance pick a bad one.

Also, I really don't see the problem if it gets stuck. If the system finds a very effective genome (e.g.: a shark), why shouldn't that species survive unchanged for a very long time? The problem is if every species does that, and we end up with a static ecosystem, but given that this would require the environment to be static too, it shouldn't really happen. With a seasonal climate, long term climate change, catastrophes, and whatever changes the player makes, there should always be something for the AI species to adapt to, so they should become stationary. The simulations on the first page show that even in a trivially simple system, adding seasonality can delay stabilisation from a few 'months' to hundreds of 'years'.

Finally, if a species gets stuck in a local maximum, it may be unable to adapt to long term changes in its environment. If it doesn't get out of that maximum and find a better one before it's too late, that maximum may get to a point where it can't sustain the population, and it goes extinct. Tbh that's just realistic, species ussually go extinct becuase they're unable to adapt.

Pieces of the puzzle

Right, now I'm hoping to show how we've already solved most of these issues before. A lot of this comes from the various auto-evo threads, and a lot is relatively new developments from various discussions I've had with Scio and Calli (both on this thread, elsewhere on the forum and off it) and a lot of thinking over the past few months. I really wasn't ready to present this yet, partially becuase theres a lot of more basic things I need to introduce first (which I will briefly do here), and partially becuase there are still some issues I haven't had time to fix (which I'll point out, so we can hopefully work on solving them). First, back to the seperate pieces, from the bottom up:

Dynamic systems

Each organism is a collection of compounds, which are managed by the compound system. Organisms gain compounds from their environment, and other organisms, they process them internally using organelles or other processes, and they excrete waste compounds back into the environment. Some compounds are necessary for survival, others are harmful, an organisms basic aim in life is to have the right mix of compounds available to allow it to survive and reproduce.

At the population level, species can be represented as the number of individuals in an area, and the average compound contents of it's individual organisms. The compound system again manages these compounds, but the population is managed by population dynamics, which takes information from the compound system. If a population has insufficient access to a particular compound (e.g.: sugar), all it's members will suffer and the population as a whole will suffer starvation, reducing birth rates and possibly increasing mortality.

In addition to information from the compound system (the internal processes affecting a species' members), population dynamics also takes information from external processes, including predation, other interactions (e.g.: symbioses, competition) and environmental drivers (e.g.: light and temperature levels). All of these factors have some effect on a species ability to survive and reproduce, but it's far from sufficient to simply talk about birth and death rates, we need to differentiate (in the non-mathematical sense) these parameters into more specific parts, e.g.:

  • Species A mortality due to predation by species B
  • Species B energy/compound gain due to predation of species A
  • Species C (a plant) energy gain due to photosynthesis
  • Species A mortality due to exposure to envionmental hazard (toxin, extreme temperatures etc.)
  • Energy expended by species B when searching for prey
  • Energy expended by species A/B during a predation encounter (the chase/fight)
  • Energy expenditure required for species A to reproduce

This list is far from complete, and deciding all the necessary parameters and related equations won't be easy. This, along with a similair list of 'abilities' I'll mention later, are the two key issues we need to overcome to make this work. They're certainly not impossible though, just hard work.

Now we have something which is far more than a simple logistic equation or predator-prey model. It incudes those two things, but also many more factors, in calculating population levels. This appears overcomplicated for this purpose, but that's not the point. Knowing the population level of each species in each location is a side effect of the population dynamics system, what we actually want is a way of calculating species fitness. The simplest measure of fitness is r, or (b-d) as explained on the first page of this thread. It's pretty clear that it won't be any where near that simple with the parameter list above, but calculating it will be just as simple to the computer.


Now the other half of the puzzle. Each species has a genome, all members of a species in a particular location/biome (a population) share the same genome. Populations of the same species in seperate locations may differ slightly, and may eventually speciate if they're seperated for too long, but speciation and spatial dynamics (migration) are beyond the scope of this discussion. This genome controls the placement and number of organelles and limbs, the efficiency and size of those organelles, the efficiency of processes not associated to any organelle, the compounds available to the organism.

Derived from this information, and the definitions of each genome, compound, process and what each can do, is the organism/species' phenome. This phenome record the abilities of the organism. For example, if the genome specifies 3 mitochondria with an efficiency of x%, and the mitochondria definition says at that it can produce 1mol ATP per second at 100% efficiency, then the phenome records the ability to produce ATP from sugar at a maximum rate of 3*x moles of ATP per second (depending on the availability of oxygen + sugar). If the organism has the appropriate organelle (golgi apparatus + vesicles?), and the ability to produce a particular toxin, then the phenome records the ability to produce that toxin at a rate dependent on the efficiency of the golgi, and at a strength dependent on the level of the toxin. The phenome will also have a value for the organisms maximum speed, dependent on the types of motion available (flagella, cilia, pseudopodal), their number and efficiency, as well as the size and mass of the cell. Again these are examples from an incomplete list.

We also have a budget of mutation points, or genetic diversity, to spend on mutations. How exactly these will work is still being discuss in another thread, so I'll just assume they're limited, and that they may be split into seperate pools for different types of mutation.

Finally we have data both from the envionment and the Population Dynamics system: the number of each population, the density (dependant on the area of each location), acidity, temperature, light, environmental compound reserves etc.

Calculating population

Now we have all the pieces we need to calculate population. The population dynamics equations use the environmental, population and compound level data (variables), and each species' phenome (parameters) are combined to calculate a species reproduction and mortality rates, and therefore the change in its population for the next generation. An example:
From populations, we know the density of species A (predator) and B (prey), and therefore how often they are likely to meet eachother. From species A's phenome we know how likely it is to detect B upon meeting it, as well as how capable it will be of chasing B down. Combining this with B's phenome telling us how well it can escape or fight A off, and some other details from each phenome, we can calculate the chance of a meeting resulting in an individual of B being succesfully brought down. We also calculate how much energy this hunting process (succesful or not) costs each species, each species loses this much energy regardless. We then multiply the encounter chance by the chance of a succesful kill to find an overall predation rate. Population B loses members, and their embodied energy and compounds at that predation rate. Population A gains some of those energy and compounds at a rate depending on their digestion efficiency and their ability to defend the kill and consume it before being chased off. What doesn't get eaten by A is returned to the environment as a carcass, which may be decomposed or scavanged, whatever material isn't digested by A is returned as faeces. This is only one interaction between two species, there will be many more between both species and the environment.

All of this information is fed back into the next generation as changes to species populations, their compound reserves, and the environment - some of the data in the previous section.


Finally we come to the question of mutations. Everything else about auto-evo is pretty irrelevant at this point - we've picked a species, possibly becuase of a mutation to another species, possibly at random; we may or may not also apply a completely random 'genetic drift' mutation - all we're worried about here is picking the best possible mutation given all the information we have.

1. What we do is pick a set of traits in the genome, this may be small or may include all traits depending on how computationally intensive this all turns out to be.
2. For each one we then increase and/or decrease it as far as our mutation budget allows(for some upgrades we simply can't afford, we stop here and move on to another trait). We also consider one genome where no mutation takes place.
3. We then calculate the resulting phenome for each such possible change.
4. We calculate the predicted population growth rate in the next generation for each phenome.
5. Whichever change results in the greatest population growth provides the best fitness boost, so we choose that mutation. If all growth rates are negative, we choose the least negative. These population growth 'estimates' are calculated exactly as in the previous section, and include input from interactions with other species and the environment. Phenomes for other species are kept at that set at the last generation, so all species have the same information about eachother.

Steps 3 and 4 are the difficult bit. Wherever possible we need to find equations for these calculations, and I'm fairly confident that we can do this for most if not all situations. Where we can't, we resort to the mini-simulations discussed in the previous few posts, but that should be a last resort.

If your wondering, steps 2 and 5 are the hill climbing parts; in 2 you choose a few possible directions, then in 5 you find out which of those directions is uphill. I have just realised that this is a very naive hill climbing system, and we might be able to reduce the number of mutations we need to test drastically by choosing a better one (Nelder-Mead comes to mind). However, I need to think this over some more, and even if we can't I'm really not that worried.

At this point all that's left is to make the chosen changes to the genome and update the phenome. Once all mutations for this generation are done we calculate population growth rates for each species via standard population dynamics and update all the population levels, along with compound levels in species and those in the environment. The last step is to create any new meshes and animations needed, then go back to gameplay.


I'm not sure if there's much more to say. I've probably made a few mistakes here, it's gone 5am and I've been writing this since before midnight, so I'll try and clear up anything obvious tomorrow. I also mentioned at the start that I was far from ready to present this, so not everything is as well developed as I'd like.

I should also point out that while there are bits of this which would be difficult to program, theres nothing here which I couldn't program (and I'm definately not the best programmer here), and an aweful lot of it is similair to the sort of stuff I do every day, so it's certainly possible. I can provide much more detailed program flow and pseudo code when needed, but that really isn't a priority right now.

Again, a lot of whats been discussed here the past few days is similair to this. Also, of all the criticism the various ideas have recieved, the only truely valid one I can see is that this is really rather complicated. To that I can only say that I can't think of a simpler system which will produce similair or better results for a reasonable amount of computation (and thats not for lack of trying). Also, while the whole system is definately complex, the individual components are actually very simple, and even the ways they interact are fairly simple too.

A few points on computation

I run these sorts of simulations and computations almost daily, and I know we can run probably hundreds of thousands of them per second. Given the few complicating factors (these equations are a fair bit more complicated, they'll be running in c++ which is a lot faster than what I use, we need to run a game at the same time) I'm pretty confident that computation isn't going to be an issue, so long as we don't resort to too many mini-sims.

In addition to this, we won't be running this in anywhere near realtime. Auto-evo only needs to run on each location maybe once every 2 minutes, if that? Locations not observable by the player can be run even less frequently, and be done in the background while they're playing, so that only the observable location needs to be run while the player is in the editor.

The biggest computational workload to auto-evo will still be the generation of any new meshes or animations, and this only really needs to be done for the observable location. Other locations can have these generated as and when needed as the player moves around.

Finally, this wasn't supposed to be a rant, sorry if some of it came accross that way. What it's supposed to be is a summary of most of the relevant concepts we've discussed on various parts of this forum about auto evo and population dynamics. A lot of this was discussed and practically decided in the first 2 pages of this thread, I've just filled in the blanks from what I've been thinking about over the past several months.

tl;dr - I wasn't BSing

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License