I want to implement a flexible calculation system that can calculate the damage of an ability based on it’s level.
I’m not sure how to go about doing that. The best I’ve thought of so far is to create a “Calculation” class where you can select the type of calculation you want: substraction, addition, multiplication, exponentional, etc. but that doesn’t seem very flexible.
I want to be able to do complex operations like this:
Ability damage = (((ability level * 10) - 40) + (ability level / 2)) *10
Does anyone have any experience or ideas on designing such a system?
Yeah, if there’s only one input variable, then an animation curve is clearly the way to go for that.
If you do want to create a “formula editor”, you could do that by doing what you’d originally suggested, but allow nesting - each component of the formula has left and right references (which may be a constant, an input variable, or another formula), and an “operator” enum.
AnimationCurve seems interesting. I’ll have to look more into it. What if there’s 2 or more input? I actually wanted it to be based on level + character stats.
Depends on how you want to allow them to combine. You can use multiple AnimationCurves (and add or multiply them together), or you can use a formula system as I described.
The information about the ability should probably be available internally in the ability - you shouldn’t need to calculate this stuff from the outside.
So instead of storing the damage anywhere, when you use the ability, you have a GetDamage() method that gives the ability the character that uses it, and returns the damage:
public abstract class Ability {
public int level;
public abstract int GetDamage(Character user);
}
public class Fireball : Ability {
public override int GetDamage(Character user) {
return (((level * 10) - 40) + (user.level / 2)) *10
}
}
It’s possible to go too far to the “non-hard-coding” extreme, and this case is sort of right on the borderline. At a certain point avoiding hard-coding gets to be more trouble than it’s worth.
Don’t know anything about that plugin and 5.0. I just found it on the AS.
I agree with @Baste . The formula should be encapsulated by the class doing the damage. However, this is only part of an interesting combat system. You should look into how the D&D damage system works. Some of the big MMO’s still use a “D20” engine under the hood to keep things interesting.
If you want simplistic formulas, you could just put them in a string field and write a parser that turns that into an equation. Writing a program that can parse something like:
I still don’t get it. then your formula is hardcoded into a string.
If you really want to make your formulas dynamically, then use an Expression Tree. But I can’t imagine why you would need to make such a complicated system.
Well when I say hard-coded I mean non-customizable. With @Baste 's latest idea, I could have a string field and then customize the damage formula for every individual ability.
If it’s you, then you already have a perfectly good parser. It’s called the Mono compiler.
Creating a string parser is overkill. The only reason you would need such a thing would be to interpret from another system which can’t provide better than a string - like a user entering custom damage formulas (which sounds like a terrible idea to me). And, any parser capable of arbitrary complexity formulas (and I don’t mean complicated, just arbitrary number of brackets and variables) would need to build an expression tree anyways.
Ok well let’s say I have a base Ability with a GetDamage function and other Abilities override and implement their own formula.
Let’s say I have this code here:
public class Fireball : Ability {
public override int GetDamage(Character user) {
return (((level * 10) - 40) + (user.level / 2)) *10
}
}
Then that means every time I want to create a new ability, I have to create a new class even if that ability works in almost exactly the same way. In the case of Fireball, what if I have an Icebolt skill that functions the same way as Fireball? But It should do (user.lvl / 1.2) instead then I have to make a new ability just for that? OK in that example you might say "just make that a variable* so you can reuse the class but what if I wanted Fireball to do base + (ability level ^ i) * y and I wanted Icebolt to do base + ability level * i? Seems like a waste to create a new ability just for that if they’re going to function similarly.
Those are just my thoughts. Not sure if I’m wrong or not making sense. What do you guys think?
Yes so I only have 1 Projectile class I re-use for all projectile-based abilities.
Well other people thought there was no need for such a system so I wanted to clarify why I was looking to implement such a system and see if my logic made sense or if I was still wrong.
Isn’t the whole point of the forum to discuss stuff
I’m at work and can’t program anything anyway.