# What is the statistically superior character creation method, twelve 3d6 or six 4d6?

The D&D 3.5 Player's Handbook gives (among others) two preferred methods to roll ability scores for a new character: a) roll 3d6 twelve times and keep the preferred six results, or b) roll 4d6 and drop the lowest die, six times.

What is the statistically better method in terms of total modifiers?

In addition, IIRC the core rulebook excludes characters whose total bonus is lower than +3, because adventurers are assumed to be exceptional people.

-
I'm not smart enough to answer this question, but if I knew more about probability I would use anydice.com to help me figure out the answer. –  Bryant Aug 27 '10 at 20:08
I had a DM in 3.5 that wouldn't accept scores that didn't total 75 or better. My current 3.5 campaign all use the 32-point buy system, and there are several calculators out there like this one: emrilgame.netau.net/Dmstuff/pointbuy.html –  Ororo Aug 27 '10 at 20:28

If you actually get a standard distribution from the dice in the 3d6 x12 method, it will be slightly better than a standard distribution of results from the 4d6 method. The more samples you take, the more likely it is that you will get something approaching average or a standard distribution. The fewer samples you take, the more likely the results will just be random.

-
+1 Beat me to it. With more dice the bell curve gets taller and narrower in the middle. –  Colonel Sponsz Aug 27 '10 at 19:57
I think he's asking which gives better average stats, though? So the average for 12 runs of 3d6 will be lower, but what're the chances you'll get more peaks? –  Bryant Aug 27 '10 at 20:08
It seems you are right. I run some additional check and then post the graph. –  Stefano Borini Aug 27 '10 at 20:14
Bryant - The average doesn't really matter a whole lot because the sample sizes are 12 vs. 6. With 6, the results will be pretty random with no room to ignore outliers. With 12, the results are still pretty random in distribution, but you can ignore results that are unfavorable. –  Mike Bohlmann Aug 27 '10 at 20:56
@bySwarm: you are absolutely right with the "no room to ignore outliers". I'd like to comment though that excluding the lowest die in the 4d6 set technically reduces the chance of an outlier. However, a very bad throw (e.g. 3,2,1,1), forces you accept the resulting 6 due to the effect you report –  Stefano Borini Aug 27 '10 at 21:02

I appears that bySwarm is right. Here are the results:

along the X axis is the total bonus over the six ability scores. Along the Y axis, the probability, obtained from 1 million runs. Results below a total bonus of +3 have been purged from the count, so the grand total of runs is less than the original 1 million.

It appears that the twelve 3d6 statistically produces a better total bonus than the 4d6 method.

This is the code to run the 4d6 case (in Python)

import sys
import random

count = {}
for i in xrange(1,1000000):
collection = []
for j in xrange(0,6):
extraction = [random.randint(1,6), random.randint(1,6), random.randint(1,6), random.randint(1,6) ]
#print extraction
collection.append( sum( sorted( extraction )[1:] ) )
#print collection
bonuses = map(lambda x: (x-10)/2, collection)
#print bonuses
total_bonus = sum(bonuses)
#print total_bonus

if total_bonus < 3:
#print "too low, excluded"
continue

if not count.has_key(total_bonus):
count[total_bonus]=0
count[total_bonus] += 1

total_extractions = sum(count.values())
for bonus,occurrences in sorted(count.items()):
print bonus,occurrences/float(total_extractions)


This is for the twelve 3d6 case:

import random

count = {}
for i in xrange(1,1000000):
collection = []
for j in xrange(0,12):
extraction = [random.randint(1,6), random.randint(1,6), random.randint(1,6) ]
collection.append( sum( extraction ) )
##print collection
collection = sorted(collection)[6:]
#print collection

bonuses = map(lambda x: (x-10)/2, collection)
#print bonuses
total_bonus = sum(bonuses)
#print total_bonus

if total_bonus < 3:
#print "too low, excluded"
continue

if not count.has_key(total_bonus):
count[total_bonus]=0
count[total_bonus] += 1

total_extractions = sum(count.values())
for bonus,occurrences in sorted(count.items()):
print bonus,occurrences/float(total_extractions)

-

When you roll 4d6k3, each of your 6 ability scores follows the exact same probability distribution. In statistics lingo, your 6 ability scores are i.i.d.---independent and identically distributed---random variables. Call one of these i.i.d. random variables Y. The mean of Y is E[Y]=12.2445987654321, and its standard deviation is $\sigma_Y=2.8468444453115$. Additionally, this distribution is skewed to the left; its skewness is -0.283507652977282.

By comparison, when you roll 3d6 once, you get a random variable X, with E[X]=10.5, and standard deviation $\sigma_X=2.95803989155$. Additionally, it is symmetric, so its skewness is 0.

However, when you roll 3d6 12 times and keep the highest 6, you get 6 different random variables (not i.i.d.), called the 7th through 12th order statistics, denoted $X_{(7)},\ldots,X_{(12)}$. E.g., $X_{(12)}$ is the maximum of the 12 rolls. Each order statistic has its own mean, standard deviation, and skewness:

\begin{tabular}{ l | r r r } Order statistic & mean & standard deviation & skewness \ \hline $X_{(7)}$ & 10.8184 & 1.1411 & -0.00564534 \ $X_{(8)}$ & 11.4663 & 1.14865 & -0.00978342 \ $X_{(9)}$ & 12.1517 & 1.1693 & 0.00712255 \ $X_{(10)}$ & 12.919 & 1.2154 & 0.0435863 \ $X_{(11)}$ & 13.8598 & 1.30455 & 0.0503448 \ $X_{(12)}$ & 15.2263 & 1.44603 & -0.125062 \ \end{tabular}

Of course, you can easily find the average of the means of the 7th through 12th order statistics: $\mu=\frac{\sum_{i=7}^{12} E[X_{(i)}]}{6}=12.7403$, so $\mu > E[Y]$ by about a $\frac{1}{2}$ point. But note that $E[X_{(7)}] < E[X_{(8)}] < E[X_{(9)}] < E[Y]$, meaning the expected value of each of the 6 ability scores generated with 4d6k3 is greater than what you can expect from half the ability scores generated by the largest 6 of 12x(3d6). So the answer isn't so simple.

-
Could you please explain how did you calculate E[Y]? –  Jaime Pardos Sep 19 '10 at 11:18
@Jaime Pardos: There is a general, combinatoric formula for calculating the probability mass function f(y)=Pr[Y=y] for the random variable Y that results from throwing n s-sided dice and summing the highest k dice. The formula was derived by a user calling himself techmologist'' on Physics Forums at physicsforums.com/showthread.php?p=2813034 Once you know the pmf f(y) of Y, you can easily calculate its expected value E[Y]=mu=sum of f(y)*y over all possible values of y. Also, you can calculate its variance sigma^2=E[(Y-mu)^2]=sum of f(y)*(y-mu)^2 over all possible values of y. –  A. N. Other Sep 19 '10 at 17:26
The doc over on scribd is great (if a bit mathematically dense), but can you find a way to present it better here? StackExchange doesn't understand LaTeX. –  Paul Marshall May 30 at 18:05

As everyone else has stated, 12 rolls of 3d6 is better.

You guys writing hundreds of lines of dice code... I love the web-based tool for Troll for dice calculations.

Here's Troll code for best six of 12 rolls of 3d6:

sum (largest 6 12#(sum 3d6))

This averages in a total score around 76.4.

And the Troll code for six rolls of 4d6 keeping the best 3d6:

sum 6#(sum largest 3 4#d6)

This averages in a total score around 73.5.

-
But writing code is so much fun! –  Iain M Norman Aug 31 '10 at 9:36
Writing short and concise code that does exactly the same thing is much more fun. ;) –  Adam Dray Aug 31 '10 at 18:56
But these are strict averages! We want to know the standard deviation, because some stats can be bad, and that's okay, and we want to know if min-maxing is an option! This is crucial! Really! I should be typing in all caps! –  Beska Sep 20 '10 at 20:13
Last I checked, the web-based Troll tool is producing an error when you run it in statistics mode. If you really want this statistics info, I can (or you can) run the one-line programs through the command-line tool on your own machine. It'll have to wait till I have some time. –  Adam Dray Sep 20 '10 at 20:28

Writing a program to brute force it looks like that the difference is slight

I added up all six attributes and counted the number of times that total appears.

The 3d6 six times method clusters around a total of 72, The 4d6 drop low clusters around a total of 74

A straight 3d6 roll clusters around a total of 63.

3d6 six time is more tightly clustered and ranges from 56 to 95 while 4d6 drop low ranges from 40 to 100.

Here is the source code for Visual Basic

Option Explicit
Dim Result1(1 To 18 * 6) As Long
Dim Result2(1 To 18 * 6) As Long
Dim Result3(1 To 18 * 6) As Long

Private Sub Command1_Click()
Dim I As Long
Dim R1 As Long
Dim R2 As Long
Dim R3 As Long
Cls
For I = 1 To 100000
R1 = RollStat6TimesTakeBest
R2 = RollStat4
R3 = RollStat
Result1(R1) = Result1(R1) + 1
Result2(R2) = Result2(R2) + 1
Result3(R3) = Result3(R3) + 1
Next I

Dim F As FileSystemObject
Set F = New FileSystemObject
Dim T As TextStream
Set T = F.CreateTextFile("C:\test.csv", True)
T.WriteLine "Total,3d6 6 times , 4d6 drop one , straight 3d6"
For I = 1 To 18 * 6
T.WriteLine CStr(I) & "," & CStr(Result1(I)) & "," & CStr(Result2(I)) & "," & CStr(Result3(I))
Next I
T.Close
MsgBox "Done"
End Sub

Private Function D(Roll As Integer) As Integer
Dim Result As Long
Dim Test As Double
Result = Rnd * 1000000000
D = Result Mod Roll + 1
End Function

Private Function Roll3D6() As Integer
Roll3D6 = D(6) + D(6) + D(6)
End Function

Private Function RollStat() As Integer
Dim Total As Integer
Dim I As Long
For I = 1 To 6
Total = Total + Roll3D6
Next I
RollStat = Total
End Function

Private Function RollStat6TimesTakeBest() As Integer
Dim Best As Integer
Dim I As Long
Dim Roll(1 To 6) As Integer
For I = 1 To 6
Roll(I) = RollStat
Next I
Best = Roll(1)
For I = 2 To 6
If Best < Roll(I) Then Best = Roll(I)
Next I
RollStat6TimesTakeBest = Best
End Function

Private Function Roll4D6DropLow() As Integer
Dim Roll(1 To 4) As Integer
Dim Low As Integer
Dim I As Integer
Dim Total As Integer
Roll(1) = D(6)
Roll(2) = D(6)
Roll(3) = D(6)
Roll(4) = D(6)
Low = 1
For I = 2 To 4
If Roll(I) < Roll(Low) Then Low = I
Next I
For I = 1 To 4
If I <> Low Then Total = Total + Roll(I)
Next I
Roll4D6DropLow = Total
End Function

Private Function RollStat4() As Integer
Dim Total As Integer
Dim I As Long
For I = 1 To 6
Total = Total + Roll4D6DropLow
Next I
RollStat4 = Total
End Function

-
3d6 is thrown 12 times, and the best 6 results are kept. –  Stefano Borini Aug 27 '10 at 20:37

D&D players are quick on the math. Agreed.

Want a lot of 14-16, go with 4d6. If you want more 17 & 18 go with the 3d6 method. So are you building a Monk or a Wizard?

-
Why does 3d6 produce more 17&18s than 4d6 DL? –  Pureferret Dec 28 '11 at 22:28
@Pureferret Likely because you get more rolls/tries, and that increases the probability. –  Allen Gould Mar 15 '12 at 16:47