[How Stuff Works] Loot Generation

ChthonChthon Posts: 1,855
edited May 2016 in TL2 General Discussions
I was looking into this for modding purposes awhile back. Since there seems to be some interest in the topic on the forums, I thought I'd post some info about how loot generation works in TL2.

Step 0: Kill a Monster
The first step in the loot generation process is that you have to kill a monster. When a monster dies, the loot generation process begins. This process is run independently for each player who is close enough (and probably locally on that player's computer). You cannot see, much less steal, other players' loot. How close is close enough is defined in GLOBALS.DAT as LOOT_DISTRIBUTION_RANGE:68.

Step 1: The Monster's Treasure Entries
In each monster's data file, there can be up to three entries for "treasure." Each entry specifies three things: The spawnclass to roll for the drop, the minimum number of times to roll that spawnclass, and the maximum number of times to roll that spawnclass. When the monster dies, for each treasure entry it has, a random number between the entry's minimum and maximum is picked and that entry's spawnclass is rolled that number of times.

In order to keep this example simple, I'm going to proceed as if we're only doing one roll for one treasure entry; but remember that it's entirely possible to end up repeating steps 2 and 3 for multiple rolls for each treasure entry, and that a monster can have up to three treasure entries.

Step 2: Spawnclasses!
A spawnclass consists of a list of entries. Each entry contains four major pieces of information:
  • First, what you get if the entry is chosen. There are three possibilities:
    • A specific item. If this entry is chosen, you get this specific item. Example, if the entry says "Mana Potion 3" as a specific item, then you will get a Mana Potion 3 (a/k/a "Giant Mana Potion"). FYI: Gold piles are specific items.
    • A Unit Type. If this entry is chosen, you get a random item from this unit type. See Step 2b for details. FYI: "None" is a unit type, meaning you get nothing. it is by far the most common unit type in the spawnclasses.
    • A roll from another spawnclass. If this entry is chosen, you go roll the named spawnclass. The process continues recursively until you finally roll a specific item or a unit type.
  • Second, the "weight" of this entry being chosen. The entry's chance of being chosen is equal to its weight divided by the sum of the weights for all the entries in the spawnclass. Entries with a weight of -1 are always chosen (which means that more than one entry can be chosen when a spawnclass is rolled.)
  • Third and fourth, a minimum and a maximum. If this entry is for a specific item, you will get a random number, between the minimum and the maximum, of copies of that specific item. If this entry is for a unit type, you will get a random number, between the minimum and the maximum, of items from the unit type. If this entry is for a spawnclass, you will get a random number, between the minimum and the maximum, of rolls of that spawnclass.

Entries within a spawnclass can also have some other properties. These aren't very important for understanding the overall picture, but may be helpful to modders and detail-oriented loot seekers:
  • Beneficiary Unit Type (optional). This entry cannot be selected if the player's character is not of this unit type. Used to make class-specific quest rewards.
  • Rarity Override (optional). Only applies if this entry is for a unit type. Unknown if this is inherited by recursed spawnclasses. Ignores the rarities defined in items' dat files, causing all eligible items to have the same chance to spawn -- including those that would otherwise never spawn due to rarities of 0.
  • Level Bonus (optional). Applies if this entry is for a unit type. Unknown if it also applies if this entry is for a spawnclass that doesn't specify its own level bonus. Loot gets generated by this entry as if the monster was this many levels higher than it actually was.
  • Magic Find % (optional). Applies if this entry is for a unit type. Unknown if it also applies if this entry is for a spawnclass that doesn't specify its own MF bonus. Loot gets generated by this entry as if the player has this much more MF% than the player actually has.
  • Ignore range (true or false). Only applies if this entry is for a unit type. If set to "true," then all items from the unit type are candidates to drop instead of only items with a level range that includes the dead monster's level.
  • Force enchant (true or false). If set to true, item cannot be white; must be green or better.
  • No unique (true or false). Only applies if this entry is for a unit type. Unique items are excluded from being candidates to drop.
  • No magical (true or false). Only applies if this entry is for a unit type. Blue items are excluded from being candidates to drop.
  • No set pieces (true or false). Only applies if this entry is for a unit type. Set items are excluded from being candidates to drop.
  • Only set pieces (true or false). Only applies if this entry is for a unit type. Everything other than set items are excluded from being candidates to drop.

Again, for the sake of simplicity, I'm going to be proceeding as if we just picked one spawnclass entry; but remember that we could have had multiple entries picked if some had weights of -1, so it's possible to go through steps 2b, 2c, and 3 multiple times per spawnclass roll. And that's on top of going through step 2 multiple times if the monster had multiple treasure entries and/or multiple rolls for a treasure entry.

Step 2b. Magic Find!
This step only applies if a spawnclass entry for a unit type gets selected. If a spawnclass entry for a specific item was selected, skip to step 3.

Before I describe how magic find works, here's a very important note: Magic find only comes into the picture AFTER a spawnclass entry for a unit type gets selected. It does NOT do anything to steer the random selection of which entry from the spawnclass gets chosen. Two examples to clarify this:
1. A spawnclass contains two entries: one for the unit type "potion" and one for the unit type "legendary sword," each with equal weight. You will get a potion 50% of the time regardless of your MF%.
2. A spawnclass contains two entries: one for the unit type "potion" and one for the unit type "1H Sword," each with equal weight. You will get a 1H Sword 50% of the time regardless of your MF%. If you get a 1H Sword, then the rarity of the sword will be affected by your MF%.
Because of the way Runic laid out the spawnclasses for "decent" drops, MF usually has no effect on them (i.e., it's useless for "boss running" like in D2), and is only useful for improving the terrible odds on what are supposed to be "****" drops. (This is definitely something that could stand to be improved through modding.)

With that out of the way, magic find works as follows:
Assuming that a spawnclass entry for a unit type has been selected, the next step is to choose a rarity level. The rarity levels are defined in GLOBALS.DAT as:
NORMAL_ITEM_WEIGHT:10000 (white items)
MAGIC_ITEM_WEIGHT:90 (blue items)
UNIQUE_ITEM_WEIGHT:7 (gold and red items)
RANDOMMAGIC_ITEM_WEIGHT:100 (green items)
So, for example, the baseline chance for a blue item is 90 / (10k + 100 + 90 + 7) ~= 0.0088.

Magic find effects these weights as follows: new_weight = old_weight * (1 + (MF/100 * bonus/100)), where the bonuses are also defined in GLOBALS.DAT as:
MAGICFIND_MAGIC_INFLUENCE:2000 (blue items)
MAGICFIND_UNIQUE_INFLUENCE:2000 (gold and red items)
MAGICFIND_RANDOM_INFLUENCE:1000 (green items)
So, for example, with 10% MF, your chance to find a blue item would increase to 270 / (10k + 200 + 270 + 21) ~= 0.026.

A couple observations here, mostly based on the fact that MF% modifies the weights for the rarity levels (rather than a more intuitive system like modifying the threshholds for a waterfall):
1. There is no plain English way to express what MF% does in TL2. Intuitive statements like "100% MF doubles your chance to find magic items" are nowhere near accurate.
2. The relationship between MF% and the actual chance of getting a particular rarity is non-linear with diminishing returns.
3. The hidden bonus multipliers mean that low amounts of MF% have a much, much bigger influence than you would intuitively expect from the number displayed. For instance, our example with 10% MF nearly tripled the actual odds of getting a blue item.

Step 2c: From Unit Types to Items
This step only applies if a spawnclass entry for a unit type gets selected. If a spawnclass entry for a specific item was selected, skip to step 3.

Again assuming that a spawnclass entry for a unit type has been selected, after the rarity is selected, it's time to pick the actual item. This is a two step-process:
First, unless the spawnclass entry had "ignore range" set to true, the pool of items in the unit type is filtered by level. Items have a level range bracketed by a minimum and maximum in their dat file. (I don't remember the default values for if these fields are left blank, but they're something like item's level +/- 4.) Items are only allowed to stay in the pool of candidates if the monster's level (as modified by any level bonus in the spawnclass entry) falls within that range.
Second, the rarities of the items remaining in the candidate pool are added up, and each item has the chance to drop equal to its rarity divided by the sum of all the rarities. Items with a rarity of 0 cannot spawn unless a rarity override is specified in the spawnclass entry (in which case all items will have an equal chance).

Step 3: Affixes and Sockets
At this point, we know what kind of item is going to drop -- either because our chosen spawnclass entry specified a particular item to start with, or because we went through the whole process of picking an item from a unit type. What's left to figure out is what kind of magical properties the item is going to have. There are three general possibilities: First, a plain white item will never have anything added to it. Easy enough. Second, an item that has one or more affixes already assigned in its dat file will get exactly what the dat file says it will get, nothing more or less. (All unique items fit into this category. So do 4-socket weapons, due to a hidden "blank" affix.) The third category is the random blues and greens, where the rules get interesting:

The affixes providing magical properties are defined with a list of item types and a range of item levels they can appear on. Affixes are selected by a system that should be familiar to you by now -- the weights for all eligible affixes are added up, and each affix's chance to appear equals its weight divided by the sum of all the weights.

Each affix has a defined cost called "slots occupy." Typical values are 1, 2, 3, and 5. Items have a number of "slots" to spend on affixes picked randomly from the ranges for their rarity defined in GLOBALS.DAT:
MIN_RANDOM_ENCHANT_SLOTS:2 (green items)
MAX_RANDOM_ENCHANT_SLOTS:2 (green items)
MIN_MAGIC_ITEM_SLOTS:5 (blue items)
MAX_MAGIC_ITEM_SLOTS:6 (blue items)
MIN_UNIQUE_ITEM_SLOTS:10 (gold and red items, but never matters b/c these items all have predefined affixes)
MAX_UNIQUE_ITEM_SLOTS:12 (gold and red items, but never matters b/c these items all have predefined affixes)
The process of rolling for affixes continues until the item does not have enough "slots" left to pay for any of the available affixes.

Randomly generated items may also get sockets, up to the maximum allowed in that item's dat file, based on the following odds defined in GLOBALS.DAT:
RANDOM_SOCKET_CHANCE:25
SECOND_SOCKET_CHANCE:33 (8.25% overall)
THIRD_SOCKET_CHANCE:33 (~2.7% overall)
(These numbers strike me as somewhat higher than what I'm used to seeing in game, so that may be another factor hidden somewhere that lowers the odds.)

An Example:
I think an example may help make sense of the system, so let's do one.
This example is quite long, so I'm going to put it in a spoiler. I do recommend reading it though, since it really helps to clear things up.
Assume that you have just killed a Salamander in Swarm Point in NG0. The level range on Swarm Point in NG0 is 31-33, so let's assume 32. A salamander has only one treasure entry:
[TREASURE]
	<STRING>SPAWNCLASS:TREASURE_MONSTERLOOT_NORMAL
	<INTEGER>MIN:1
	<INTEGER>MAX:3
[/TREASURE]
So, we are going to roll the spawnclass named "SPAWNCLASS:TREASURE_MONSTERLOOT_NORMAL" a random number of times from 1 to 3. Let's say our random number comes up 2, so we will do 2 rolls.

Let's take a look at SPAWNCLASS:TREASURE_MONSTERLOOT_NORMAL. Here it is:
[SPAWNCLASS]
	<STRING>NAME:TREASURE_MONSTERLOOT_NORMAL
	[OBJECT]
		<STRING>UNITTYPE:NONE
		<INTEGER>WEIGHT:46799
	[/OBJECT]
	[OBJECT]
		<STRING>SPAWNCLASS:TREASURE
		<INTEGER>WEIGHT:3200
	[/OBJECT]
	[OBJECT]
		<STRING>UNITTYPE:LEGENDARY
		<INTEGER>WEIGHT:1
		<INTEGER>RARITY_OVERRIDE:1
	[/OBJECT]
[/SPAWNCLASS]

First Roll:
None of the 3 entries has a -1 weight, so there are no automatic picks, just one random one. The odds are 46799/50k for "none"; 3200/50k for recursing into the spawnclass named "treasure"; and 1/50k for the unit type "Legendary." Let's say our random roll comes up, as is most likely, for "none." Nothing drops from this roll. But we've got one roll still to go.

Second Roll:
Again, none of the 3 entries has a -1 weight, so there are no automatic picks, just one random one. The odds are still 46799/50k for "none"; 3200/50k for recursing into the spawnclass named "treasure"; and 1/50k for the unit type "Legendary." Let's say our random roll comes up for recursing into the spawnclass named "treasure." So we go do a roll for the spawnclass "treasure."

Second Roll Continued - Rolling Spawnclass "Treasure":
Let's take a look at the spawnclass named "treasure." Here it is:
[SPAWNCLASS]
	<STRING>NAME:TREASURE
	[OBJECT]
		<STRING>SPAWNCLASS:WEAPONS
		<INTEGER>WEIGHT:240
		<INTEGER>MAGICFIND:10
	[/OBJECT]
	[OBJECT]
		<STRING>SPAWNCLASS:ARMOR
		<INTEGER>WEIGHT:240
		<INTEGER>MAGICFIND:10
	[/OBJECT]
	[OBJECT]
		<STRING>UNITTYPE:POTION
		<INTEGER>WEIGHT:80
	[/OBJECT]
	[OBJECT]
		<STRING>UNITTYPE:SCROLL
		<INTEGER>WEIGHT:4
	[/OBJECT]
	[OBJECT]
		<STRING>SPAWNCLASS:TRINKETS
		<INTEGER>WEIGHT:56
		<INTEGER>MAGICFIND:10
	[/OBJECT]
	[OBJECT]
		<STRING>SPAWNCLASS:SOCKETABLES_SPAWN
		<INTEGER>WEIGHT:2
		<BOOL>NO_UNIQUE_ITEMS:true
	[/OBJECT]
	[OBJECT]
		<STRING>SPAWNCLASS:SPELLS_SPAWN
		<INTEGER>WEIGHT:2
	[/OBJECT]
	[OBJECT]
		<STRING>UNITTYPE:NONE
		<INTEGER>WEIGHT:400
	[/OBJECT]
	[OBJECT]
		<STRING>SPAWNCLASS:GOLD_PIECES
		<INTEGER>WEIGHT:28
		<INTEGER>MINCOUNT:3
		<INTEGER>MAXCOUNT:7
	[/OBJECT]
[/SPAWNCLASS]
Again, none of the entries has a -1 weight, so there are no automatic picks, just one random one. The odds are 400/1052 for "none"; 240/1052 for recursing into the spawnclass named "weapons"; and so on. Let's say our random roll comes up for recursing into the spawnclass named "weapons." So we go do a roll for the spawnclass "weapons." Note also that we've picked up a 10% MF bonus here (and I believe it carries into recursed spawnclasses so long as they don't specify a different one).

Second Roll Still Continued - Rolling Spawnclass "Weapons":
Let's take a look at the spawnclass named "weapons." Here it is:
[SPAWNCLASS]
	<STRING>NAME:WEAPONS
	[OBJECT]
		<STRING>SPAWNCLASS:2HSWORDS_SPAWN
		<INTEGER>WEIGHT:6
	[/OBJECT]
	[OBJECT]
		<STRING>SPAWNCLASS:2HMACES_SPAWN
		<INTEGER>WEIGHT:6
	[/OBJECT]
	[OBJECT]
		<STRING>SPAWNCLASS:2HAXES_SPAWN
		<INTEGER>WEIGHT:6
	[/OBJECT]
	[OBJECT]
		<STRING>SPAWNCLASS:SWORDS_SPAWN
		<INTEGER>WEIGHT:12
	[/OBJECT]
	[OBJECT]
		<STRING>SPAWNCLASS:PISTOLS_SPAWN
		<INTEGER>WEIGHT:14
	[/OBJECT]
	[OBJECT]
		<STRING>SPAWNCLASS:MACES_SPAWN
		<INTEGER>WEIGHT:12
	[/OBJECT]
	[OBJECT]
		<STRING>SPAWNCLASS:WANDS_SPAWN
		<INTEGER>WEIGHT:11
	[/OBJECT]
	[OBJECT]
		<STRING>SPAWNCLASS:AXES_SPAWN
		<INTEGER>WEIGHT:12
	[/OBJECT]
	[OBJECT]
		<STRING>SPAWNCLASS:BOWS_SPAWN
		<INTEGER>WEIGHT:11
	[/OBJECT]
	[OBJECT]
		<STRING>SPAWNCLASS:SHIELDS_SPAWN
		<INTEGER>WEIGHT:15
	[/OBJECT]
	[OBJECT]
		<STRING>SPAWNCLASS:RIFLE_SPAWN
		<INTEGER>WEIGHT:11
	[/OBJECT]
	[OBJECT]
		<STRING>SPAWNCLASS:CROSSBOW_SPAWN
		<INTEGER>WEIGHT:5
	[/OBJECT]
	[OBJECT]
		<STRING>SPAWNCLASS:POLEARM_SPAWN
		<INTEGER>WEIGHT:8
	[/OBJECT]
	[OBJECT]
		<STRING>SPAWNCLASS:STAFF_SPAWN
		<INTEGER>WEIGHT:16
	[/OBJECT]
	[OBJECT]
		<STRING>SPAWNCLASS:CANNON_SPAWN
		<INTEGER>WEIGHT:11
	[/OBJECT]
	[OBJECT]
		<STRING>SPAWNCLASS:FISTS_SPAWN
		<INTEGER>WEIGHT:14
	[/OBJECT]
[/SPAWNCLASS]
Again, none of the entries has a -1 weight, so there are no automatic picks, just one random one. The odds are 6/170 for recursing into the spawnclass named "2HSWORDS_SPAWN"; 6/170 for recursing into the spawnclass named "2HMACES_SPAWN"; and so on. Let's say our random roll comes up for the unit type "2HSWORDS_SPAWN." So we go do a roll for the spawnclass "2HSWORDS_SPAWN." Further down the rabbit hole!

Second Roll Continued Some More - Rolling Spawnclass "2HSWORDS_SPAWN":
Let's look at this one:
[SPAWNCLASS]
	<STRING>NAME:2HSWORDS_SPAWN
	[OBJECT]
		<STRING>UNITTYPE:2HSWORD
		<INTEGER>WEIGHT:-1
	[/OBJECT]
[/SPAWNCLASS]
Aha! A weight of -1. That means that this entry will be automatically selected without a random roll. (Not that it'd have any competition if there was a random roll...) So we select the unit type "2HSWORD."

Since we (finally) have a unit type, rather than a single specific unit, we need to sort out out which item we actually get.

The first step is to work out the rarity. This means that magic find finally gets to come into play. Let's assume our player had 15% MF to start with. We picked up 10% MF in a higher spawnclass (and I believe that carries through) for a total of 25% MF. That gives us odds of 10k/10932 of a white item, 350/10932 for a green item, 540/10932 for a blue item, and 42/10932 for a gold/red item (though most of the red items have rarity of 0 or a low rarity and require level 99). Let's say our random roll comes up for a blue item.

The next step is to figure out which blue item. There are 32 blue 2-handed swords, but most of them don't have the right level range. We only get to consider the ones with a level range that includes level 32, since that's what our dear departed salamander was. Southern Tulwar doesn't specify its level range, but it's a level 28, so I think 32 is within the default range. Ashenfeld Slasher specifies a range of 32-33. Beheading Sword has no range specified and is exactly level 32. Cryptkeeper Claymore has no range specified, but is level 36, and, again, I think that falls within the default. So, that's 4 candidates. Ashenfeld Slasher has a rarity of 10; the others have a rarity of 100. That means odds of 10/310 for the Ashenfeld Slasher and 100/310 for the others. Let's say the random roll come up for a Beheading Sword.

Now we know we're getting a Beheading Sword for our second roll. What's left is to figure out its magical properties. It's not a white item -- which would mean it doesn't get any. Nor does it have any predefined affixes -- which would also mean it doesn't get any. The firs thing to do is a random roll to decide how many "slots" we get. Blue items get 5 or 6. Let's say our random roll came up a 6. So we go make a list off all the affixes that can apply to 2HSWORD or one of its parent types and that can spawn at level 32, add up their weights, and do a random roll. I'm not about to type that out, so just imagine I did. Let's say our first roll for an affix comes up with "OFICE5." So our Beheading Sword gets the "OFICE5" affix added, meaning additional base damage of a random amount between 21% and 29% of the weapon damage graph at level 32, and probably "of Ice" added to it's name. (Affixes have priority ranks for which one gets to appear in the name. This one has a rank of 26, so it usually wins.) Strangely enough, the "OFICE5" affix costs 5 slots, so we have 1 slot left. So we narrow down the list of eligible affixes to only those with a slot cost of 1 and do another random roll. Let's say we get "OF_TL2_SHORTSTUN." That gives our Beheading Sword a 5% chance to stun for 2 seconds. We're now out of slots.

The last thing to do is roll for sockets. We've got a 25% chance of getting the first socket. Let's say our roll comes up good. So we get 1 socket. We've got a 33% chance to get a second one.Let's say our roll comes up bad. So we don't get the second socket, nor a chance to roll for a third.

We're done with the second roll. We got a Beheading Sword with some big ice damage, a 5% chance to stun for 2 seconds, and 1 socket.

So, to recap:
We killed a level 32 salamander who gave us 2 rolls of the treasure class "SPAWNCLASS:TREASURE_MONSTERLOOT_NORMAL." Our first roll was a bust. Our second roll recursed through several spawnclasses until we finally got the unit type 2HSWORD. With a little help from magic find, we rolled a blue rarity. Among the 4 blue 2-handed swords with level ranges including 32, we rolled a Beheading Sword. Since this is a random-stats item, we rolled for affixes, and got some big ice damage and a 5% chance to stun for 2 seconds before running out of slots. Since this is a random-stats item, we also got to roll for sockets, and we got one before failing the second roll.
Torchlight 2 Rapid Respec - Putting the "hack" in "hack-n-slash"
StashNinja - INFINITE Stash for Torchlight 2
NullMod - Play together in the same multiplayer game with different mods!

Comments

  • freerealestatefreerealestate Posts: 4
    edited May 2016
    Thanks for your post, without it I would never be able to make sense of it.

    I'm still a bit confused though.

    I've been farming Grell for a long, long time. I'm told he drops an eye, but I've never seen it after around 75 or more runs. So I decided to look in the game files and try to figure out what was happening. I loaded up Grell's spawnclass, then saw he has an eye chance specific spawnclass that has a 15 weight for the eye, and an 85 weight for nothing; in other words, a 15% chance of dropping an eye. But in practice it's nowhere close to 15%. Barring incredible, other-worldly terrible luck, I should have had at least one eye drop at this point. I can only imagine that there's something going on that's affecting the drop rate.

    The only difference I could see between the entries was that the eye drop had a weight of 15 and a rarity override of 1. For "nothing" it was weighted 85 with a rarity override of -1.

    So what effect, if anything, does "1 rarity override" (as opposed to -1 rarity override for "nothing") have on the chance for an Eye of Grell to actually drop?

    edit: a word
  • ChthonChthon Posts: 1,855
    Thanks for your post, without it I would never be able to make sense of it.

    I'm still a bit confused though.

    I've been farming Grell for a long, long time. I'm told he drops an eye, but I've never seen it after around 75 or more runs. So I decided to look in the game files and try to figure out what was happening. I loaded up Grell's spawnclass, then saw he has an eye chance specific spawnclass that has a 15 weight for the eye, and an 85 weight for nothing; in other words, a 15% chance of dropping an eye. But in practice it's nowhere close to 15%. Barring incredible, other-wordly terrible luck, I should have had at least one eye drop at this point. I can only imagine that there's something going on that's affecting the drop rate.

    The only difference I could see between the entries was that the eye drop had a weight of 15 and a rarity override of 1. For "nothing" it was weighted 85 with a rarity override of -1.

    So what effect, if anything, does "1 rarity override" (as opposed to -1 rarity override for "nothing") have on the chance for an Eye of Grell to actually drop?

    I'm afraid you've just had incredible, other-wordly terrible luck. (About 1 in 200k odds if 75 runs isn't an exaggeration.) Grell's eye has a flat 15% chance to drop.

    (Also, beware the Gambler's Fallacy when thinking about your loot drops. While he odds of not getting the eye 75 consecutive times are vanishingly low, the odds of not getting the eye on the 76th roll remains 85%. There is no such thing as being "due" some good luck to balance out prior bad luck.)

    Rarity override only matters when the selected spawnclass entry provides for a unit type. Overriding rarity can equalize the odds of eligible items in the spawnclass to spawn, and cause items to spawn that are otherwise blocked from spawning by a 0 rarity. For spawnclass entries that provide for a specific unit (like the one that drops Grell's eye), rarity override does nothing.
    Torchlight 2 Rapid Respec - Putting the "hack" in "hack-n-slash"
    StashNinja - INFINITE Stash for Torchlight 2
    NullMod - Play together in the same multiplayer game with different mods!
Sign In or Register to comment.