TLDR;
Looking at the changelog of 3.2 and previous performance improvements it seems that most of the computational effort at each timestep is used to calculate "Pop"- related game rules/mechanics/optimizations. Big improvements to performance have been achieved by empire-wide logarithmic growth which basically caps the total population in the game and therefore reduces the computational burden for the late game.
This post tries to raise awareness that the representation of the current population seems to be computationally inefficient and how it proposes an improvement without affecting the current user experience. The main proposed idea is to avoid simulating single entities and assume instead that there is a large number of these entities represented by a floating point number.
Problem
Please keep in mind that I do not have any insight into the code of stellaris itself, however, it seems to be the case that there are computations regarding the population. For instance migration off a planet: Each single "pop" needs to be checked if it should migrate to another planet. Let N be the number of the total population on the considered planet and let M be the total number of planets in the empire. The calculations for migrations have to be performed with the complexity of O((M-1)N). In simple terms, each pop has to be checked if it should move to another planet and which one. This is especially computational heavy in the late game where you have a lot of pops and a lot of planets which makes the product of (M-1)N large. Similiar problems arise for fractions and jobs.
Suggestion
Instead of calculating operations/events for single "pops" consider the operation/event to be calculated for the whole population and applied to the whole population. This would of course require the game to not have any integer amount of pops that range between 1 and ~10 000 but instead to have a floating point number which could for instance represent a billion or more entities.
Let me illustrate that by the migration example:
Let K be the number of the same species with the same traits. For the whole population, the migration chance to each planet has to be calculated. The number of people migrating to planet X is then: Mirgration_Chance_to_X*Population_on_Planet.
The complexity of this example depends on the number of planets and the number of unique species. This results in a complexity of O(K(M-1)).
In the endgame, the number of K is way smaller than the number of pops N. And therefore fewer computations have to be performed.
Fractions can also be treated like the migration problem. Thus the complexity here can also be reduced.
For the user experience, the pop mechanic is especially interesting when it comes to jobs.
In the early, to mid-game, the user develops the planets and constructs buildings which is an interesting mechanic.
Often the user waits until a pop is finished and then constructs the building the pop should work in.
Treating pops as a floating point number the population on a planet should continuously grow. How fast is an open question (exponetial/logarithmic/linear etc).
As for the jobs, the assignment is done in the same way as it is right now. Everything is simply expressed as a percentage of the whole population instead of assigning an integer number of "pops". Disabling buildings could be for instance realized with a simple slider instead of clicking 25 times on a minus to disable your farms.
And so on...
I think that this could improve performance and also increase user experience. It would also allow to have a higher population count in terms of usage of Planets. Basically, this allows to max out each planet since the performance of the game does not depend on the number of "pops" anymore. The current logaritmic pop growth for instance does not allow to populate the ringworlds of a fallen empire in the endgame since it would otherwise break the game.
I hope my point got clear. Please let me know if something is unclear.
Looking at the changelog of 3.2 and previous performance improvements it seems that most of the computational effort at each timestep is used to calculate "Pop"- related game rules/mechanics/optimizations. Big improvements to performance have been achieved by empire-wide logarithmic growth which basically caps the total population in the game and therefore reduces the computational burden for the late game.
This post tries to raise awareness that the representation of the current population seems to be computationally inefficient and how it proposes an improvement without affecting the current user experience. The main proposed idea is to avoid simulating single entities and assume instead that there is a large number of these entities represented by a floating point number.
Problem
Please keep in mind that I do not have any insight into the code of stellaris itself, however, it seems to be the case that there are computations regarding the population. For instance migration off a planet: Each single "pop" needs to be checked if it should migrate to another planet. Let N be the number of the total population on the considered planet and let M be the total number of planets in the empire. The calculations for migrations have to be performed with the complexity of O((M-1)N). In simple terms, each pop has to be checked if it should move to another planet and which one. This is especially computational heavy in the late game where you have a lot of pops and a lot of planets which makes the product of (M-1)N large. Similiar problems arise for fractions and jobs.
Suggestion
Instead of calculating operations/events for single "pops" consider the operation/event to be calculated for the whole population and applied to the whole population. This would of course require the game to not have any integer amount of pops that range between 1 and ~10 000 but instead to have a floating point number which could for instance represent a billion or more entities.
Let me illustrate that by the migration example:
Let K be the number of the same species with the same traits. For the whole population, the migration chance to each planet has to be calculated. The number of people migrating to planet X is then: Mirgration_Chance_to_X*Population_on_Planet.
The complexity of this example depends on the number of planets and the number of unique species. This results in a complexity of O(K(M-1)).
In the endgame, the number of K is way smaller than the number of pops N. And therefore fewer computations have to be performed.
Fractions can also be treated like the migration problem. Thus the complexity here can also be reduced.
For the user experience, the pop mechanic is especially interesting when it comes to jobs.
In the early, to mid-game, the user develops the planets and constructs buildings which is an interesting mechanic.
Often the user waits until a pop is finished and then constructs the building the pop should work in.
Treating pops as a floating point number the population on a planet should continuously grow. How fast is an open question (exponetial/logarithmic/linear etc).
As for the jobs, the assignment is done in the same way as it is right now. Everything is simply expressed as a percentage of the whole population instead of assigning an integer number of "pops". Disabling buildings could be for instance realized with a simple slider instead of clicking 25 times on a minus to disable your farms.
And so on...
I think that this could improve performance and also increase user experience. It would also allow to have a higher population count in terms of usage of Planets. Basically, this allows to max out each planet since the performance of the game does not depend on the number of "pops" anymore. The current logaritmic pop growth for instance does not allow to populate the ringworlds of a fallen empire in the endgame since it would otherwise break the game.
I hope my point got clear. Please let me know if something is unclear.
- 2
- 1
- 1