T HIS online tool calculates the victory probabilities in a D&D encounter. It relies on a python script , which simulates an encounter 1,000 times for statistical accuracy. The characters can be inputted in a variety of ways ranging from a preset to an incomplete list of parameters, which the code will either calculate from others or default to the value of a commoner. The presets are based on a monster manual table ("beastiary.csv") it references a series of assumptions (tactical decisions) detailed in the Workings section and in more technical detail in the documetation of the code . For example, due to the complexity of the tactical decisions involved, which human players often fail at, the encounters are performed with the assumption that everyone borders everyone. The script is 5e focused in the way it handles crits, conditions, advatages and disadvantages.
Here are provided three ways to input the list of
combattants. The first is picking creatures from the beastiary table, the second relies on a set of
hardcoded creatures, many which have not yet been moved to the beastiary table and the third allows
custom creatures to be added. The latter is a tad limited: for example nets, barkskin and rage
cannot be added despite the fact that the presets "netsharpshooter", "druid" and "barbarian" use them.
NB. The program times out after 10 seconds, therefore if the battles are lengthy (e.g. one good
tarrasques vs. one evil tarrasques) it will have less than the default 1,000 rounds.
Pick a default creature, these are present in a csv file — the original was compiled by Jeff Fox and can be found on my GitHub page.
Here one can add a raw json string (details. Note that there are more names than in the list above as the hardcoded creatures have not been moved to the beastiary spreadsheet (examples).
Build from stats. For more options, such as buffs and nets or building from ability scores up, run the python script or ask the author, who can happily add a default. Apart from the name, all these parameters are optional (default is commoner).
Name: | |
Base creature: | |
Alignment: | |
HP: | |
AC: | |
Initiative bonus: | |
attack parameters: | |
Number of healing spells: | |
healing dice: | |
healing bonus: | |
Str: | |
Dex: | |
Con: | |
Int: | |
Wis: | |
Cha: |
D&D is an amazing game, but encounters can get tedious when they are not a challenge. Conversely, too much of a challenge leads to a dissapointing series of GM fiats or, worse, a total party kill, a scenario to avoid as it is disappointing for all or worse. Therefore a correct balance is needed. As a result the GM guide has a table that can be used to calculate how hard an encounter is, which is not overly accurate. I have been in too many encounters that on paper should have been deadly, while on the table have been a walk in the park. The reason for this is that a single value cannot represent the strength of a party.
Consequently, to address and analyse this and to trial new weapons, I wrote a python script to simulate battles.
The script empirically simulates a specified number of repeats of an encounter (i.e. 1,000 times) in order to gain the probability of victory of defeat. damage and hp are not the sole factor in determining how an encounter may swing, therefore it may be impossible to predict with calculus, hence the simulation.
There are may factors involved, one of which is strategy, which is encoded here with a set of assumptions.
This code does not take into account space. That means it assumes tactics on a grid don't matter: this is clearly wrong, but it is a lesser evil that encoding a lot of behavioral rules that are not obeyed in game —every group has a muchkin who will dive infront of a wizard's AoE just to kill stuff— or rules to solve non-trivial situations —player takes a 30 minute turn. Thanks to the many iterations, machine learning could be adopted making it a function minimisation problem, but it is overkill as no player is such a master strategist.
Spell-budgeting troubles players, therefore there is not much spellcasting, bar for a handful of cantrips.
This is the webserver version of a python script that is a lot more complex and customisable, such as running multiple analyses changing on parameter or running a single button and getting the verbose description of the battle. For technical reasons, the simulations are limited to 1,000 battles (encounters) and no custom spells are allowed as spells are encoded as method references which might lead to vulnerability.
See GitHub for more.