I am joining a D&D group. To generate each ability score, the DM has us roll 4d6, reroll any 1 or 2, and then drop the lowest die. If the reroll is a 1 or 2, then reroll again and again until the result is 3 or higher.

I am curious about the distribution, and wonder if AnyDice could do it. How can I calculate the distribution of this ability score generation method in AnyDice?

  • \$\begingroup\$ Am I correct in assuming your DM was using this as an ability score generation method? \$\endgroup\$
    – V2Blast
    Aug 3, 2019 at 5:57

4 Answers 4


Assuming you reroll each d6 until it doesn't show a 1 or 2 anymore, the easiest way to model that constraint is as a custom die, d{3..6}. This represents a uniform die that can only roll the values 3, 4, 5, and 6. (Side note: at the table, you can substitute d4+2 and get the same result, if you want to roll once without rerolls.)

To keep only a subset of dice, use the functions highest or lowest.

Thus, we can show "4d6, reroll any 1s and 2s, then drop the lowest die" as:

output [highest 3 of 4d{3..6}]

  • 6
    \$\begingroup\$ If you're ignoring the rolls of 1 or 2, then rolling the {3, 4, 5, 6} die once is functionally identical. \$\endgroup\$
    – Exal
    Feb 10, 2018 at 11:03
  • 2
    \$\begingroup\$ Why is d{3..6} "the easiest way to model that constraint" when d4+2 exists? \$\endgroup\$
    – Zachiel
    Feb 11, 2018 at 13:05
  • 1
    \$\begingroup\$ @Zachiel: Because to roll more than one of your d4+2 dice, you have to use awkward syntax like 4d(d4+2). Also, it doesn't generalize to things like "roll 4d6 and reroll any ones and threes", whereas this is easy to express as 4d{2,4..6}. \$\endgroup\$ Feb 19, 2018 at 23:21
  • \$\begingroup\$ @IlmariKaronen I agree on the "if we had to reroll any ones and threes" part but... 4d4+8 \$\endgroup\$
    – Zachiel
    Feb 21, 2018 at 19:38
  • 2
    \$\begingroup\$ @Zachiel Because I personally find it easier to demonstrate I'm performing the right steps in the right order (roll, reroll, then apply the "keep" function) when I don't really transform/reorder the flow in any way. I couldn't find a clean way to do it with d4 without something like "4d4k3 + 6." \$\endgroup\$
    – Alex P
    Feb 21, 2018 at 21:06

If you keep rolling until there are no 1s or 2s

This is the same as rolling 4 4-sided dice marked 3-6. So:

output [highest 3 of 4d{3..6}]

If you only reroll once

Think about the second dice you roll on a 1-2, this will give you a result of 1-6. Now imagine that you do a reroll if you roll a 3-6 but all the faces of that die are the same and the same as the number you rolled. Now combine all these "rerolls" into one big dice with 36 sides, it will have 8 faces marked 3-6 and 2 faces marked 1-2. We can divide the number of faces by 2 to give an equivalent 18-sided die. So:

output [highest 3 of 4d{{3..6}:4, {1..2}}]

  • \$\begingroup\$ I think this formula is a bit off. It's using the 3..6 4 times (:4) effectively creating 16 faces marked 3-6 instead of 8 faces. Not quite the exact same example, but here is some stats with various re-rolls anydice.com/program/18106 So the re-roll once equation should be one of these output [highest 3 of 4d{{3..6}:2, {1..2}}] OR output [highest 3 of 4d{{3..6}, {1..6}}] \$\endgroup\$
    – Snekse
    Oct 11, 2019 at 19:23
  • \$\begingroup\$ @Snekse The 8 faces of 3-6 are 8 faces each: 32 altogether. Divide by 2 gives 16. The formula is correct. \$\endgroup\$
    – Dale M
    Aug 23, 2023 at 3:24

Rolling a d6 and then rerolling all 1s and 2s every time they show up is functionally identical to rolling a d4, then adding 2.

The same way, rolling 1d4+2 four times and taking the best 3 is the same as rolling 1d4 four times and taking the best 3, then adding 6 (the +2 of the three best dice)

The following formula is a little bit shorter than the one proposed by AlexP, and, since it avoids using d{3..6}, it is easier to read even for someone who's not familiar with AnyDice's syntax.

output [highest 3 of 4d4]+6

The general solution for rerolling once is to use a helper function like this:

function: ROLL:n reroll BAD:s as REROLL:d {
  if ROLL = BAD { result: REROLL }
  result: ROLL

You can assign the result of this function to a custom die, and then roll as many of them as you want:

X: [d6 reroll {1,2} as d6]
output [highest 3 of 4dX]

For re-rolling an unlimited number of times, we can use a trick from this answer by Carcer and pass the "empty die" d{} as the REROLL parameter, like this:

Y: [d6 reroll {1,2} as d{}]
output [highest 3 of 4dY]

When summing up the results of the function, AnyDice will simply ignore these empty dice, as if the rolls that resulted in them had never happened.

However, for simple dice like a single d6, it's also possible to just directly define a custom die that excludes the faces to be rerolled, as described in Alex P's and Dale M's answers:

output [highest 3 of 4d{3..6}]

The general reroll trick is more useful in cases where the input "die" to be rerolled is already the result of some complex rolling procedure, so that the probabilities of different rolls are not all the same (like they are with a simple d6).

For example, if you wanted to calculate, say, the distribution of ability scores obtained by rolling 4d6, dropping the lowest die and then rerolling the whole score until it's at least 10, you could use this code:

output [[highest 3 of 4d6] reroll {3..9} as d{}]

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .