Graveflo / BDO_Enhancement_Tool

Open source tool for planning fail stacks and enhancement priority in Black Desert Online
27 stars 8 forks source link
bdo black-desert black-desert-online blackdesert blackdesertonline calculator gear planner python

BDO Enhancement Optimizer

I've throw together this fail stack calculator so that I could try out the new enhancement chance numbers that were released. I also wanted to get a more objective way to decide how to fail stack and enhance when considering multiple different pieces of gear at different enhancement levels.

It still needs more testing and the code could be commented better, but I am posting the code so it isn't necessary to wait on me and you can alter it as you please.

Video Guide: https://www.youtube.com/watch?v=l6IzuQ-0Crw

Important Info

GUI User guide

1.) Go to the "Monnies/ MP" tab on the left side of the program.

2.) Go to the "FS Gear" tab on the left side of the program.

3.) OPTIONAL: Go to the "FS Cost" tab on the left side of the program.

4.) Go to the "Equipment" tab on the left side of the program.

5.) Go to the "Strategy" tab on the left side of the program.

6.) Press the "Open Guide Overlay" button at the bottom of the "Strategy" tab

Future Plans

How run code

If you are unsure how to set up the environment see the \"Dependencies\" section below. Make sure the directory that houses the code is in python path variable and run:

python.exe -m BDO_Enhancement_Tool

Dependencies

This project depends on several libraries and some libraries of my own. For this project to work the utilities and QtCommon module collection must be present. These are small versions of larger modules that I copied and cleaned for convenience.

See requirements.txt:

altgraph==0.17
future==0.18.2
fuzzywuzzy==0.18.0
numpy==1.19.0
packaging==20.4
pefile==2019.4.18
pyparsing==2.4.7
PyQt5==5.15.0
PyQt5-sip==12.8.0
PyQtWebEngine==5.15.0
python-Levenshtein==0.12.0
pywin32-ctypes==0.2.0
six==1.15.0
urllib3==1.25.9

Versions

It is recommended to install Anaconda python distribution 2.7 for this project because that is how it was developed.

See: Downloads | Anaconda

> python --version
Python 3.7.6
> python -m conda --version
conda 4.8.3

Methods

To be clear, I am not great at statistics so I highly encourage anyone who know what they are doing to critique the methods I am using to calculate. I detail the math here in the hopes that someone may destroy it \:)

Establishing Fail Stack Cost

The cost of a fail is an important factor in the calculation because it establishes a curve of value that equipment and opportunity cost rely on.

The essence of a fail stack cost at any level of fail stacks is the opportunity cost of acquiring another fail stack and the value of the current fail stack.

The opportunity cost pseudo code:

op_cost = black_stone_cost + (suc_rate * (last_cost + return_cost)) + (fail_rate * repair_cost)

Here, there is:

Since the opportunity cost is just the cost for the opportunity to gain a fail stack, we calculate the average amount of opportunities incurred before a fail is achieved. Now and hereafter the number of fails is calculated as the average number of fails:

avg_num_fails = 1.0 / suc_rate

Since for fail stacking we are counting the number of successes before a failure we have:

avg_num_success = 1.0 / fail_rate

So the function (F) defined as, cost of gaining a fail stack, at fail stack position x :

F(x) = avg_num_success * op_cost
F(x) = avg_num_success * (black_stone_cost + (suc_rate * (F(x-1) + return_cost)) + (fail_rate * repair_cost))

Calculating Enhancement Cost

The next step is to use the global fail stack cost curve to find the number of fail stacks for each gear such that the cost of enhancing at that number of fail stacks is minimized. Fail stacks get expensive quickly, almost needlessly so, an attempt at mitigating this issue is addressed next.

The method for calculating the price uses the same concept from before where an average number opportunities is calculated and then used with probabilities to compute an overall cost. The difference here is an a number of fails is calculated and the remainder is used as a number of successes. These are not integer values. The basic pseudo code for the enhancement cost of a piece of equipment at a particular fail stack:

avg_num_attempts = 1.0 / suc_rate
avg_num_fails = avg_num_attempts - 1

fails_cost = avg_num_fails * repair_cost
total_cost = fails_cost + cum_fs_cost + (black_stone_cost * avg_num_attempts)

Here we have:

Notice here that the price of the fail stack is included in the success rate. This may be obvious, but it is there so the max fail stack isn't chosen every time. Here we have cumulative fail stack cost compared to repair cost.

What about gear that drops an enhancement level upon failure:

backtrack_start = lvl_map['TRI']

for i in range(0, 3):
    this_pos = backtrack_start + i
    prev_cost = min(total_cost[this_pos - 1])
    new_avg_attempts = 1.0 / suc_rate[this_pos - 1]
    new_num_fails = new_avg_attempts - 1
    new_fail_cost = repair_cost + prev_cost 
    total_cost[this_pos] = (new_num_fails * new_fail_cost) + (black_stone_costs[this_pos] * new_avg_attempts) + cum_fs_cost

This is just a loop starting at \"TRI\" which is \"DUO\" -> \"TRI\" that factors in the previous gear cost upon failure. The cost formula is the came as above

Here we have:

Notice that this method needs to be different for accessories and the like.

Calculating Enhancement Strategy

This needs an update. The previous explination does not represent the code anymore.

Calculating Enhancement Probability

A quick note on the \"Strategy\" tab in the bottom right list of enhancing gear there is a probability on the far end of the list. This probability is the chance of at least one success in n trials, where n is the average number or trails to success. This probability helps determine a reasonable amount of fail stacks because it gives the confidence that attempting the average number of trials will result in success.

Files

Below are file definitions or descriptions of some of the files that this project uses.

*.log Files

Log files simply contain debug information that the program has output. Typically this file should not be altered by the user. These files should not be copied from one machine to another or it could make debugging the application harder. There is no maximum file size for these so if they get to big they can be deleted. That should not be a problem though

settings.json

As the name would suggest this file is a JSON string that contains the programs settings. They can be safely edited with a text editor; be careful. If you really screwed up the settings file it can just be deleted. The next time the program runs it will simply create a new settings file with default values. The settings file is auto saved when the program exits unless it crashes. This can be revised later. The settings file can be found in the user %APPDATA% path under a folder named after this program. A command line parameter should be used to supply the default loaded settings file in the future. Below are a description of the fields:

Parameter Default Value Description
fail_stackers [] List of gear objects on the fail stacking list
enhance_me [] List of gear objects on the enhancement list
r_fail_stackers [] List of gear objects removed from the fail stacking list
r_enhance_me [] List of gear objects removed from the enhancement list
fail_stackers_count {} Dictionary of indexes pointing to fail stacking items that specifies their count. If the value is encapsulated in a list it is in the removed list.
fs_exceptions {} Dictionary of fail stack indexes that corrispond to indexes of fail stack gear items
cost_conc_w 2590000 Cost of Conc stone (Weapon) (silver)
cost_conc_a 1470000 Cost of Conc stone (Armor) (silver)
cost_bs_w 225000 Cost of Black Stone stone (Weapon) (silver)
cost_bs_a 220000 Cost of Black Stone stone (Armor) (silver)
cost_cron 2000000 Cost of cron stone (silver)
cost_cleanse 100000 Cost to clease gear from +15 to +14
cost_meme 1740000 Cost of Memory Fragment
alts [[]] List of lists of size 3 [img path, name, fail stack level ]
valks [] List of Valks enhance items (values)
quest_fs_inc 0 Bonus fail stacks from quests like the Bartali Adventure log
central_market_tax_rate 0.65 Tax rate on central market. This should probably not be changed
value_pack_p 0.3 Percentage of after tax value a Value Pack adds to sale balance
is_value_pack True Is a Value Pack active
merch_ring 0.05 Percentage of after tax value a Rich Merchant Ring adds to sale balance
is_merch_ring False Is a Rich Merchant Ring active
_version None Version information for change tracking

Gear Object

The gear object is a json string object that is encapsulated in the settings file.

Parameter Description
name A name for the piece of gear.
cost Cost of the base item, or cost of resetting an item after a fail attempt.
fail_dura_cost For repairable items this is the amount of durability lost in failure.
enhance_lvl String that denotes the level of enhancement, like \"PRI\"
gear_type Corresponds to a file in the Data folder that describes it's enhancement levels and probabilities.
sale_balance A balance that is added to the value of an item when fail stacking on enhancement success. For example sale price of TET minus price of DUO if purchased at DUO.