Creating balanced combat encounters can be surprisingly difficult,
especially for newer Dungeon/Game Masters (DMs / GMs). If you want to
use the Dungeon Master’s Guide (DMG) you need to consult several
interrelated tables for each encounter. To help other newbies–like
myself!–dndR
includes a handful of functions aimed at
simplifying the encounter balancing process.
Encounter Creation
If you’d rather avoid consulting the DMG at all, the
encounter_creator
function may be a valuable tool for you
to consider. This function requires the average level of all player
characters in the party, the number of players in the party, and how
difficult you’d like to make the encounter (allowable answers are
‘easy’, ‘medium’, ‘hard’, and ‘deadly’). Once you’ve provided this
information, it will automatically select one tougher creature and as
many other creatures as possible without making the encounter more
difficult than you specified.
The function returns a dataframe with one row for each unique experience point (XP) value of the selected creatures. A separate column indicates the number of creatures worth that amount of XP that should be selected in the encounter. The function also returns the “pool” of XP available for the encounter and the realized XP “cost” of the chosen creatures. More detail is provided on this later in this vignette but for now keep in mind that there is an optimization step being done under the hood so this function will not always return identical results. I suggest running the function more than once until you are satisfied with the results!
# Pick a hard set of creatures for a four-person party of 3rd level characters
dndR::encounter_creator(party_level = 3, party_size = 4, difficulty = "hard")
#> # A tibble: 4 × 4
#> creature_xp creature_count encounter_xp_pool encounter_xp_cost
#> <dbl> <int> <dbl> <dbl>
#> 1 200 1 1112 1100
#> 2 50 3 1112 1100
#> 3 25 2 1112 1100
#> 4 10 4 1112 1100
After this function has identified the number and XP value of the
creatures in this encounter, you may consider using other
dndR
functions to identify specific creatures (e.g.,
creature_list
, etc.) or use your favorite source book /
homebrew to decide on particular creatures.
XP Balancing
This may be more detail than you require but a small description of how experience points are used to balance encounters (in and outside of this R package) will be useful context for some of the other encounter balancing tools described below. In essence, the difficulty of a combat encounter in Dungeons and Dragons is affected by four things:
- Level of characters
- Number of characters in the party
- How difficult the GM wants to make the encounter
- How many enemy creatures are included
The first three go into the “pool” of available experience points to spend on a given encounter. However, the number of creatures can dramatically influence how difficult an encounter is even if their total XP value is the same (e.g., a fight against one 1000 XP creature versus against four 250 XP creatures). This realized XP “cost” is calculated by applying a multiplier to the total rules-as-written XP value of all monsters in the encounter. This multiplier is affected by the number of enemy creatures as well as the number of player characters.
The DMG handles the total XP pool and the XP cost in two separate
tables. In order to balance an encounter you need to carefully consult
both of them. Often this involves iterative testing of which number and
combination of creatures is below the available pool after applying the
relevant multiplier. dndR
provides two functions to handle
this instead: xp_pool
and xp_cost
.
xp_pool
returns the amount of XP the GM can ‘spend’ on
monsters in a given encounter to ensure the difficulty is as desired
based on the three factors identified above. You may note that it has
identical arguments to encounter_creator
–this is because
that function relies on both of these functions ‘under the hood.’
# How much XP is available for a hard encounter for the four-person, 3rd level party?
dndR::xp_pool(party_level = 3, party_size = 4, difficulty = "hard")
#> [1] 1112
Once you have that in mind, you can make a note of that number and
then use xp_cost
repeatedly until you find the highest
realized XP cost that will still fall beneath that threshold.
# Identify 'realized' XP of two monsters worth a total of 1,000 XP versus our party
dndR::xp_cost(monster_xp = 1000, monster_count = 2, party_size = 4)
#> [1] 1500
Even though the total XP value of the creatures is beneath the
threshold identified by xp_pool
it is dramatically higher
after the appropriate multipliers are applied. Using
xp_pool
alone would risk creating a much harder encounter
than you intended. In fact, in this case, that realized XP value is
actually appropriate for a “deadly” encounter!
While encounter_creator
is meant to avoid needing to use
these helper functions, you can of course use these if you’d rather take
a middle path between relying entirely on this package versus relying
entirely on the DMG.