Drop rates are used in two ways in games: common rates, where the player is expected to get numerous drops as they play, and rare rates, where a special item has a small chance of dropping, forcing the player to grind to get the item.
Common rates work well, and they aren't really that interesting mathematically. If everything I kill in a Zelda game as a 25% chance of dropping a rupee and I kill thousands of things over the course of a game, rupees will drop fairly steadily.
Uncommon rates are tricky. If I spawn an endless wave of monsters that have a 10% chance to drop a key needed to get to the next room, how many monsters does the player need to kill to get the key? The answer is not 10. It's actually pretty complicated. What we get is a table of a percentage of players that get a key by the time they kill X number of monsters:
#Kills %Players
1 10%
2 19%
3 27%
4 34%
5 41%
6 47%
7 52%
8 57%
9 61%
10 65%
20 88%
30 96%
40 99%
So we can see that over one third of all players have to kill more than 10 monsters to get the key. Of course, there are also some that get the key on the first or second monster.
What is the math behind this? First, total the probability of the player not getting the key N times. Since there is a 90% chance of not getting a key each drop, it is 90% * 90% * 90% ... n times, or 0.9^n. But since I want the probability of the player getting a key (or multiple keys), I subtract this value from 1.
P = 1 - (1 - dropRate)^n
Let's take a look at another result. Let's say you want to have your super secret special item drop with a 1/1000 chance, or 0.1%.
#Kills %Players
1 0.1%
10 1%
100 10%
1000 63%
2000 86%
3000 95%
There's still 14% of your players that don't get your drop even after killing 2000 monsters. Clearly this will be frustrating for them.
So what are some alternatives? There is no easy answer, but this is one solution that I like:
Increase your drop rate every time the drop fails, and reset it once the item drops. Take a look at the 10% drop rate example, now with an additive 10% increase every time the drop fails (10%, then 20%, then 30%, etc.):
#Kills %Players
1 10%
2 28%
3 50%
4 70%
5 85%
6 94%
7 98%
8 99.6%
9 99.96%
10 100%
The drop rate is quite aggressive now, but we know that if the player does not get the drop for 9 kills in a row, then 10th kill is guaranteed to drop with a 100% chance.
The math here is slightly more interesting.
P = 1 - product(1 - dropRate * i, from i = 1 to i = n)
For the 10% case, we can write it as:
P = 1 - (9!/(9 - n)!) * 0.1^n
But overall, this is not really what we want. Half of the players are getting the drop in 3 kills. Let's try another solution that does away with the 10% rate altogether.
Let's set the drop rate to start at 2^(-9), and double it each time it fails to drop (2^-9, 2^-8, 2^-7, etc.), while still resetting on a successful drop.
#Kills %Players
1 0.2%
2 0.6%
3 1.4%
4 2.9%
5 5.9%
6 12%
7 23%
8 42%
9 71%
10 100%
Finally, we have something that looks like we want. Most of our players will not get the drop until the higher number of kills, but there is a hard cap at 10 kills that guarantees every player will get the drop.
What does the math look like?
P = 1 - product(1 - 2^(a - MaxN), from a = 1 to a = N)
in this case, we have maxN = 10, so
P = 1 - product(1 - 2^(a - 10), from a = 1 to a = N)
This can be expensive computationally, but there are some shortcuts. There might even be a way to simplify the product expression to an exponential term, but I'll have to look at that later.
Hopefully I have imparted a small amount of distrust for low random drop rates to you. If you have any ideas on other ways to make a good drop rate system, I'd love to hear them. Otherwise, if you are stuck grinding for something in a game and it feels like it's taking way too long, now you know why >_>