# D&D GeneralPoint Buy Meets Best of 4d6 in Order

##### Legend
Supporter
Generating abilities came up in another thread. One thing some folks like is having the random stats in a random order (maybe so not everyone of a given class has pretty much the same array, or maybe to let the dice guide what class they want). A sizeable subset of those folks don't actually make the players stick with the rolls if they are really bad. For those who don't like the point buy, one of the arguments is that it can lead to the situation where someone's character has much better stats than someone else's and that can lead to feel-bads.

The (totally not-optimized) code in the spoiler below should randomly generate a 27 point character from 5e, where the chance of the particular array showing up is proportional to the chance it would be observed using best 3 out of 4d6. (So imagine generating best 3 of 4d6 in order, and throwing them out until you get one that is 27 points) .

To run it, simply copy the spoilered code into either: Create a new R program - myCompiler - myCompiler or Run R code online , hit run, and wait a few seconds. It will generate ten of them. (Changing nchar= to a bigger number will make more of them).

zz<-0
x<-matrix(0,nrow=262144,ncol=6)
for (i in 8:15){
for (j in 8:15){
for (k in 8:15){
for (l in 8:15){
for (m in 8:15){
for (n in 8:15){
zz<-zz+1
x[zz,]<-c(i,j,k,l,m,n)
}}}}}}
costm<-x-8
costm[x==14]<-costm[x==14]+1
costm[x==15]<-costm[x==15]+2
cost<-apply(costm,1,sum)
x<-x[cost==27,]
probm<-matrix(0,nrow=dim(x)[1],ncol=dim(x)[2])
probm[x==8]<-0.0478
probm[x==9]<-0.0702
probm[x==10]<-0.0941
probm[x==11]<-0.1142
probm[x==12]<-0.1289
probm[x==13]<-0.1327
probm[x==14]<-0.1235
probm[x==15]<-0.1011
prob<-apply(probm*10,1,prod)
prob<-prob/sum(prob)
nchar=10
x[sample(1:dim(x)[1],nchar,prob=prob),]

Sample output:

I'm happy to modify the code if someone wants a different point buy or for the probabilities to match just 3d6 or whatever.

I'm also happy to hear why folks would absolutely hate this. (I'm guessing one reason is that actually rolling dice is fun!)

Last edited:

##### Legend
Supporter
As an aside, even after all these years, my default is apparently still SIWDCCh when I read across in my head.

#### ezo

##### Where is that Singe?
Nice work! Honestly, I'm surprised I never thought of this before LOL!

Something along these lines would work fine for me, personally. For one reason, rolling of course can lead to lucky and unlucky rolls, which can discourage players when they feel their PC is unbalanced to the others. Another is that it keeps the scores within a range I find preferable for play (I dislike beginning with scores above 15).

#### pukunui

##### Legend
Nice work!

Back when I last ran 3.5e, I created a mixed roll + point buy method. It went something like: you'd roll for three stats, then subtract the value of those rolls from a point buy total, then buy the other three stats. That way you could get something higher (or lower, if that floats your boat) than standard point buy, while keeping all PCs balanced and giving old school players that dice-based randomness they crave.

I haven't used it since then. Just been using point buy or standard array ever since.

#### ezo

##### Where is that Singe?
FWIW here's a quick VBA script I just wrote for Excel (which I use for most stuff anyway).

It only generates one set since that is all I need for a PC. But, it wouldn't be difficult to create several with a little modification.

So, random order, point-buy range, 27 points total.

Sub roll_Scores()

Dim scores(6)
Dim dr(3)
Dim done As Boolean

done = False

Do
cursum = 0
scoreout = False
For i = 1 To 6
scores(i) = 0
For j = 0 To 3
dr(j) = Int(Rnd * 6) + 1
scores(i) = scores(i) + dr(j)
Next j
scores(i) = scores(i) - Application.WorksheetFunction.Small(dr, 1)
If scores(i) > 7 And scores(i) < 16 Then
cursum = cursum + scores(i) - 8
If scores(i) = 14 Then cursum = cursum + 1
If scores(i) = 15 Then cursum = cursum + 1
ElseIf scores(i) < 8 Or scores(i) > 15 Then
scoreout = True
Exit For
End If
Next i
If cursum = 27 And Not scoreout Then done = True
Loop Until done

For a = 1 To 6
Range("A" & a).Value = scores(a)
Next a

End Sub

Replies
36
Views
3K
Replies
29
Views
3K
Replies
5
Views
1K
Replies
704
Views
33K
Replies
20
Views
2K