This project is intended to be a Python Package focused on performant crafting simulations for Path of Exile. All of the data is gathered from RePoE, which parses the content.ggpk file into json.
This project now uses Cython, which precompiles some of the code to allow for C level performance.
Upon close inspection one will notice extra structure around this package, which is to accomodate Cython.
We follow the cython template that scikit-learn uses, which is outlined at this repository.
The main gist of the extra files is there are recursive setup.py files in every subdirectory which help compile the cython into extension .c files for distribution.
To use this repository, one needs to install RePoE (which in turn requires PyPoE).
With these installed one can run pip install -e . in the PoECraft directory to install PoECraft as a package.
There are example scripts which are carefully annotated found in /example_scripts. These demonstrate the current basic features of this package.
Currently this package has no unit tests, but does have smoke tests to confirm the probability distribution on certain test items is as expected. The smoke tests check:
- Tag occlusion
- Generation Weight reweighting
- Mod group occlusion
- Prefix/Suffix occlusion
Note: there are currently no examples of mod groups which spawn both prefixes and suffixes on the same item, but this project does support that functionality
This project presumes the following model in which the game crafts items.
- Crafts one affix at a time - Even when a currency orb puts multiple affixes on an item, it accomplishes this by randomly selecting a mod from the available mod pool one at time
- 1:3:8 split for total number of affixes - For items with a max of 6 mods, extensive data farming has shown that there is a 1/12 chance for 6 mods, 3/12 chance for 5 mods, and 8/12 chance for 4 mods
- Max Prefix/Suffix other than 3/3
- Meta Crafting Mods
- Beast Crafting
- More Currency Items
There are multiple entities which influence the affix weighting.
- Mod Groups - In
RePoE.modsevery affix has a propertygroup. Only one total mod can show up from each group on the item - Tags - Every base item has tags on it which affect the weights in different ways:
- Base Item Tags - Every base item comes with tags which can be found in
RePoE.base_itemsunder the propertytags. - Added Tags - Affixes can add tags upon being put on an item, which can be found in
RePoE.modsunder the propertyadds_tags - Tags Influence Spawn Weights - For each mod it comes with a list of
spawn_weights, which associate to some tags the raw weight of the mod spawning. The game reads thespawn_weightsin the order they are listed, and selects thespawn_weightcorresponding to the firsttagwhich is on the item. - Generation Weights - In
RePoE.modsone can find the propertygeneration_weights, which is a list of tags. The game looks through the list from top to bottom, and stops when it finds atagalready on the item. Then it takesvalue/100 and multiples thespawn_weight.
- Base Item Tags - Every base item comes with tags which can be found in
- Mod Type Tags - These behave very similarly to tags, and are mainly used in fossil crafting
- Mod to Mod Type - Every affix in
RePoE.modshas a propertytypewhich corresponds to a mod type found inRePoE.mod_types - Mod Types to Tags - Every mod type in
RePoE.mod_typeshas a propetytagswhich corresponds tospawn_weights. These mod type tags affect spawn weight before the mod is rolled. - Mod Type Tag Multipliers in Fossils - In
RePoE.fossilsthere arepositive_mod_weightsandnegative_mod_weightswhich after being divided by 100 tell the generation weight applied to aspawn_weightif that mod has that mod type tag.
- Mod to Mod Type - Every affix in
- Prefix/Suffix Cap
- Some items have a 1/1 cap, 2/2 cap, 3/3 cap, or 4/4 cap. Once the cap is reached, all other prefixes or suffixes are removed from the pool.
- Currently do not have a working model of how Sanctified Fossils work
The crafting process at it's core is a markov chain - one can imagine starting with a blank base and then rolling a random first mod, whose probabilities are described above. Then for each one of those we get new probabilities based on tags, groups, etc. There are two basic approaches to evaluating a function over this probability space
- Exact Computation - In order to do exact computation, we need the exact probability of every permutation of mods spawning on an item. On a ilvl 100 Vaal Regalia there are 119 mods that can spawn. So for 6 mod variants we have 119^6 possible permutations. Many of these will be invalid because of too many prefixes, suffixes, or repeated groups. Regardless the order of magnitude should only be off by a bit. 10^12 leaves is computationally infeasible. -Mod Group Computation - One alternative strategy that would work for some cases is to instead calculate the probability of a mod group being chose, instead of a mod itself. However, with influenced items even the total number of mod groups can get near 100, leading to the same problem as before.
- Simulated Rollouts - Instead of exactly calculating the probability of each leaf in our crafting tree, we instead quickly simulate rollouts. There are a few limiting factors in simulating crafts: -Generating Random Numbers - Generating random numbers is slow and expensive. -Need to Recalculate Spawn Weights at Every Step - More on this below.
In order to get fast rollouts, we need to cache as much information as possible to do our random draws. There are three main factors that change our distribution: tags, groups, and generation type (prefix/suffix).