User guide All recipes Tutorial Function reference Open playground

Blades in the Dark — action roll

At the table

Blades in the Dark resolves risky actions with d6 pools. Roll all your dice at once and use only the highest face—everything else is ignored unless you need a critical (see below).

Highest dieWhat happens
1–3Bad outcome. Things go wrong: you likely miss your goal and the GM brings extra trouble.
4–5Partial success. You get what you were after, but with a cost—harm, heat, reduced effect, a hard choice, or similar.
6Full success. It works; things go as you hoped.
Two or more 6sCritical success. As a full success, plus an extra edge (position, effect, or another boon depending on the move).

Building the pool: Take a number of dice equal to a rating—usually a player’s action (Prowl, Skirmish, Attune, and the rest) or sometimes crew Tier, a situation bonus, or a push. Ratings are often one to four dice in play. Even one die is respectable: you have a 50% chance of partial success or better (4+ on that single die).

Zero or negative dice: If you would roll no dice (or fewer than zero after modifiers), roll 2d6 and use the lower die only—the desperate position. You still use the same outcome bands, but you cannot roll a critical from a desperate roll (at most one 6 counts).

Most specialized rolls in the book (resistance, group actions, fortune rolls, etc.) are variations on this core chart. When you are learning, you can always fall back to “roll the pool, read the highest die” and look up the exact twist later.

Why partial success dominates: On typical pools, 4/5 is the most common band—characters often succeed, but rarely cleanly. That matches the game’s pitch: scrappy criminals in too deep. Complications are where play gets interesting; the dice keep nudging you there on purpose.

Try it

In the playground, open this recipe in the playground and click Run. Output entries 0d through 7d give exact odds for each outcome band. Pool sizes 1d–4d are what you see most often at the table; 0d is the desperate case. 5d7d are included so you can see how crit-heavy larger pools behave.

The script

Scale = scale().step("BAD").step("MESSY").step("CLEAN").step("CRITICAL")

def blades_pool(faces):
    high = max(faces)
    if high == 6:
        if len([f for f in faces if f == 6]) >= 2:
            return 3
        return 2
    if high >= 4:
        return 1
    return 0

def code_label(c):
    return ["BAD", "MESSY", "CLEAN", "CRITICAL"][c]

def desperate_label(n):
    if n == 6:
        return "CLEAN"
    if n >= 4:
        return "MESSY"
    return "BAD"

output("0d", classify(keep_lowest(2, 6, 1), Scale, desperate_label))
for dice in range(1, 8):
    codes = pool_map(dice_pool(dice, 6), blades_pool)
    output("{}d".format(dice), classify(codes, Scale, code_label))

0d · Outcomes

outcome%fracX/36
BAD75.03/427
MESSY22.22/98
CLEAN2.781/361
CRITICAL0.0000

1d · Outcomes

outcome%fracX/36
BAD50.01/218
MESSY33.31/312
CLEAN16.71/66
CRITICAL0.0000

2d · Outcomes

outcome%fracX/36
BAD25.01/49
MESSY44.44/916
CLEAN27.85/1810
CRITICAL2.781/361

3d · Outcomes

outcome%fracX/36
BAD12.51/84
MESSY45.449/10816
CLEAN34.725/7212
CRITICAL7.412/273

4d · Outcomes

outcome%fracX/36
BAD6.251/162
MESSY42.034/8115
CLEAN38.6125/32414
CRITICAL13.219/1445

5d · Outcomes

outcome%fracX/36
BAD3.121/321
MESSY37.1964/260113
CLEAN40.2428/106514
CRITICAL19.6115/5867

6d · Outcomes

outcome%fracX/36
BAD1.561/641
MESSY31.9386/120911
CLEAN40.2428/106514
CRITICAL26.3209/7949

7d · Outcomes

outcome%fracX/36
BAD0.781/1280
MESSY27.1220/81110
CLEAN39.1345/88314
CRITICAL33.0211/63912