Drop Rate
A Drop Rate is a value that indicates how often an item has a chance to drop from a game event such as defeating an enemy.
Simple Drop Rate
The simplest implementation of a drop rate is to store the rate as a percentage or ratio, and then generate a random number and check if it is lower than the drop rate. If it is, the item drops. This is similar to rolling a dice and dropping the item if certain numbers come up.
// 1 in 20 drop rate (could also set to 0.05f directly) float DropRate = 1f / 20f; void OnEnemyKill() { var n = random.NextDouble(); if (n < DropRate) { DropItem(); } }
- Pros
- Easy to understand
- Promotes trading items between players
- Cons
- For small drop rates and rare items, there is a large variation from player to player in how often the item drops.
- If the item is something that the player is intended to grind for, the grind may take multiple times longer than average.
Sampling without Replacement
For rare items that the player cannot trade or must obtain for progression, sampling without replacement provides a more consistent experience for obtaining an item. Each time the item fails to drop, the chance of failure decreases. This is similar to picking a card from a deck and removing the card from the deck once picked.
// 1 in 20 drop rate (numerator) float DropRateSuccess = 1f; // 1 in 20 drop rate (denominator) int DropRateTotal = 20; // number of times the item has failed to drop since last success int DropFailures = 0; void OnEnemyKill() { var n = random.NextDouble(); if (n < DropRateSuccess / (DropRateTotal - DropFailures)) { DropItem(); DropFailures = 0; } else { DropFailures++; } }
- Pros
- Uniform distribution of items
- Limits the maximum time needed to grind for an item
- Promotes grinding for an item
- Cons
- Introduces more total items than the drop rate suggests.
- May oversaturate a trade market.
- Some players may obtain the item on the first or second opportunity, while others still have to grind.
Sampling with Delay without Replacement
In some situations, sampling without replacement is not a good solution because the item is not intended to drop until after a minimum number of tries. This can be solved by sampling with delay.
// 1 in 20 drop rate (numerator) float DropRateSuccess = 1f; // 1 in 20 drop rate (denominator) int DropRateTotal = 20; // Drop rate delay (cannot drop in the first 10 chances after dropping) int DropRateDelay = 10; // number of times the item has failed to drop since last success int DropFailures = 0; void OnEnemyKill() { var n = random.NextDouble(); if (DropFailures >= DropRateDelay && n < DropRateSuccess / (DropRateTotal - DropFailures)) { DropItem(); DropFailures = 0; } else { DropFailures++; } }
- Pros
- Uniform distribution of items
- Limits both the minimum and maximum time needed to grind for an item
- Promotes grinding for an item
- Cons
- Not as simple to explain or understand.
- Introduces less total items than the drop rate suggests.
Example: Dropping a key for a door
Suppose a game has a room with a locked door that spawns endless waves of monsters. Killing a monster has a 10% chance to drop a key that opens the door. How many monsters need to be killed to open the door?
Total Kills | Simple Drop Rate (1 in 10) | Sampling without Replacement (1 in 10) | Sampling with Delay without Replacement (1 in 10, Delay = 5) |
---|---|---|---|
Players with Key | Players with Key | Players with Key | |
1 | 10% | 10% | 0% |
2 | 19% | 20% | 0% |
3 | 27% | 30% | 0% |
4 | 34% | 40% | 0% |
5 | 41% | 50% | 0% |
6 | 47% | 60% | 20% |
7 | 52% | 70% | 40% |
8 | 57% | 80% | 60% |
9 | 61% | 90% | 80% |
10 | 65% | 100% | 100% |
20 | 88% | ||
30 | 96% | ||
40 | 99% |
As shown in the table, the major differencec in drop rate implementations are the minimum and maximum amount of enemies killed before players obtain the key. For this scenario Sampling with Delay without Replacement is the best implementation, forcing all players to kill between 6 and 10 enemies to progress.