D&D 5e Battle simulator


Suggestions

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 "beastiary" table  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 a minute, 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.

Encounter setup

Option A: add default combattant from list

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.

Option B: add combattant as a raw string

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).


Option C: build combattant

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:


Lineup





Simulation Results

More

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.

Motives

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.

Workings

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.

Assumptions

There are may factors involved, one of which is strategy, which is encoded here with a set of assumptions.

  • One targets an alive enemy with lowest hp (tag: "weakest"). Alternatives modes are random or that with highest average damage (tag: "fiercesomest")
  • One heals only when there is no chance of wastage and one heals the most wonded character
  • One uses net-throwing, grappling and other fancy moves only when there is turn economy — that is, one's team outnumbers the other.
  • If there is turn economy and one is taking all the damage, one dodges.
  • Some minor rules that make no difference

Gridlessness

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-list

Spell budgeting troubles players, therefore there is not much spellcasting, bar for a handful of cantrips.

Future work

  • Add more fields for custom creatures (the sole reason why there are not more is the layout needs changing).
  • Add more creatures to the excel sheet, especially PCs.
  • Allow user submissions.
  • Get creature info on line-up from server and add option to delete specific ones.
  • Double check with the PHB and MM some parts (TODO comments in code).
  • Introduce machine learning to the code, so that it accepts more spells and can work on a grid.