Hello, I am looking for some suggestions and ideas on how to improve a structure of mine. In my project, I have this formula that represents the value property of an entity, including modifiers. If it doesn’t display, this is the raw LaTeX formula: [quote]
value \defd (value_{ base } + scaled_{ base }) * additive_{ base }) * multiplicative_{ base }) + unscaled_{ base }
[/quote]
.
To explain this formula, a final value called, well, value is calculated by:

Creating the sum of a base value and the sum of all flat bonus values that should be scaled.

The resulting sum is multiplied with the sum of all values that represent additive percentage modifiers.

The resulting value of step 2 is then multiplied with the sum of all values that represent multiplicative percentage modifiers

Finally, the value resulting from step 3 is then summed up with the sum of all values that represent unscaled flat bonus values, unscaled as in unaffected by percentage modifiers.
For better understanding, here are some examples for these values:

“This hero talent increases your base health by 100 points”  This is a scaled flat bonus.

“This equipment piece increases your base life by 10%”  This is a additive percentage bonus.

“This buff increases your total health by 25%”  This is a multiplicative percentage bonus.

“This buff increases your total health by 250 points”  This is an unscaled flat bonus.
Now because I wanted to have something that works as quickly as possible, I translated this into literal code, having four collections that keep track of all values of each individual part of the formula, as well as a function that calculates the final value. It could look like this:
public interface FloatProvider
{
float Value { get; }
}
public class MyEntityValue
{
private float baseValue;
public List<FloatProvider> scaledValues;
public List<FloatProvider> additiveValues;
public List<FloatProvider> multiplicativeValues;
public List<FloatProvider> unscaledValues;
public float Value
{
return (((baseValue + scaledValues.Select(x => x.Value).Sum())
* additiveValues.Select(x => x.Value).Sum())
* multiplicativeValues.Select(x => x.Value).Sum())
+ unscaledValues.Select(x => x.Value).Sum();
}
}
Now aside from some obvious improvements such as introducing a new collection type to only recalculate the value of a list of values such as scaledValues
if it is dirty, has changed, how could I improve on this structure?
In particular, I am curious about the collection themselves. At runtime, some lists might not actually be needed most of the time. Perhaps, an entity never has unscaled flat bonus values [from a certain point on], for instance. Is there a way to destroy lists, but regenerate them when needed? Reading about WeakReference, would this improve the performance if you need objects at some times and don’t care about it at other times?
It might not seem very useful in this particular case, however, as you might have noticed, in the formula everything has the addendum “base”, as I am still investigating if I need more layers, basically chaining the formula multiple times. When I do this three times, for instance, I already end up with twelve lists and it seems a lot to me considering that most of them won’t be needed most of the time. Are there better data structures for my case that don’t rely on a lot of individual lists?