Pillars of Eternity Wiki
Advertisement

Random loot is loot that the game selects from a set of possible items for a given container.

This article primarily covers random loot generation in Pillars of Eternity. Many concepts carry over to Pillars of Eternity II: Deadfire, although the seed generation in Deadfire no longer relies on a value that is unchanging, so loot is not deterministic.

Containers[]

Lootable objects (containers and killed NPCs) fetch their contents from three main sources:

  • A loot list, which is a set of items that are picked at random. Some containers do not have a loot list, and therefore will not generate random loot. Notably a majority of containers in The White March - Part I and The White March - Part II expansions do not have random loot.
  • An inventory. This is a fixed set of hand-picked items that are guaranteed to appear in the container. All quest items and most unique items are fixed.
  • The items equipped by the killed creature or NPC, including their equipment slots, weapon sets, and quick items. Note that certain items are set to never drop as loot, and containers can be set to not pull items from the character's equipment.

Fixed containers can be locked CUR locked noarrow.png- requiring a key or the appropriate skills (along with Lockpicks) to unlock, trapped CUR disarm noarrow.png- which requires you disarm the trap to safely open it, and hidden CUR noLOS noarrow.png- which prevents the container from showing up or being interacted with before it is detected. All of these checks use the Mechanics skill. Most containers that are trapped are also hidden.

By design, certain items do not appear as random loot in containers found in the world, including monster parts, plants, crafted food and drink items, and most shields.

Loot list evaluation[]

Loot lists are used to determine the loot placed in a container, and the probability of specific items occurring in a container. Each element ("loot item") in the list can be either an item (i.e. piece of equipment, weapon, consumable, etc), or a nested loot list which will be evaluated recursively.

Each element has the following properties:

  • A weight, which is used as a factor in a random weighted selection process. Items with a higher weight "take up more room" in the distribution, and are more likely to be selected than items with a lower weight. The default weight is 1, and items that are always present have a weight of 0. If all items in a loot list have a random weight of 1, they are all equally likely to be present in the container. If an item has a weight of 2, it is twice as likely to be present in the container than items with a 1.
  • A quantity, the amount of this item to be generated. In the case of a nested loot list, the list is evaluated <quantity> times instead of generating x amount of a single evaluation.
  • A boolean "always", which when set will mean this element will always be included in the container.

When a lootlist is evaluated - that is, a process where the game decides which items from the list will be placed into the container - only one element from the lootlist is selected. First, a random value is generated between 0 and the total weight of the loot list (excluding the upper limit, non-recursive). This value, or "roll", is used to determine which element from the list is selected. The list is then iterated from the start to the end, and the weight of each item is added at each step. Once the cumulative weight is greater than or equal to the value generated (or inversely the value generated is less than the cumulative weight), the item is picked and no more items are evaluated (besides those that should always be present).

Example

A loot list for a regular Xaurip looks something like this:

CreL_Xaurip
Item Qty Wgt Always
Spear_Xaurip 1 - true
Shield_Xaurip 1 - true
↳ Gem_1_100 1 1 false
PART_Xaurip_Tongue 1 1 false
(none) 1 3 false

In this instance, the first two rows are items that will always appear, a Xaurip Spear and a Xaurip Shield. One of next three items will appear randomly, based on a single roll made over the cumulative weight of these items . In this case, a random number is generated between 0 and 5 (upper limit exclusive).

  • If the result is 0, the loot lists Gem_1_100 is evaluated and its result added to the container.
  • If the result is 1, a Xaurip Tongue is added.
  • If the result is 2, 3 or 4, the empty item is picked, meaning no additional items are added. Because this item has a weight of 3, it is more likely to appear.

Random seed[]

A random seed (a value which is used to initialize the pseudorandom number generator) is calculated for each container when its contents are generated. The seed directly determines the random number sequence, and it is ultimately what influences the "rolls" that occur, and therefore the loot granted.

The seed is calculated using the following values:

  • The X and Z position of the loot object (the clickable on the ground), added together and truncated to an integer value. Since the position of a container on the screen remains consistent (containers don't typically move), this only serves to skew the rolls of a loot list on a per-container basis, so that containers with the same root loot list do not generate the same loot. Because of this, enemies cannot be reliably tied to a set of per-day items, since they can move around and will influence the seed. Interestingly, there are few enemies that do not move (e.g. Dank Spores), and in these instances they will always generate the same loot across the month.
    • As an aside (and slightly unrelated), the world is placed on the XZ-plane with the camera above facing down (-Y), however the camera is rotated by 180 + 45 degrees on the Y axis (and 40 degrees on the X axis) such that the world -X axis is towards the top right of the screen, the world +X axis is towards the bottom left of the screen, the world -Z axis is towards the top left of the screen, and the world +Z axis is towards the bottom right of the screen.
  • Multiplied by the hashcode of the player GameObject's name. This is always "Player_New_Game(Clone)_0" (1413436758), except in the Encampment after character creation, where it is "Player_<name>", and the Backer Beta, where it is "Player_Beta" (-2071464818). Because of this consistency, the player name does not end up affecting loot rolls at all. This is very likely an oversight on the developers' part.
    • Note that these exceptions persist from the start of the game until the next save and reload, meaning that the loot evaluations shown on the wiki will NOT be correct immediately after character creation until saving and reloading the same game - after which the player GameObject will then use the fixed name "Player_New_Game(Clone)_0".
  • Plus the current day of the month (a value from 1-20). This is shown in the bottom left of the text that appears when hovering over the clock in the action bar (e.g "2 Fonprima"). It is not to be confused with the days since the start of the adventure, shown as "Day X" in the top left of the same panel. Some days of the month will be shown as a holiday (counting as a 1-3 day month), which may confuse things.

With the above considered, the random seed and the subsequent random rolls can be extrapolated so that we can determine the exact loot that will be generated on each day of the month on a per-container basis.

The seed is computed and the items are generated on the first opening of the container, or in the case of lootable NPCs - when they are killed. When this occurs, the container contents are saved and will persist in the current save from then onwards.

Xorshift PRNG[]

Unity uses the Xorshift128 algorithm for fast random number generation, using a state consisting of four unsigned 32-bit integers. The seed (x) is used to initialize the other three state values (y, z, w) using a method similar to that of the Mersenne Twister (MT19937) PRNG. The Xorshift algorithm is well known and fairly simple, consisting of a series of bit-shifts and exclusive-or operations. Here's an implementation of Xorshift128 in C#, including the same Mersenne initialization method used by Unity:

// These state values must be initialized to not be all zero
private static uint x, y, z, w;

public static Init(int seed)
{
        x = (uint)seed;
        y = (uint)(MT19937 * x + 1);
        z = (uint)(MT19937 * y + 1);
        w = (uint)(MT19937 * z + 1);
}

public static uint Xorshift128()
{
	uint t = x ^ (x << 11);
	x = y; y = z; z = w;
	return w = w ^ (w >> 19) ^ t ^ (t >> 8);
}	

// Limits the range from 0 - max (exclusive)
public static uint Xorshift128(uint max)
{
	return Xorshift128() % max;
}

See also[]

  • Loot lists - A master list of all loot lists
  • Random loot tables - The original collection of tables listing where to find specific rare items. Some of this information may be outdated.
  • All item pages in Pillars of Eternity have a complete list of the containers that contain that item, and on what day of the month (e.g. Ruby#Random loot). Items that do not spawn randomly will not have this list.
  • All location pages in Pillars of Eternity have a sub-page with a complete list of the loot generated on all days of the month (e.g. Dyrford Village/Loot), and a summary of this loot on the location page itself (e.g. Dyrford Village#Loot).
  • All map pages in Pillars of Eternity have nodes that list the fixed loot and generated loot lists, linking to the container on the associated location page (e.g. Map:Dyrford Village.
  • The following pages mirror the random loot section shown on item pages, but are expanded to include more detail about each container. They have been split up to reduce server load and bandwidth overconsumption:

External links[]

Advertisement