1
\$\begingroup\$

I'm trying to develop a character calculator for a RPG, and it could evolve into a turn based combat / text based RPG. One of my concerns is how to handle the equipment stats / buff system.

Currently each of my buffs / equipment object and my character object itself has a member bonusstats, which is a struct containing a (potentially) very large amount of possible modifiers (attributes, misc_skills, protections, secondary_stats, etc and their multiplier versions).

struct BonusStats {
    int attribute[8], misc_skill[30], protection[9], HP, MP, ... ;
    //define constructor, operator+=, reset function
}

And everytime an actualize call is requested every stat is recomputed:

Character::Actualize() {
    this->bonusstats.reset();
    for /*iterate through vector of buffs and equipped items*/ {
        this->bonusstats += item->getBonusStats();
    }
}

While this is a rather simple approach I am concerned about two things mainly:

1.- Is it performance-wise acceptable? I get the feeling that having to sum two structs containing 100 elements just to add a buff is not a very good practice. Would there be any practical advantage in using a function like Character::ApplyStats( std::function<void(BonusStats*)> itemstats) instead?

2.- How could I implement more complex buffs than stat modifiers? For example, reflecting x% damage when blocking a melee attack. The thing that comes to my mind is to create complex stats like percent_damage_reflected_on_melee_block and check its value everytime conditions are met. Is it a good approach?

\$\endgroup\$
2
  • \$\begingroup\$ Also: gamedev.stackexchange.com/questions/43489/… \$\endgroup\$
    – user1430
    Commented Nov 25, 2014 at 16:38
  • \$\begingroup\$ As for your performance question: is it performant enough for you? If your profiler doesn't show it as a bottleneck and your overall game performance is acceptable with it, I'd say you're fine. Don't worry about it until the data shows it's a problem. \$\endgroup\$
    – user1430
    Commented Nov 25, 2014 at 16:39

1 Answer 1

0
\$\begingroup\$

I would switch from having a function that adds stats to a function that takes in the entity with the equipment or buffs and make the item responsible for modifying the entity. Something like...

Character::Actualize() {
    this->bonusstats.reset();
    for /*iterate through vector of buffs and equipped items*/ {
        item->applyEffect(this); // Maybe a reference? Dunno, don't use c++ anymore.
    }
}

I have a VERY similar system in one of my games and not only is it performant enough to have hundreds of buffs, most of those buffs are sending network calls in my game and it still works fantastically. Iterating through a loop and doing some basic math is nothing compared to the performance of draw calls.

As for the different types of events, the best way is some kind of event system where the buffs or items can register for the events. There should be a ton of libraries for those, but it's also a simple system to write yourself.

\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged .