EMI Loot

EMI Loot

5M Downloads

The average item amount and probability calculated by EMI_loot is giving wrong values

jopejoe1 opened this issue ยท 5 comments

commented

The average item amount and probability calculated by EMI_loot is giving wrong values.

For example, in the Buried Treasure loot it shows the probability for Iron Ingots to be 371% and the average item amount to be 2 where the actual probability is 99.4% and the average item amount is ~9 items.

EMI_Loot-wrong-values

I couldn't find where these numbers are getting calculated in the code, but the correct calculations should look something like this:

// Calculation of the average item amount in this pool
public static double avgItemAmount(double minStackSize, double maxStackSize, double minPoolRolls, double maxPoolRolls, int itemWeight, int totalWeight) {
	double avgStackSize = (minStackSize + maxStackSize) / 2;
	double avgPoolRolls = (minPoolRolls + maxPoolRolls) / 2;
	return avgStackSize * avgPoolRolls * itemWeight / totalWeight;
}

// Calculation of the probability that the item is appearing in this pool
public static double itemChance(double minPoolRolls, double maxPoolRolls, int itemWeight, int totalWeight) {
	double inverseResult = 0;
	int inverseItemWeight = totalWeight - itemWeight;
	double curDividend = totalWeight;
	double curDivisor = totalWeight * (maxPoolRolls - minPoolRolls + 1);

	for(int i = 0; i<=maxPoolRolls; i+=1) {
		if (i >= minPoolRolls) {
			inverseResult = inverseResult + curDividend / curDivisor;
		}
		curDividend = curDividend * inverseItemWeight;
		curDivisor = curDivisor * totalWeight;
	}

	return (1 - inverseResult) * 100;
}
commented

I can see where this confusion would come from, so it may be more clear to write something like 3.71 rolls instead of 371%.

commented

Yeah that would be less confusing, but would also be nice to have someway to see what the chance is that the item is appearing in loot.

commented

EMI Loot is performing ~the same probability math, and would arrive at the same result of ~9 stacks if not for integer rounding (3.71 roll-weight * 2.5 avg stack = ~9). Unfortunately, ItemStacks handle count as an int, as they should, so that precision gets lost.

This basically comes down to how to portray the total probability with multiple rolls, as well as how loot tables actually collate counts for items and rolls. Loot tables are very abstracted things, expecially in code, so arriving at a mathematically precise answer is tedious at best. Some issues that may come up for a pure mathematics approach:

  • An item is spread across multiple pools, probably with different conditions and weights.
  • An item is in the same pool multiple times with different conditions or functions.
  • Item Entries may be called from completely separate loot tables

As such I've made the decision to localize math as much as possible to where it can be relatively deterministic. For example, the set_count function is applied directly to the stack as it's parsed, resulting in the count of 2, rounded from 2.5. Weights are determined within one pool builder. This also helps with any custom loot functions EMI Loot may run across, as I am planning on developing a datapack-based function/condition parsing script "language" of sorts. If any of those custom things mess with item count, it can be done within the function, like set_count.

EMI Loot is saying "you are getting approximately 4 slots with iron, each with 2 (int rounded) iron on average"

The pure math would say "you are getting ~9 iron on average" and not have a concept of 'slots'

So you are technically correct, the sum values shown in this case by EMI Loot are somewhat off due to precision loss, but this is due to a decision made on programming approach for flexibility and determinism, and a parsing engine that's trying to match to the reality of loot pools within a table (the player will actually see multiple smaller iron stacks rather than one big one.)

commented

The easiest possible workaround I can think of would involve passing back a "stack correction factor" in my parsing result that would affect the item weight float. I'm not convinced I want to follow this approach, however, as that would simply be misrepresenting the weighted-rolls in order to increase precision lost elsewhere.

As the code stands, the percentage does accurately represent the expected number of slots a player can expect of an item in any given chest, and the item stack indicates a typical amount that can be expected in each slot. I'm not sure I want to lose that communicated information in pursuit of precision.

commented

I assumed that the percentage is the chance that the item has of appearing in a chest, and that the amount is referring to the average amount I can expect when I see the item.

In case of the same item appearing multiple times in the LootTable I assumed that it would appear multiple times in the output list.

My biggest issue is not really the amount I would probably take ages to realize that they are wrong, what my issue is that when I see a percentage of 100% or higher that I should be able to find at least 1 of that item in each chest of that kind.

So, from what I can see, this issue came about because we have a different expectation of each value should mean.