Ecosystem simulation - Follow up

Making Of / 30 May 2018

In this post, I'll be going over some of the results of the ecosystem simulation system, some reflection on what I learned as well as ideas for the future!

Easy mode

So, to start off, lets get some results in here:

In this video, you can see what I dubbed the "easy mode" climate.
This climate doesn't favor any of the species in particular but rather focuses on letting every plant grow and giving competition the lead in keeping certain species alive.
That being said, almost immediately, the summer tree disappears from the simulation and the oak tree takes the lead.
This happens due to the summer tree being mostly "optimized" for really warm climates.

But, it's hard to tell what happens here when there's no reference, so let's get some more simulations!


The second climate we'll be going over is the maritime climate.

There were two reasons for adding this climate in there, the first one was that I live in it (technically it's a cold maritime climate but oh well).
The second reason is derived from this, because I am more familiar with the climate, I am able to better judge how well the simulation performs.

What do I mean with this? Well, in one of the earlier versions of this system, the summer tree would consistently win, even though the temperature should be too cold for it to flourish. During other occasions I noticed the strong decline of the oak trees, which would be weird as they usually do completely fine in this environment.

Using this climate as a benchmark I was able to effectively bug-fix and tweak the system.
To make this even easier I made a system that could create plants as a spreadsheet format.
Not only, did this allow me to quickly add new plants, but it also gave me the option to leave some out if I want to.
This is the interface I used for this process:




For the third climate I decided on finding something more warm and went with the desert climate.
Just like the maritime climate this was a test to see if the system properly worked. And yes, it did its work proper!

Main thing to note here is how nearly every tree dies out, except for the summer tree! (and the bush).
This again proved that the system behaves as intended, really destroying any "weak" plants as time progresses.


With only one tree type left, the pine tree, I went with a cold climate for the final test. As the title suggests: taiga.

Again, I was amazed by how the system does its work, only keeping the plants fit for the environment.
Besides this, I don't have much to say about it. Only that it performs just as I had hoped!

What I learned

I think the main lesson I took away from this whole experience is that you always need an anchor point in reality.
In earlier versions I was never able to properly asses whether the system worked properly.
When I started using a relatable climate though, everything became more readable and the whole tweaking/fixing loop became much easier.

This is definitely something I want to use in my future projects.

Ideas for the future

During the process of rendering and tweaking the variables I got a lot of new ideas that I want to add when I have time.
Some of these ideas are:

  • Evolution
    As of now, the system uses just the input-values to simulate the plants.
    What if, during offspring, these (at the moment) static values can be changed.
    This will mimic evolution by giving random variations that over multiple cycles turn into a different species by survival of the fittest.
    To make this happen though, I would also need various systems to procedurally show these changes in the geometry.
  • Automatic plant generation
    Currently I add all plants by hand, using real life data to recreate them in the system.
    Making a system that does this automatically, I would be able to have a larger variety in the amount of species.
    This could work together with the evolution part, making the system into a true ecosystem simulation!
  • Faster system
    Where the current version is a lot faster than previous ones,
    I would still like to have a faster system that can handle more generations in shorter time.
    Open Cl could be the answer here, but it would need a lot of adjustments to the code to work
  • More terrain variables
    With the current system I only care about the soil fertility when spawning/weakening plants.
    For future iterations it could be interesting to bring in more variables like slope, gained sunlight in a certain spot.
    With this also comes more interaction between the plants: Occluding sunlight, stealing fertile soil, etc..
  • Animals
    At the moment the system does a pretty good job in using environmental factors and a bit of competition.
    But, what if I added animals into the mix?
    It could be really cool to use animals for controlling certain plants, in turn changing the ecosystem.
    This would probably need another system for managing these animals though, relations between predators and their prey.
    Oh well, so much to do!


So, in the end I definitely learned a lot whilst developing this system and I am very much looking forward to working on it more when I have time.
For now though, I will conclude this system as done.

Thank you for reading!

Ecosystem simulation

Making Of / 28 April 2018

The issues of placing plants

Filling an environment with foliage is always a pain and from what I have found, the methods haven't changed much.
With the rising popularity of proceduralism, new techniques are being applied. But they more often then not still rely on basic principles (like scattering points around). Sometimes additional layers are applied, like rules to incorporate environmental factors and other influences. These still only manage to replicate real life when an artist glances over the output and adjust it manually.

Disney to the rescue

Since I had been doing it like this myself, I always accepted these methods as the best ones since they still provided reliability and most of all stability. But, that was before I came across the Disney research paper on simulated ecosystems. (get the paper HERE)
In this paper they propose a method of simulating an environment using adjustable factors and real life data (lots of it).
This seemed like an amazing thing to implement, so. Off I went to create this system using houdini.

A side note

Before I continue, a quick note: The upcoming paragraphs go mostly into my thought process whilst creating the system and the problems I ran into. If you're mostly interested in the results the system produces, feel free to skip to the "The system in action" title.

The process

The first iteration seemed pretty promising, instead of making a cycle based on a single frame I thought it would be interesting to add a frame-range. With this, I would not only be able to simulate a year, but also the months in that year.
Since the system used a lot of real life variables (like temperature, sunlight per day and humidity) I was able to find real life data on those,
pick multiple maximum and minimum values and interpolate between those to simulate a year cycle.

How the variable picking works (in this case the temperature).

This thought ended pretty quickly with the realization that if one year were to be 12 frames then simulating longer time periods would be insanely
expensive. For visualization purposes it would be amazing to see seasons go by as the environment grows but, my goal was a quick solution
So, multiple frames per cycle would probably be a no go.

With that in mind, I compressed the system. Instead of one frame per month I now used one frame per year.
Instead of interpolating between the a-biotic factors (values that are there regardless of the ecosystem like temperature, sunlight and humidity)
I picked one of the maximum values and one of the minimum values (I had two of both to emulate better or worse years, more on that later) and
took the average of those. With this, I successfully compressed the simulation to a single frame per year.
This new approach brought along some new issues though: overpopulation.

For some reason, plants would keep spawning regardless of any factors.
Turns out, I hadn't put a limitation on when the plants could start creating offspring.
In real life this would be pretty fuzzy as it differs a lot per plant, but to solve this I gave every plant an age threshold based on it's other factors,
as to balance the plant a bit.

The results of this were immediately visible as the population still grew, but not as drastically!
I ran into a new problem though: mass extinction and little response to parameter changes (besides the mass extinction).
Up until this point, I had been testing the system on an artificial climate that was for all intents and purposes easy mode:
A heaven with gentle temperatures and plenty of sunlight.
When I changed this to another climate (maritime for instance) the whole population would die off without reproducing.
That's an issue.

Third version

At this point the main script became too cluttered as I had only been patching it during the shift from version one to two.
Because of this, it became very hard to see where the issue was.
To save myself time and improve the system I decided to rewrite it.
This time around, I used functions instead of writing the code down every time, restructured how I stored all the attributes,
added a bunch of parameters for controlling the system and even made an easy interface for creating plants to be used in the system.

Alright, an updated system, an easy to read attribute layout and a bunch of parameters to tweak. This should fix the issue in no time flat!

That is what I hoped for anyway.
For some reason, the simulation still murdered all those poor poor (digital) plants.
But, after running through the code a couple of times I finally found the solution: my relative distribution function!

The first and second version of the distribution function.

Above you can see the first and second version of the distribution function.
A little bit of information about them. Every plant has three values for it's a-biotic factors: Its minimum-, maximum and preferred value.
The minimum and maximum value are used for normalizing the current temperature, sunlight or humidity value. But, the preferred value, is what
drives the peak seen in the first graph and the flat-line in the second.
After looking around a bit, the abundant sunlight and the graph above are what caused the plants to die.
Because the sunlight would be above the preferred value fairly often, the function would remap it to be zero anyway.
Even though, more sun would improve their situation. By making the function go constant after the preferred value the plants wouldn't
receive a zero value, and would continue to live!
Once I patched this out, I finally had a system that would simulate using environmental and biological factors!
Off to simulation tests!

The system in action

Without further ado, lets just see the system in action!

On screen here is a simulation that took place over 36 cycles in a maritime climate.
The amount of species in this scene is four:

A closeup of all plants used in the simulation
  1. Oak tree (light blue, all round plant with low reproduction capabilities)
  2. Summer tree (dark green, tree designed for warm environments with high reproduction rates)
  3. Pine tree (pink, Thrives best in cold environments and has high resilience to hostile environments)
  4. Ribes bush (dark blue, quickly reproducing bush with low space needs and relatively high resilience)

Something of note here, is that the third tree isn't a real life one. It is one I made and specifically designed for warm environments.

What really stands out here is how a large part of the initial generation die off, due to bad placement.
This was very satisfying to watch after a lot of strange bugs break the system.
It also shows how the "weak" plants don't survive. Weak meaning, plants that aren't fit for the environment.
You can see this especially well in the data graph made of this sim:

Percentage of total instances per plant

Here you can see how all plants start of in fairly equal numbers and almost immediately, survival of the fittest kicks in.
Due to its fast reproduction rate, the ribes bush is able to take up all space and win the race by sheer quantity.
The pine doesn't grow much relatively, but holds its own due to its high resilience.

On the other hand, the oak and summer tree don't do so well.
Due to it's low reproduction rate and large space needed the oak simply can't keep up with the exponentially growing competition of the bushes.
And because the temperature isn't warm enough, the summer tree also slowly dies off.

In video, the colours represent a couple of things:
The colour represents the species (mostly for telling things apart) and the brightness stands for the plants fitness.

This fitness value is key to the simulation.
It determines if the plant reproduces (and how much), whether the plant looses life force and whether the plant grows (amount of growth included).
The value is computed by combining all biotic and a-biotic factors. This is done through some fairly simple code like seen below.

fitness = competition * soil_adapt * temp_adapt * sun_adapt

I am able to get away with a simple function like this because most of the heavy lifting is done in those variables used in it.
Speaking of those, this is what they stand for:

  • Competition: How proximity of other plants influences the current one.
  • Soil_adapt: The interaction of the plant with the combined value of soil fertility, water availability and height. 
  • Temp_adapt: How the temperature influences the plant.
  • Sun_adapt: How well the plant handles the current sun values.

Some ideas I have for future versions of the system is making different versions of the fitness function, making the values above interact in different ways.

Now, if you paid close attention to the video, you might notice how the plants in the center don't really spread. Like they are being blocked.
This is the result of the soil value set on the terrain.
Here's the same video again, only this time, it's using the soil value as it's main colour.

In this video, grey is low fertility and brown high.
I added this to see how well the plants would respond to it and it turned out surprisingly well.
This is also one of the main features of this system.
Because you can control the outcome so well by simply adding or removing fertile soil, the whole thing becomes much more friendly.
Which was the initial goal!


After three main iterations, lots of smaller fixes and a lot of crashing due to running out of ram for simulating I got what I looked for:
An easy to use system for realistically placing foliage.
At this point, there's only one question that needs to be answered: Is this system usable.
The answer to this is yes and no.
For a lot of situations this system might be overkill: The simulation time is fairly optimized, but still takes longer than just placing scattered foliage.
On the other hand, this system can apply a large quantity of realistically placed foliage on a large quantity of terrain so in my eyes, large open world games would definitely benefit from it.

Whilst I'm writing this, I'm also rendering out more simulations with different climates and setups so if you're looking for more, stay tuned!