Every entity has some stats which change over time and some which are static for a given type of entity. For example current hp vs max hp: lets say humans have max 100hp, then every human would have an int hp
member, but it doesn't make sense to have a const int max_hp=100
for all the humans since it's always the same thing.
That can be solved by using static
member variables, but here's the catch: I want to load all the stats such as max_hp
from a config file when the app starts, which precludes use of static
.
The only way I know how to reconcile these two things is to use a singleton object, which provides entities their stats via something like singleton::instance().model("human").stat("max_hp")
. However, every mention of singletons I have ever seen has been in the context of warning against their use. And I wouldn't want to use it anyway, because then my entity update methods lose referential transparency.
So in short:
- I want to avoid duplicating data.
- I want to load that data from file.
- I want to avoid global state.
- Update methods must be pure functions.
What strategy can I use to meet these requirements?
I require update methods to be pure because my engine is built around the concept of updating every entity in parallel, and the way to do that is to have entity.update
be a pure function which takes an immutable reference to the world and returns a new entity [0]. So every entity starts its update by making a copy of itself, which is then mutated as it goes through the update process, until finally being returned to the world to become the manifestation of that entity in the new generation. Now that would be a lot of copying if only the dynamic data were copied! But to also copy all the (duplicate) static data every frame is just crazy, and I'm looking for the approach which would let me copy only the dynamic stats while still having access to the model data.