I have a game with an RPG system where derived stats, like HP,armor, etc depend on a variety of components: armor, stats and feats. I'm running into an issue where the code to change derived metrics gets spread throughout the game - some is in the inventory module, another in stats module, another in buffs module.

How can I centralize and ensure accuracy of all my stat/equipment related changes to the character?

I thought that I can just create a "mega method" within the character class that would recalculate everything any time I change anything within the formula, but I don't know if this recalculate everything is a good practice, or if there are potential pitfalls with this approach down the road.

One of the complications with the complete rebuild that I see is that I will have to keep track of the player's HP and properly restore it after rebuild is complete.

  • \$\begingroup\$ try delegation, ie the module that gives access to a derived stat registers itself to be notified for any chances relating to specific stats - when any of them change the module updates the derived stat. \$\endgroup\$ – LearnCocos2D Dec 24 '13 at 23:40

This also largely depends on how your character class is setup.

Assuming we're using direct references here, I would actually refrain from storing your stats directly. Instead I might have the following:

int Player::GetStrength() { return _stats.strength + equipment.GetStrength() + buffs.GetStrength(); }
int Equipment::GetStrength() { return _head.strength + body.strength + gauntlets.strength + leggings.strength + feet.strength }
int Buffs::GetStrength() { int strength = 0; foreach(Buff buff in Buffs) { strength += buff.strength; } return strength; }

Then any time you need to reference this, whether for UI purposes, combat calculations, etc... you have a realtime value with minimal performance cost.

  • \$\begingroup\$ Great answer, I have an issue where these calls may form long chains - current hp depends on current constitution, which depends on items and speed. Then each monster may call these multiple times. ** Is there a good way to cache these values until an update is needed?** \$\endgroup\$ – Alex Stone Dec 25 '13 at 2:42
  • \$\begingroup\$ Another approach that may work better for you may be to separate these into a Get and Set function for each stat. for example you could have int GetConstitution() { return _stats.constitution; } and void SetConstitution(int value) { _stats.constitution = value; DoUpdateDependents(); } \$\endgroup\$ – Thebluefish Dec 25 '13 at 3:36
  • \$\begingroup\$ @AlexStone: There's many ways to cache them. One simple one is to recalculate a current value only when buffs, equipment, or character level changes. Something like a RecalculateStats method that does all the work and is called when needed. \$\endgroup\$ – Sean Middleditch Dec 25 '13 at 7:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.