Loot Drop Chance

I looked through several threads and answers on this topic but can’t seem to find something that works for my situation. I’m trying to create a loot drop system where each item has a different percent chance to drop when an enemy dies. So lets say I have 5 items with the following drop chances:

item1 - 80%

item2 - 60%

item3 - 50%

item4 - 30%

item5 - 10%

From what info I found on this topic, I could do the following:

var randomNumber : int = Random.Range(1, 101);

if (randomNumber <= 10)
{
     //drop item5
}
else if (randomNumber <= 30)
{
     //drop item4
}
else if (randomNumber <= 50)
{
     //drop item3
}
else if (randomNumber <= 60)
{
     //drop item2
}
else if (randomNumber <= 80)
{
     //drop item1
}

But this doesn’t seem right to me. According to the code above, doesn’t item1 have a 20% drop rate instead of 80% since it can only drop when the random number is 61-80? Item5 seems to be the only one that is truly a 10% drop rate. The others are more like a range instead of from 1 to the drop rate.

For my system, I only want one item to drop when an enemy dies, but not 100% of the time. So sometimes it can drop something, and somethings it won’t.

Also, what about for items that have the same drop chance? Like if item1 and item2 had a 80% drop chance, do I just do another Random.Range() if the first random number was <= 80? That also doesn’t make sense to me because then it would mean item1 and item2 have an initial 80% drop chance, but then if they are chosen, they have to go through another check where each of the two items has a 50% chance to drop.

You are right, this is not going to be what you describe. And you cannot get what you want. That is if item1 gets selected 80% of the time, item2 cannot be selected 60% of the time unless you allow multiple items to drop. One solution would be to partition 100 for the various items:

     5% no drop
     5% item 5
    10% item 4
    15% item 3
    25% item 2
    40% item 1

Then you can assign the various ranges to each of the items.
If you want something more forgiving/automatic, you could assign weighted values to each one, but the Random.Range() would be from 1 to the sum of all the weighted values. And each item would be assigned a range based on the weight.

Here is a bit of code that would do a return based on weighted values:

#pragma strict
var items : int[] = [10, 20, 30, 40, 60, 80, 95];

function RandomItem() : int {
	var range = 0;
	for (var i = 0; i < items.Length; i++)
		range += items*;*
  • var rand = Random.Range(0, range);*

  • var top = 0;*

  • for (i = 0; i < items.Length; i++) {*
    _ top += items*;_
    _
    if (rand < top)_
    _
    return i;_
    _
    }_
    _
    }*_
    Note the list of values add up to 335, so the actual percentage change is the weight / 335.

take a look at http://www.codeproject.com/Articles/420046/Loot-Tables-Random-Maps-and-Monsters-Part-II
it´s not difficult to implement :slight_smile:

You can just do each separately:

var dropped = false;
var randomNumber : int = Random.Range(1, 6);
if(randomNumber < 5) { //80% chance
//drop1
dropped = true;
}
else
randomNumber = Random.Range(1, 6);
if(randomNumber < 4 && dropped == false)  //60% chance
//drop2

etc…