A reasonably core element of my game is the addition of status effects that confer both time-limited buffs or debuffs, like what you would see in any MMO (Slow reduces Speed by 10% for 30 seconds), and semi-permanent buffs/debuffs that persist until some state is triggered (taking medicine to heal sickness, missing an attack and breaking the combo chain). I have an idea of one way to accomplish this and part of a second, but I’ve been teaching myself to program as I develop and this feels like a very brutish, unclean way to accomplish things, so I would love to hear any feedback on my method, or suggestions if there’s a much cleaner way to accomplish this.
The functionality I’m trying to encompass in this system is, simply, “Change any character statistic, by any set amount or percentage, for any duration”. This obviously implies that the pre-buff stats need to be retained in a sacrosanct area that buffing never sees or touches, and so in the character data class I’m putting three variables for each statistic: BaseStat, StatModifier, EffectiveStat. BaseStat is the sacred, untouchable variable that contains the stat’s unadulterated value, it only gets modified when the player levels up or otherwise permanently adjusts that stat. StatModifier starts at 0, and represents the total number of adjustments made to that stat: a minor debuff would set StatModifier -=1, for instance. Finally, EffectiveStat is the variable most of the game will look at to determine that stat’s effective value, and every time StatModifier or BaseStat changes, I run EffectiveStat= BaseStat + StatModifier.
This effectively makes every buff or debuff a matter of changing StatModifier, which is simple, but I don’t like it: it’s very easy to get a wrong number (for instance, if StatModifier = 3, and instead of subtracting 3 from it I call StatModifier -= -3, I get 6 instead of 0), and I’m uncomfortable lumping every buff into a single float.
An alternative to this, which I haven’t entirely thought through, would be to instantiate a StatModifier class for each new debuff: it could be fairly pared down, and only contain the debuff’s name (for menu purposes), a reference to the statistic it modifies (I’m not quite sure how to do this without pointers- could I use delegates to retain a reference to a specific statistic from the character data class?), the amount it modifies that statistic by, and its duration, with either -1 being indefinite, or using some bool NoDuration to specify semi-permanent buffs.
That seems much cleaner than using a single modifier variable, but where I trip up is thinking about the best way to actually apply StatModifiers to the character- I could give the character data sheet a List, then every time that list was modified, call an UpdateBuffs() function in character data that zeroes out all of the EffectiveStat values, then iterates through my list of modifiers and applies them, but that’s going to be a lot of effort wasted, as I would end up setting every stat every time something changed, instead of only targeting a single value.
So is this looking like a generally reasonable way to go about things? Am I missing something huge and obvious?