Jan Dvorak points out the exponential function in a comment. I'll explain it here.
Note that exponential (and trig) operations are considerably more computationally expensive than even square root operations, which are themselves far worse than basic math, so you're probably better off with Adam's approach if you'll be doing these calculations many times per second. If you just calculate the values when the player levels, changes equipment, etc., speed isn't important, so use whatever gives you the best curve.
An exponential function is some base, B, to some power, x, y=B^x
. Mathematicians commonly use a base of e, (~= 2.718), but there's no reason you can't use 2 or 10 if you prefer.
y=e^x
looks like this:
Notice the left side is moving asympotically to 0. So we can flip the x-axis by doing y=e^(
-x)
, but it's still descending from 1 to 0 and we want it to ascend. So we can flip it across the y-axis with y=
-e^(-x)
. Now it's ascending from -1 to 0. We can add 1 to get y=
1- e^(-x)
and it's ascending from 0 to 1.
From here, it's just a matter of scaling it vertically and horizontally. We can multiply the entire thing by some value, let's call it A, that sets the asymptotic limit. Then we can multiply x by a rate-of-change value, k, to adjust how quickly it closes in on the limit.
This gives us a final equation of y=A*(1 - e^(-k*x))
. Using values of k=0.012
and A=0.5
, we can set the limit to 50% and let it get pretty close to that limit around x=400
.
Now, you can make a few tweaks to this. One tweak I made was changing to A=0.5041
, so if we round to a percentage with 2 decimals (like 32.23%), y(399) = 49.99% and y(400) = 50.00%. From y(347) onward, there are several places where it takes two points to get a change of 0.01%. But that last possible point still gives a (barely) tangible benefit, and brings it to an even 50%.
Alternately, we could tweak the k
value to have a similar effect. At k=0.02305
, the value rounds to 49.99% at y=399
and 50.00% at y=400
. However, this has the problem that the graph is very shallow at the end -- it takes 48 points to get that last hundredth of a percent (from y(352)=49.99%
to y(399)=49.99%
to y(400)=50.00%
) and the last 1% crit chance takes a whopping 230 points (from y(170)=49.01%
to y(400)=50.00%
) which is probably a bit too diminishing on returns.
If you wanted, you could adjust both A and k so it's diminishing to a somewhat higher limit at a slower rate, to give something between linear and exponential decay. Doing y=0.6*(1-e^(-0.00447*x))
, you end up with this:
Note that the curve continues past 50%, but since there's a hard limit of 400 rating, the player can't pass that point (and if they do manage to pass it, there's still a hard limit of 60% crit). With this equation, you can use 1 decimal place and still see gains every 2 to 3 points, with a final tick from y(399)=49.9%
to y(400)=50.0%
.
Mathematically, the earlier equations might seem better, since they're actually approaching 50%, but I personally think gains of 0.1% every couple points feels better than gains of 0.01%. Even with A=0.05041
and k=0.012
, it takes 102 points to go from y(298)=49.00%
to y(400)=50.00%
. 25% of your points spend on 2% of your crit is probably too diminished. The 60% equation only takes 20 points for the last percent (which is still 5 times higher than the 4 points needed for the first percent).
With these last several equations, I just plugged the equations into a spreadsheet and manually tweaked values until they looked good. You'd have to do something similar if you wanted a different cap.