The Infected AI engine has been praised for its virulence and aggression, however it is extremely messy and difficult to transport from one level to another.
Therefore I am going to overhaul it - I will use the experience I gained writing the first version to write a new version basically from scratch.
As is becoming usual for me whenever I start a complicated project, I am going to keep all my notes here in public. I have no clue if others will actually benefit from this or not - hopefully you will - but apart from anything else it's a nice place to keep my notes that I can access from anywhere with an internet connection. :>Aims
- The engine must automatically learn about the level, without having to be told lots of different parameters manually by the programmer.
- The engine must be able to deal with levels where the number of asteroids in play changes over time.
- The engine must be equally at home conducting itself in a static level as in a dynamic level, with gravity or roids that are otherwise moving.
- The engine must be easily copy+pasteable from one level to another.
- The engine must deliver a similar level of deadliness to version 1
- The engine must be resilient, able to recover and ultimately take over the galaxy (if left alone) even when knocked all the way back to, say, 1 tree on one asteroid.
- The engine must be capable of controlling multiple AI factions, fighting against each other as well as the player.
- The engine must work fine alongside the Gravity Engine, but must not REQUIRE the gravity engine in order to function.
- The engine must be sufficiently lightweight (unlike version 1) that it can be run on a large number of asteroids without significant performance loss.
- The engine will be run on a random asteroid each tick of the "While Running" loop. The engine then carries out a series of checks for that asteroid.
- The checks determine the asteroid's state: how many trees, how many seeds, how many player seeds, etc.
- The asteroid will also make a list (array) of all a) friendly or empty asteroids, b) a list of enemy neighbouring asteroids or empty asteroids with enemy seedlings on them that are within its send distance.
- The asteroid will set a "metric" for itself based on its own status and the status of the neighbouring asteroids. The metric is a list that is kept for all asteroids currently in play. It is used in order to dynamically create a priority travel list for seeds. An asteroid that can spare seedlings will send them to whichever neighbouring asteroid has the lowest metric.
In version 1 I kept different metrics for guarding the empire, colonising new asteroids, and building up a force ready to attack. In this new version, I plan to combine all of these metrics into one. Therefore, one metric array will be used per empire
Here is my initial proposed scale of metrics:
0 = under attack
100 = asteroid that needs more trees for building
200 = gather point (ready to attack somewhere).
Suppose I'm an asteroid that has been selected for checking. I have the same number of trees as my treecap, and I have 50 seedlings orbiting me, and I'm not under attack in any way.
I will now look around at all my "neighbours" - asteroids within my send distance - to see what they are up to. One of them is a blank asteroid, so his metric is 100. The only other asteroid in my range is fully built too, like me...however his metric is 101. That means he must be within range of another asteroid that is blank.
Because the asteroid in the northeast has the lowest metric (100), I'll send my 50 seedlings to it, and set my own metric to be 100 + 1.
The seeds will build 4 trees, and 10 will be leftover. Now the northeast asteroid is finished building, so it resets its metric to nil, ready to be re-evaluated on the next cycle.
On the next cycle when Fluffy is selected, Fluffy realises that now the lowest metric of any neighbour is 101. So Fluffy sets to 102.
On the next cycle when the north-east asteroid is selected, it looks at Fluffy and sees that the metric there is 102. So it sets itself to 103. It also notices that it has 10 seedlings orbiting, so it sends them to the next lowest metric...which is Fluffy.
...and then fluffy (102) sends them to the next asteroid (101)...
...which sends them to the asteroid with metric 100, which builds a tree with them.
This is the whole basis for how the engine works. You can probably do your own thought experiments for what happens if an asteroid comes under attack (and sets its metric to 0).
Sorting out the behaviour of the gather point is the tricky part for me right now. Especially in dynamic levels, whole sections of an empire might be seperated from one another. I need to figure a way to let them operate independently of one another, so that orphan empires can still launch attacks and potentially bridge the gap with the other half of the empire. I need to do this without introducing problems like every asteroid trying to be the gather point.
This will require some thought.