It seems that you're using an outdated browser. Some things may not work as they should (or don't work at all).
We suggest you upgrade newer and better browser like: Chrome, Firefox, Internet Explorer or Opera

×
According to the options menu, the basic d20 randomization algorithm is ([0-32767] % 20) + 1, and lists used by the other algorithms are presumably generated this way. The problem with this algorithm - i.e. downsampling a d32768 to a d20 - is that it has a slight bias in favor of low results due to 32768 not being evenly divisible by 20. Consequently, while a raw 0 leads to a die roll of 1 at the low end of the range, a raw 32767 does not yield a 20 at the high end - it yields an 8, while the highest raw value that yields a 20 is 32759.

This means that die values 9-20 each occur with frequency 1638 / 32768 (1638 = (32759 + 1) / 20), while die values 1-8 each occur with frequency 1639 / 32768. This could be corrected by discarding any raw value greater than (but not including) 32759 and drawing a new random number.

However, d20 is not the only die size used in D&D and most other games based on its mechanics, which raises the question of how you generate values for these other dice. Most likely, I suspect you either use the same algorithm (or the variations listed in the options menu), substituting the appropriate value for 20 on the right of the modulus operator, or downsample from d20.

Most d20 games use dice in sizes d2, d3, d4, d6, d8, d10, d12, d20, and d100, or some subset of that list. Of note, d3 is the only odd die, and can be (and in tabletop play usually is) downsampled evenly from a d6, d2 can be evenly downsampled from any larger even-sided die, d4 from d8 or d20, d10 from d20, and (though rarely done) d6 from d20. d8 and d20 can be downsampled from d100 if d100 is being generated, but d100 may or may not actually be used, and if it is it may be more convenient to construct d100 from two d10 or d20 rolls as is common in tabletop play (physical hecatohedral dice do exist, but are rare, expensive and notoriously awkward to read).

If these die rolls are generated in the similar manner as the formula given for d20 rolls, most of them will produce similar bias. The formula will produce no bias for d2, d4 or d8 as those numbers divide evenly into 32768, but this is not true for d3, d6, d10, d12 or d100. Correcting this would require discarding the appropriate portion of the high end of possible raw random numbers. For d10, this would mean discarding anything greater than 32759 (as witn d20). For d12, it would mean discarding anything greater than... 32759. It turns out 32760 is evenly divisible by all common dice sizes, except d100, for which anything above 32699 should be discarded if generating d100 directly from a single random number.

Furthermore, all commonly used dice, other than d100, divide evenly into 60, which divides evenly into 32760. So a simple procecure would be roll d60 = [0-32759] % 60 (no need toa dd +1 since this will not be used directly), use this to fill lists for the list algorithms, and roll dX = (d60 % X) + 1. If d100 is needed it could be composed as ((d60 % 10) - 1) * 10 + (d60 % 10), or 20 * ((d60 % 5) -1) + (d60 % 20), or any similar formula, using d60 values possibly-randomly selected from the possibly-shuffled list if using any of the list algorithms.

If smaller dice are currently implemented by downsampling from d20 values, I would assume (and hope) the devs are already aware of the need to trim high results form the [1-20] range for die sizes that are not divisors of 20, i.e. discard 17-20 when converting to d8, 19-20 when converting to d3 or d6, and 13-20 when converting to d12.
Thanks for the analysis and algorithm. I'll consider to use it to improve the dice generator of LMA.
avatar
lliihhaaoo: Thanks for the analysis and algorithm. I'll consider to use it to improve the dice generator of LMA.
For the record, what algorithm(s) does LMA currently use for generating other-tnan-d20 die rolls, and does (and if so, how) the choice of d20 algorithm in the options menu affect how these rolls are generated? As I said in my original post, I can see two "obvious" possibilities based on the d20 algorithm stated in the Options menu (i.e. converting from pre-genarated d20 values, or using the modulus algorithm directly with a modulus of 6, 8, 10, etc. instead of 20), or it could be something else entirely.
avatar
lliihhaaoo: Thanks for the analysis and algorithm. I'll consider to use it to improve the dice generator of LMA.
avatar
A_Khan: For the record, what algorithm(s) does LMA currently use for generating other-tnan-d20 die rolls, and does (and if so, how) the choice of d20 algorithm in the options menu affect how these rolls are generated? As I said in my original post, I can see two "obvious" possibilities based on the d20 algorithm stated in the Options menu (i.e. converting from pre-genarated d20 values, or using the modulus algorithm directly with a modulus of 6, 8, 10, etc. instead of 20), or it could be something else entirely.
The default d20 algorithm of LMA:

1. Make a 1~20 list
2. Use std::random_shuffle to shuffle the list
3. Pick first number as result


The algorithm for other die rolls, such as 2d8, is more direct:
...
for(int i = 0; i < cnt; ++i)
sum += rand_range(1, sides);// rand() % (b - a + 1) + a
...