SEEN ALSO: Description of battle simulator and some analysis, the GitHub code for the encounter simulator, analysis of dice equivalence
Who would win in a battle of 15 peasants against a hill giant? In Dungeons and Dragons it is quite hard to predict the difficulty of an encounter. Unlike previous editions, in fifth edition the challenge is based on XP, while the challenge rating (CR) limits how nasty the monster can get. However, it isn't quite right.
In order to find
out what the victory probabilities are as various parameters are changed
I wrote a Python script to simulate D&D battles.
The script can be found in my GitHub repository:
https://github.com/matteoferla/tangents/blob/master/DnD_Battler.py
Details
It
doesn't operate on a grid and instead simply assumed everyone is next
to everyone. Adding a grid would be easy, but making the various
creatures abide by a reasonable strategy would be very hard.
There already is a fair amount of strategy already in the code adding
more may require Bayesian tricks.
One such strategic choice is who
to target. D&D battles have a peculiarity in that one isn't really
supposed to know the game stats of other PCs and monsters, yet one does
—prior knowledge or guesswork during the battle. This simulator can
either target randomly or, by default, target the creature with the
lowest HP. This results in "squishies" getting mercilessly owned in the
first few rounds, which is what may happen for squishy monsters, but not
squishy PCs, because they generally cower in the rear, while the DM
kindly focuses on the tanks in melee range.
In terms of strategy,
the code determine if a team has a better turn economy and therefore
makes the weakest character (target) dodge and characters with a net to
use that —both actions do no damage, but stop the monster's action.
The
script does not do spellcasting, except for power word heal and
barkskin, nor does it implement several class features as that
would require a lot more code. Currently, barbarians can't lose range,
for example. Nevertheless, it is very useful for testing hypotheses.
For example let's see how much of a challenge stuff is for 4 level 3 heroes.
For them hard is above .9k and deadly above 1.6k corrected xp.
4 generic heroes vs. 1 ankylosaurus (700 xp): Medium encounter
hero = Creature("hero", "good",
ac=16, hp=18, #bog standard shielded leather-clad level 3. attack_parameters=[['longsword', 4, 2, 8]])
This has a 61% survival.
anky=Creature("Ankylosaurus", ac=15, hp=68, alignment='evil', attack_parameters=[['tail',7,4,6,6,6,6]], log="CR 3 700 XP")
The generic "hero" above is so generic, he is truly underpowered. Instead, 2 lore bards and 2 generic tanks have a 97% win chance. The characters could be optimised better, but this is a safe lineup:
bard = Creature("Doppelbard", "good", hp=18, ac=16, healing_spells=6, healing_bonus=3, healing_dice=4, initiative_bonus=2, attack_parameters=[['rapier', 4, 2, 8]])
generic_tank = Creature("generic tank", "good", hp=20, ac=17, initiative_bonus=2, attack_parameters=[['great sword', 5, 3, 6, 6]])
polar= Creature("polar bear",'evil', ac=12, hp=42, attack_parameters=[['bite',7,5,8],['claw',7,5,6,6]])
2 polar bears are a Hard encounter (1.3k) and the heroes will have a 52% chance. 3 polar bears (2.7k)? 5% chance. However, when I use the guestimated stats of the party I currently play with I get a whopping 80% (druid, barbarian, bard, generic_tank).
druid = Creature("Twice Brown Bear Druid",
hp=86, ac=11, alignment="good",
attack_parameters=[['claw', 5, 4, 8], ['bite', 5, 4, 6, 6]], ability=[0, 0, 0, 0, 3, 0],
sc_ability='wis', buff='cast_barkskin', buff_spells=4,
log='The hp is bear x 2 + druid')
barbarian = Creature("Barbarian",
ac=18, hp=66, alignment="good",
attack_parameters=[['greatsword', 4, 1, 6, 6], ['frenzy greatsword', 4, 1, 6, 6]],
log="hp is doubled due to resistance")
bard = Creature("Bard", "good", hp=18, ac=18, initiative_bonus=2, healing_spells=6, healing_bonus=3, healing_dice=4, attack_parameters=[['rapier', 4, 2, 8]], alt_attack=['net', 4, 0, 0])
2 ankylosauruses? 2.1k. 26% for the generic mark 2 party, 92% for the actual party.
3 ankylosauruses? 4.2k. 8‰ and 38%.
In other words, the maths is for a rather rubbish party. For a balanced party is seems like a safe bet to double the challenge.
EDIT: Further thoughts and (inconclusive) analyses:
http://squidonius.blogspot.co.nz/2015/04/d-battle-simulator-part-2.html
EDIT: Further thoughts and (inconclusive) analyses:
http://squidonius.blogspot.co.nz/2015/04/d-battle-simulator-part-2.html
No comments:
Post a Comment