Later this week, I’m going to be GM-ing my first session of *Blades in the Dark*, a role-playing game designed by John Harper. We’ve already assembled a crew of scoundrels in Session 0 and set the first score. Unlike most of the other games I’ve run, I’ve never played *Blades in the Dark*, I’ve only seen it on YouTube (my fave so far is Jared Logan’s Steam of Blood x Glass Cannon play Blades in the Dark!).

**Action roll**

In *Blades*, when a player attempts an action, they roll a number of six-sided dice and take the highest result. The number of dice rolled is equal to their action rating (a number between 0 and 4 inclusive) plus modifiers (0 to 2 dice). The details aren’t important for the probability calculations. If the total of the action rating and modifiers is 0 dice, the player rolls two dice and takes the worst. This is sort of like disadvantage and (super-)advantage in *Dungeons & Dragons 5e*.

A result of 1-3 is a failure with a consequence, a result of 4-5 is a success with a consequence, and a result of 6 is an unmitigated success without a consequence. If there are more than two 6s in the result, it’s a success with a benefit (aka a “critical” success).

The GM doesn’t roll. In a combat situation, you can think of the player roll encapsulating a turn of the player attacking and the opponent(s) counter-attacking. On a result of 4-6, the player hits, on a roll of 1-5, the opponent hits back or the situation becomes more desperate in some other way like the character being disarmed or losing their footing. On a critical result (two or more 6s in the roll), the player succeeds with a benefit, perhaps cornering the opponent away from their flunkies.

**Resistance roll**

When a player suffers a consequence, they can resist it. To do so, they gather a pool of dice for the resistance roll and spend an amount of stress equal to six minus the highest result. Again, unless they have zero dice in the pool, in which case they can roll two dice and take the worst. If the player rolls a 6, the character takes no stress. If they roll a 1, the character takes 5 stress (which would very likely take them out of the action). If the player has multiple dice and rolls two or more 6s, they actually reduce 1 stress.

For resistance rolls, the value between 1 and 6 matters, not just whether it’s in 1-3, in 4-5, equal to 6, or if there are two 6s.

**Probabilities**

Resistance rolls are rank statistics for pools of six-sided dice. Action rolls just group those. Plus a little sugar on top for criticals. We could do this the hard way (combinatorics) or we could do this the easy way. That decision was easy.

Here’s a plot of the results for action rolls, with dice pool size on the x-axis and line plots of results 1-3 (fail plus a complication), 4-5 (succeed with complication), 6 (succeed) and 66 (critical success with benefit). This is based on 10m simulations.

You can find a similar plot from Jasper Flick on AnyDice, in the short note Blades in the Dark.

I find the graph pretty hard to scan, so here’s a table in ASCII format, which also includes the resistance roll probabilities. The 66 result (at least two 6 rolls in the dice pool) is a possibility for both a resistance roll and an action roll. Both decimal places should be correct given the 10M simulations.

DICE RESISTANCE ACTION BOTH
DICE 1 2 3 4 5 6 1-3 4-5 6 66
---- ---------------------------- ------------- ----
0d .36 .25 .19 .14 .08 .03 .75 .22 .03 .00
1d .17 .17 .17 .17 .17 .17 .50 .33 .17 .00
2d .03 .08 .14 .19 .25 .28 .25 .44 .28 .03
3d .01 .03 .09 .17 .29 .35 .13 .45 .35 .07
4d .00 .01 .05 .14 .29 .39 .06 .42 .39 .13
5d .00 .00 .03 .10 .27 .40 .03 .37 .40 .20
6d .00 .00 .01 .07 .25 .40 .02 .32 .40 .26
7d .00 .00 .01 .05 .22 .39 .01 .27 .39 .33
8d .00 .00 .00 .03 .19 .38 .00 .23 .38 .39

One could go for more precision with more simulations, or resort to working them all out combinatorially.

**The hard way**

The hard way is a bunch of combinatorics. These aren’t too bad because of the way the dice are organized. For the highest value of throwing N dice, the probability that a value is less than or equal to k is one minus the probability that a single die is greater than k raised to the N-th power. It’s just that there are a lot of cells in the table. And then the differences would be required. Too error prone for me. Criticals can be handled Sherlock Holmes style by subtracting the probability of a non-critical from one. A non-critical either has no sixes (5^N possibilities with N dice) or exactly one six ((6 choose 1) * 5^(N – 1)). That’s not so bad. But there are a lot of entries in the table. So let’s just simulate.

**Edit: Cumulative Probability Tables**

I really wanted the cumulative probability tables of a result or better (I suppose I could’ve also done it as result or worse). I posted these first on the Blades in the Dark forum. It uses Discourse, just like Stan’s forum.

**Action Rolls**

Here’s the cumulative probabilities for action rolls.

And here’s the table of cumulative probabilities for action rolls, with 66 representing a critical, 6 a full success, and 4-5 a partial success:

ACTION ROLLS, CUMULATIVE
probability of result or better
dice 4-5+ 6+ 66
0 0.250 0.028 0.000
1 0.500 0.167 0.000
2 0.750 0.306 0.028
3 0.875 0.421 0.074
4 0.938 0.518 0.132
5 0.969 0.598 0.196
6 0.984 0.665 0.263
7 0.992 0.721 0.330
8 0.996 0.767 0.395

**Resistance Rolls**

And here are the basic probabilities for resistance rolls.

Here’s the table for stress probabilities based on dice pool size

RESISTANCE ROLLS
Probability of Stress
Dice 5 4 3 2 1 0 -1
0 .31 .25 .19 .14 .08 .03 .00
1 .17 .17 .17 .17 .17 .17 .00
2 .03 .08 .14 .19 .25 .28 .03
3 .00 .03 .09 .17 .28 .35 .07
4 .00 .01 .05 .13 .28 .39 .13
5 .00 .00 .03 .10 .27 .40 .20
6 .00 .00 .01 .07 .25 .40 .26
7 .00 .00 .01 .05 .22 .39 .33
8 .00 .00 .00 .03 .19 .37 .40

Here’s the plot for the cumulative probabilities for resistance rolls.

Here’s the table of cumulative resistance rolls.

RESISTANCE ROLLS, CUMULATIVE
Probability of Stress or Less
Dice 5 4 3 2 1 0 -1
0 1.00 .69 .44 .25 .11 .03 .00
1 1.00 .83 .67 .50 .33 .17 .00
2 1.00 .97 .89 .75 .56 .31 .03
3 1.00 1.00 .96 .87 .70 .42 .07
4 1.00 1.00 .99 .94 .80 .52 .13
5 1.00 1.00 1.00 .97 .87 .60 .20
6 1.00 1.00 1.00 .98 .91 .67 .26
7 1.00 1.00 1.00 .99 .94 .72 .33
8 1.00 1.00 1.00 1.00 .96 .77 .40

For example, with 4 dice (the typical upper bound for resistance rolls), there’s an 80% chance that the character takes 1, 0, or -1 stress, and 52% chance they take 0 or -1 stress. With 0 dice, there’s a better than 50-50 chance of taking 4 or more stress because the probability of 3 or less stress is only 44%.

Finally, here’s the R code for the resistance and cumulative resistance.

# row = dice, col = c(1:6, 66)
resist <- matrix(0, nrow = 8, ncol = 7)
resist[1, 1:6] <- 1/6
for (d in 2:8) {
for (result in 1:5) {
resist[d, result] <-
sum(resist[d - 1, 1:result]) * 1/6 +
resist[d - 1, result] * (result -1) / 6
}
resist[d, 6] <- sum(resist[d - 1, 1:5]) * 1/6 +
sum(resist[d - 1, 6]) * 5/6
resist[d, 7] <- resist[d - 1, 7] + resist[d - 1, 6] * 1/6
}
cumulative_resist <- resist # just for sizing
for (d in 1:8) {
for (result in 1:7) {
cumulative_resist[d, result] <- sum(resist[d, result:7])
}
}
library('reshape')
library('ggplot2')
zero_dice_probs <- c(11, 9, 7, 5, 3, 1, 0) / 36
zero_dice_cumulative_probs <- zero_dice_probs
for (n in 1:7)
zero_dice_cumulative_probs[n] <- sum(zero_dice_probs[n:7])
z <- melt(cumulative_resist) # X1 = dice, X2 = result, value = prob
stress <- 6 - z$X2
df <- data.frame(dice = z$X1, stress = as.factor(stress), prob = z$value)
df <- rbind(df, data.frame(dice = rep(0, 7), stress = as.factor(6 - 1:7), prob = zero_dice_cumulative_probs))
cumulative_plot <- ggplot(df, aes(x = dice, y = prob,
colour = stress, group = stress)) +
geom_line() + geom_point() +
xlab("dice for resistance roll") +
ylab("prob of stress or less") +
scale_x_continuous(breaks = 0:8)
cumulative_plot
ggsave('cumulative-resistance.jpg', plot = cumulative_plot, width = 5, height = 4)
z2 <- melt(resist) # X1 = dice, X2 = result, value = prob
stress2 <- 6 - z2$X2
df2 <- data.frame(dice = z2$X1, stress = as.factor(stress2), prob = z2$value)
df2 <- rbind(df2, data.frame(dice = rep(0, 7), stress = as.factor(6 - 1:7),
prob = zero_dice_probs))
plot <- ggplot(df2, aes(x = dice, y = prob,
colour = stress, group = stress)) +
geom_line() + geom_point() +
xlab("dice for resistance roll") +
ylab("prob of stress") +
scale_x_continuous(breaks = 0:8)
plot
ggsave('resistance.jpg', plot = plot, width = 5, height = 4)