First, a definition of an ability in this context: any usable THING that a player or NPC can use during or outside of combat, often known as attacks, skills or spells.
Abilities can take on many different forms - attack, healing, buff, debuff, DOT, HOT, transportation, enchantment, mechanic-bending, and just about anything else you can think of.
The question is: how do you adaquately represent abilities within the code, without duplicating code, remaining as efficient as possible, and still not a complete pain to program against?
Early on when I was new to development, I used a giant set of variables - damage, debuff1, debuff2, etc. (actually called maladict1/2 at the time) Over time I learned that not only was this not efficient to program with, but it was also extremely poor design from an object-oriented perspective.
Lately I've been using a single list in my code to manage the different properties of an ability. Generic things (like casting cost, time delay, or cooldown) still receive their own variables - because those are broad, they matter for 98% of all abilities. Specific mechanics however, such as damaging an opponent, healing yourself, healing your party, slowing time, creating natural disasters, or teleporting your enemy 50 yards away - all receive an entry in the list.
A self-damaging powerful attack might be:
effects[] = list(DAMAGE_ENEMY = 120, DAMAGE_SELF = 10, DAMAGE_TYPE = PHYSICAL)
Which would cause 120% physical damage to the enemy and 10% to yourself.
A debuff with a DOT component might be:
effects[] = list(APPLY_SLOW = user.GetInflictedCondition(SLOW), DAMAGE_OVER_TIME=20, DAMAGE_TYPE = MAGICAL)
(you'll notice the method call above, these lists are created within New() for substantially more flexibility, and since only one copy of each ability is instantiated it's not a load)
However even this system has it's limitations. Handling damage abilities that use multiple elements, for example, is hackish at best (looping through the list and executing each element in order, for example) and handling complex abilities that may require multiple usages of similar types is also poor.
What are your strategies for handling abilities in your own games - and why? I find that, no matter how often I revisit this topic, I don't tend to make much ground in solving the solution with the "best" method that feels the least like hacking, and still maintains the above criteria: fast to execute and fast to program.
~Polatrite~
I once posted an example of an "effects system", look at that for an example: [link]
In a complex game, you would have each effect handled by an /effect object, and one of the gameplay methods to apply effects would be spells, which would be implemented by /spell objects, and since those are abilities, they could be invoked from /ability objects (and non-mage characters would have other /ability objects, such as physical attacks or whatnot). So you might have an /ability object that governs a /spell (or a different) object(s), which in turn contains a list of /effect objects relating to it.
Note I keep saying 'objects' because it really doesn't matter if you pick to make them basic datums, or say, atoms. It works all the same. Basic datums are simply used for objects that don't need the extra baggage of atoms, but if, say, your /spell and /effect objects can be represented visually by a graphical display, then it could make sense to make them objs with an icon and all, rather than datums (that may need to keep track of a dummy obj in order to display themselves).
So your code tree could look like this:
Note the above was done rather crudely and late at night, and is intended more as an illustration of how the general structure and as such could look. You could implement stuff differently from how it's implemented in the example if you're so inclined.