I'm trying to model average stat distributions for characters based on what a friend sent me:

Balanced Stat Roll

Roll 4d6 drop lowest five times. Count them together and deduct the total from 72. The last number is the sixth ability score, provided it's greater than 3 and less than 19, otherwise re roll the set.

Essentially, I want to take the total of 5 "4d6 drop lowest" rolls, and produce the sixth roll by subtracting that from 72. I've been able to get that far using the below code, modified from the looped function https://anydice.com/articles/4d6-drop-lowest/, resulting in the below:

ABIL: 5 d [highest 3 of 4d6]
loop P over {1..5} {
 output P @ ABIL named "Ability [P]"

output 72 - {1..5}@ABIL named "Ability 6"

However the output for "Ability 6" clearly isn't bound to the normal 3-18 distribution I want, which invalidates all of the outputs by extension as the whole group has to be tossed out if the 6th total is less than 3 or greater than 18.

I've tried a number of ways to create a function that binds the output of everything to whether the calculation of the 6th ability is within that range, but I keep running into issues as I'm not well versed in AnyDice at all. Trying to include the loop in the function results in errors with the output part of the loop no matter how I try to reformat it, and I'm not exactly sure how else to proceed. Any help would be appreciated.

Here's a link to the code above in AnyDice for visualization, you can see that "Ability 6" generates a probability range of -18 to 57. https://anydice.com/program/348c7


2 Answers 2


You can return an empty die d{} from a function to reject results. They will be removed from the probability space, which is equivalent to rerolling such results without limit, or conditioning against such results.

While we're at it, we can do an explicit sort of the five rolled scores and the synthetic sixth to get an overall ranking.

function: balanced RANK:n from FIVE:s {
 if SIXTH < 3 | SIXTH > 18 {
  result: d{}
 result: RANK @ [sort {FIVE, SIXTH}]

loop RANK over {1..6} {
 output [balanced RANK from 5d[highest 3 of 4d6]]


Side note: This script keeps cases where the last score is a 3, as per the second half of your question. However, as written in your linked image, a 3 on the last score is also rejected. I'm unsure if this was intentional; if it was, just adjust SIXTH < 3 to SIXTH < 4.

  • 1
    \$\begingroup\$ Thank you so much, this is fantastic! \$\endgroup\$
    – Cycanis
    Commented Feb 8 at 14:47
  • 1
    \$\begingroup\$ I think I had the beginnings of this in my attempts at creating the function on my own, but I wasn't sure how to apply the loop to the function. The if statement you've created is also inverse from what I was trying to create, and I didn't make it far enough with getting the program to work for it to occur to use an empty die to cull the invalid results. This is a lot more elegant that what I probably would've reached on my own even if I had known how to apply this, so thank you again! \$\endgroup\$
    – Cycanis
    Commented Feb 8 at 14:58

HighDiceRoller has already posted a very good AnyDice program for modelling this stat rolling method, so let me just amend their excellent answer with some analysis of the results.

Comparing the output of HighDiceRoller's program to a standard 6 stat array roll, we can see that the OP's "balanced method" tends to make:

  • the highest stat slightly higher and slightly less swingy (avg. 15.89 ± 1.22 vs. standard 15.66 ± 1.43),
  • the lowest stat noticeably lower (by over a point; avg. 7.35 ± 1.91 vs. standard 8.50 ± 1.95), and
  • the middle stats about the same on average, but noticeably less swingy (e.g. 3rd highest stat has avg. 12.92 ± 0.97 vs. standard 12.96 ± 1.46).

The reduction in the low stat averages seems to be mainly because the OP's method makes the stats always sum to 72 points, whereas the average for a standard array is actually about 73.5 points.

If we modify HighDiceRoller's program to make the total sum 73 instead of 72 points, we can see that all the averages rise by 0.12 to 0.23 points (which is not surprising: on average, adding one point to the total should increase each stat by 1/6 ≈ 0.17 points), with the lowest stats rising the most. Increasing the total to 74 points (again unsurprisingly) continues this trend, raising the average of each stat by 0.11 to 0.24 points.

We can summarize these results in a convenient table:

Standard Balanced (72) Balanced (73) Balanced (74)
Rank 1 15.66 ± 1.43 15.89 ± 1.22 16.01 ± 1.19 16.12 ± 1.17
Rank 2 14.17 ± 1.44 14.27 ± 1.07 14.41 ± 1.06 14.54 ± 1.04
Rank 3 12.96 ± 1.46 12.92 ± 0.97 13.08 ± 0.96 13.23 ± 0.95
Rank 4 11.76 ± 1.53 11.58 ± 0.98 11.75 ± 0.97 11.92 ± 0.96
Rank 5 10.41 ± 1.66 9.99 ± 1.17 10.18 ± 1.16 10.37 ± 1.14
Rank 6 8.50 ± 1.95 7.35 ± 1.91 7.58 ± 1.90 7.82 ± 1.89

(The number after the ± sign is the standard deviation, which basically measures how "swingy" each stat is, i.e. how far away from the average an actually rolled stat is likely to be.)

Notably, even with a 74 point total, the average lowest stat rolled with the "balanced" method is still over half a point lower (7.82 ± 1.89) than with the standard method (8.50 ± 1.95), but at least the average highest stat is correspondingly almost half a point higher (16.12 ± 1.17 vs. standard 15.66 ± 1.43). Thus, if you want stats that roughly match those rolled with the standard method, I'd be inclined to suggest setting the total to 73 or 74.

(Of course in practice, as long as everyone is rolling stats with the same method, it really doesn't matter all that much what that method is or what kind of averages it yields.)

Looking at the actual stat distributions themselves, rather than just the averages and deviations, one notable feature of the "balanced method" is that it sets a hard limit on how low your highest stat can be.

In particular, with a 73 or 74 point total, the balanced method forces your highest stat to always be at least 13. With a 72 point total a high stat of 12 is technically possible, but only if you roll 12 on every single stat (which happens with a probability of about 0.0045%). With the standard method, the probability of rolling 12 or less on all six stats is about 1.8%, which, while quite low, is still within the realm of practical possibility.

Also, none of the programs or analysis above captures the covariance between the rolled stats. I haven't actually calculated that, but in general I would expect the sorted stats rolled with the standard method to be somewhat positively correlated (basically because if your highest stat is low, that means all your other stats must be low as well, and vice versa), whereas the balanced method ought to introduce some negative correlation, or at least reduce the normal positive correlation (since if one of your stats is higher than average, that forces at least some of your other stats to be lower than average in order to maintain the fixed total).

Or, in other words, with this method single particularly good stats tend to be balanced out by your other stats being somewhat worse, and vice versa… which is guess is kind of implicit in the name anyway.

Also, we can modify HighDiceRoller's program to calculate the reroll rate for this stat rolling method with different totals. It turns out to be between 21% for total = 72 and 23.5% for total = 74. That's not too bad, but it does mean that with four players at the table, it's fairly likely that somebody needs to reroll their stats at least once.

  • 1
    \$\begingroup\$ This analysis is wonderful, thank you! To start, I wasn't aware that the usual average for the standard array was 73.5, though this wouldn't be hard to find, it's been a while since I've GMed and most campaigns I've played in recently have either used other alternate rolling methods or point assignment based on a set total. It's interesting seeing the floor/ceiling you mentioned visualized with the program as well, its a detail I probably would've overlooked without you bringing it up. You've provided some excellent food for thought while I'm playing around with ideas, so thank you! \$\endgroup\$
    – Cycanis
    Commented Feb 8 at 15:29
  • \$\begingroup\$ Great analysis! \$\endgroup\$ Commented Feb 9 at 8:06
  • 1
    \$\begingroup\$ A quick brute-forcing of correlelation shows that adjacent-ranked remain positively correlated, but larger distances become negatively correlated. \$\endgroup\$ Commented Feb 9 at 8:06

You must log in to answer this question.

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