Creating formulas like this requires knowledge of elementary mathematical functions – the things you learned about in Algebra and Pre-calculus class.
Once you have those mastered, just ask yourself (replace “value” with “damage,” or “health,” or “speed” or whatever):
- Do you want the value to grow at a constant rate? Use a linear function.
- Do you want the value to grow slow at first, but fast later? Use a polynomial or exponential function.
- Do you want the value to grow fast at first, and slow down later? Use an nth-root or logarithmic function.
- Do you want the value to grow slowly at the start/end but fast in the middle? Or do you want it to grow quickly but still have an upper-bound? Use a sigmoid curve, such as atan or the logistic function.
- Do you want the value to oscillate? Use a sin or some other wave.
Then just tweak it (add/multiply stuff, change the base-value, etc) until it feels right. A graphing calculator will help you visualize how changes to the parameters will affect the function.
By the way, the problems you are experiencing are due to integer overflows.
Use variable-types that are large enough to hold the numbers you’re working with. Sizes differ by platform in C++, but using the 32-bit Visual Studio compiler,
unsigned int is 32-bit, while
unsigned __int64 (MS-specific) is 64-bit. Also consider using a
Additionally, try to reorganize your operations so that you don’t encounter such large numbers in the first place (for example, rather than
MDef * MDef / 110, do
(int)((float)MDef / 110 * MDef)).
My Characters stats are composed of the following:
There’s your real problem: you defined your stats before defining what those stats actually mean. You’re putting the cart before the horse.
Look at how D&D (tabletop) works. “Strength” doesn’t mean anything by itself; it only means something because there’s a rule that says, “Add your strength bonus to your melee attack.” That rule is part of D&D’s combat rules. Without the combat rules, “Strength” is generally a meaningless quantity.
The first question you need to ask yourself is this: how much differentiation do I want between characters? Again, look at D&D. There, they have 6 basic stats. These stats define different dimensions of play for characters. A character with a high Dexterity will have different options from a character with low Dexterity.
But the reason for even that difference all comes back to rules. A high Dexterity means bonuses to ranged attacks; you can hit more often with ranged attacks. So just between Strength and Dexterity, you have two dimensions of play: ranged vs. melee.
Intelligence and Wisdom also form something of a pairing, but these interact more with specific classes. Int makes Wizards and other arcane spellcasters better (or possible under some rulesets), Wisdom is vital for Clerics and other divine spellcasters. Because divine and arcane spells have different spell lists, these two stats are involved in different dimensions of play.
You need to define the basic rules around stats before you can define growth progression functions and the like. You don’t need specifics; you don’t need to say that “each point of strength is added into the random roll to determine if a melee attack hits.” What you need are meta-rules like “dexterity makes ranged attackers better.” You can figure out exactly how it makes them better later on.
There are different ways to progress characters. A common old-school Final Fantasy trick was to simply use the character’s level as part of their damage computations. This could be simply multiplying the level by the appropriate stat, or it could mean applying a function to the character’s level. Say, a quadratic progression, so that the rate of a character’s damage would increase per level.
However you want your combat functions to work, they need to take into account progression. Your functions need hooks for progression.
D&D has a funny way of progression. It is part class-based; every time you go up in level, you get new class features and a flat bonus to your to-hit, based on your character class. However, some class features got better by themselves. Spells in D&D would have progression built into them. A spell might do 1d4 damage per 2 levels of a spellcaster above the first. So every other wizard level makes that spell better.
D&D also used item-based progression heavily. Until 4th edition, item-based progression was mainly for fighting characters, but even in older editions, spellcasters had items that gave them stat buffs or other adjustments (or flat out gave them spells).
So items are another thing your combat functions need to take into account. Do items just buff one or more stats while equipped, or do they do other things as well? D&D was a bit odd, in that stats rarely changed; weapons simply did XdY damage, possibly with a bonus based on one of your stats. And that was that. So your only way to do more damage in battle was to find a better weapon. In many videogame RPGs, they take level into account in addition to a weapon.
Your formulas seem pretty complicated. I’m not sure how professional RPG developers handle this, but I’d recommend on focusing on simplicity. Try to find the simplest possible formula you can that still incorporates the range of stats you want to use. For instance, could you have stats modify each other prior to damage calculation, rather than modifying the damage during the calculation? Once you’ve got a formula in mind, I’d try graphing it for a wide range of possible values to see how it will behave as players level up. Obviously the fewer variables you have, them more feasible this will be.
Additionally, BlueRaja provided an important explanation of why you might be seeing unexpected values at higher stat levels. Using unsigned types and checking for overflows will be important.