Difference between revisions of "Research Probability"
m |
m |
||
| Line 215: | Line 215: | ||
==== Critical hits ==== | ==== Critical hits ==== | ||
| − | + | Another way to create occasional bursts of high damage is to implement it more directly. In some games, a "critical hit" provides some bonus. The simplest bonus is extra damage. In the following code the critical hit damage is added '''<span style="color:#006699"><u>5%</u></span>''' of the time: | |
| − | + | ||
| + | |||
| + | <code>damage = rollDice(3, 4)</code> | ||
| + | <code>if random(100) < '''<span style="color:#006699"><u>5</u></span>''':</code> | ||
| + | : <code>damage += rollDice(3, 4)</code> | ||
| + | |||
| + | |||
| + | Other approaches to adding asymmetry include affecting further attacks: make the critical hits have a chance to trigger further critical hits; make critical hits trigger a second attack that skips defenses; or make critical hits cause the opponent to miss an attack. However I’m not going to analyze multi-attack damage distributions here. | ||
| + | |||
| + | |||
==== Try designing your own ==== | ==== Try designing your own ==== | ||
| − | * | + | For each use of randomness (damage, attributes, etc.), start by describing the characteristics of the distribution that you want for your gameplay: |
| − | ** | + | |
| + | |||
| + | * '''Range:''' what are the minimum and maximum values, if any? Use scaling and shifting to adjust your distribution to fit this range. | ||
| + | * '''Variance:''' how often do you want the values to be close to the average? Add a small number of rolls for large variance, or a large number of rolls for small variance. | ||
| + | * '''Asymmetry:''' do you want higher-than-average or lower-than-average values to be more common? Use min, max, or critical bonuses to add asymmetry to your distribution. | ||
| + | |||
| + | |||
| + | Use the playground to '''play''' with some of these parameters: | ||
| + | |||
| + | |||
| + | <code>value = '''<span style="color:#006699"><u>0</u></span>''' + rollDice('''<span style="color:#006699"><u>3</u></span>''', '''<span style="color:#006699"><u>8</u></span>''')</code> | ||
| + | <code># '''<span style="color:#006699"><u>No min</u></span>'''</code> | ||
| + | <code># '''<span style="color:#006699"><u>No max</u></span>'''</code> | ||
| + | <code># '''<span style="color:#006699"><u>No critical bonus</u></span>'''</code> | ||
| + | |||
| + | |||
| + | There are lots more ways to structure your random numbers than the playground offers, but I hope it gives you a sense of how much flexibility there already is. Also check out [http://www.avanderw.co.za/dice-distributions/ this damage roll calculator]. Sometimes though combining dice rolls is not enough to give you what you want. | ||
Revision as of 17:18, 1 July 2017
Game Design Articles ideas and Research examples to prove that rolling random dice/numbers is written all wrong in each roleplaying game articles.
When a table of Random Generation Tables are created for deciding an outcome, they inherently are created as Alphabetical lists, rather than by the desired outcome, which will eventually mismatch the desired numbers of the given table.
This article will show how to balance and adjust these tables to give desired and proper generation of proper numbers to create Realistic Tables.
Colour Text: Code: public class
| 900px |
Note: Green = I Have, Red = Don't Have, Orange = Old Scan, Blue = Misc, Black = ALL Base (Template)
Note: TO ADD: MUST add this article for random roll variances and how they function etc.
Contents
Probability and Games: Damage Rolls
Paper-and-dice role playing games like Dungeons & Dragons use damage rolls to calculate attack damage. This makes sense for a game based on dice. Many computer RPGs calculate damage and other attributes (strength, magic points, agility, etc.) with a similar system.
Typically you’ll write some code to call random(). You’ll adjust the numbers and tweak the results to get the behavior you want in your game. This tutorial will cover three topics:
- Basic adjustments — average value and variance
- Adding asymmetry — dropping dice rolls or adding critical hits
- Complete freedom in designing your random numbers, not limited by what dice provide
Basics
For this article I assume you have a function random(N) that returns a random integer from 0 to range-1. In Python, use random.randrange(N) ; in Javascript, use Math.floor(N * Math.random()) ; in C, the standard library has rand() % N but it behaves poorly so use a different random number generator ; in C++, attach a uniform_int_distribution(0,N-1) to a random number generator object; in Java, make a random number generator object with new Random() and then call .nextInt(N) on it. The standard libraries in many languages don’t have great random number generators but there are lots of third party libraries such as PCG for C and C++.
Let’s start with a single die. This histogram shows the results of rolling a single 12-sided die: 1+random(12). Since random(12) returns a number from 0 to 11, and we want a number from 1 to 12, we add 1 to it. The x-axis is the damage; the y-axis shows how often that damage occurs. With a single die, a damage roll of 2 or 12 is just as likely as a damage roll of 7.
Note: TO ADD: Table with % inside columns
| 900px |
For multiple dice rolls, it’ll help to use a bit of notation from dice games: NdS means roll an S sided die N times. Rolling the single 12-sided die above would be written 1d12; 3d4 means to roll a 4-sided die three times; we’d code it as 3 + random(4) + random(4) + random(4).
Let’s roll one 12-sided dice (1d12) and add up the results:
Let’s roll two 6-sided dice (2d6) and add up the results:
Let’s roll three 4-sided dice (3d4) and add up the results:
Let’s roll four 3-sided dice (4d3) and add up the results:
Let’s roll six 2-sided dice (6d2) and add up the results:
Let’s roll twelve 1-sided dice (12d1) and add up the results:
damage = 0
for each 0 ≤ i < 3:
-
damage += 1+random(4)
Note: TO ADD: Change text and copy the following paragraph with variant TXT (to reflect the adjustment for each table)
The outcomes could be anywhere from 2 (all dice roll 1) to 12 (both dice roll 6). It’s more likely to roll 7 than 2 or 12.
Note: TO ADD: Table with % inside columns, for each of the 4 tables
| 900px |
| 900px |
| 900px |
| 900px |
What happens if we increase the number of dice, but decrease their size?
Try these ways to generate random numbers up to 12:
The main effect is that the distribution goes from wide to narrow. There’s also a second effect, where the peak shifts to the right. Let’s first investigate the uses of shifts.
Constant Shifts
Some weapons in Dungeons & Dragons give bonus damage. We could write 2d6+1 to indicate +1 bonus damage. In some games, armor or shields negate some damage. We could write 2d6-3 to indicate that 3 points of damage are blocked; I’ll assume in this example that the minimum damage is 0.
Try shifting the damage positive (for a damage bonus) or negative (for damage blocking): +0
Adding bonus damage or subtracting blocked damage simply shifts the entire distribution left or right.
Distribution variance
As we moved from 2d6 to 6d2 the distribution both got narrower and shifted to the right. As we saw in the previous section, shifting is just an offset. Let’s look at distribution variance.
Let’s define a function for N repeated rolls of random(S+1), returning a number from 0 to N*S:
function rollDice(N, S):
-
# Sum of N dice each of which goes from 0 to S -
value = 0 -
for 0 ≤ i < N:-
value += random(S+1)
-
-
return value
Generating random numbers from 0 to 24 using two dice produces this distribution of outcomes:
Try changing the number of dice — 2 — to see how it affects the distribution. As the number of rolls goes up, while holding the range 0 to N*S fixed, the distribution becomes narrower (lower variance). More of the outcomes will be near the center of the range.
Asymmetry
The distributions for rollDice(N, S) are symmetric. Lower than average values are just as likely as higher than average values. Is that what you wanted for your game? If not, there are several techniques for creating asymmetry.
Dropping or redoing rolls
Suppose you’d like higher-than-average values to be more common than lower-than-average values. This is less common for damage, but can be used for attributes like strength, intelligence, etc. One way to do this is to roll several times and pick the best roll.
Let’s try rollDice(2, 12) twice and picking the higher roll:
roll1 = rollDice(2, 12)
roll2 = rollDice(2, 12)
damage = max(roll1, roll2)
When we pick the higher of rollDice(2, 12) and rollDice(2, 12), we end up with a number from 0 to 24. Another way to get a number from 0 to 24 is to use rollDice(1, 12) three times and pick the best two of three. The shape is even more asymmetric than picking the better of two of rollDice(2, 12):
roll1 = rollDice(1, 12)
roll2 = rollDice(1, 12)
roll3 = rollDice(1, 12)
damage = roll1 + roll2 + roll3
# now drop the lowest:
damage = damage - min(roll1, roll2, roll3)
Another approach would be to reroll the lowest outcome. The shape is similar overall to the previous approaches, but slightly different in its details:
roll1 = rollDice(1, 8)
roll2 = rollDice(1, 8)
roll3 = rollDice(1, 8)
damage = roll1 + roll2 + roll3
# now drop the lowest and roll it again:
damage = damage - min(roll1, roll2, roll3) + rollDice(1, 8)
Any of these approaches can be used to reverse the asymmetry, making lower-than-average values more common than higher-than-average values. A different way of looking at it is that this distribution produces occasional bursts of high values. Such a distribution is often used for damage, and rarely used for attributes. Here’s max() reversed to min():
roll1 = rollDice(2, 12)
roll2 = rollDice(2, 12)
damage = min(roll1, roll2)
Critical hits
Another way to create occasional bursts of high damage is to implement it more directly. In some games, a "critical hit" provides some bonus. The simplest bonus is extra damage. In the following code the critical hit damage is added 5% of the time:
damage = rollDice(3, 4)
if random(100) < 5:
-
damage += rollDice(3, 4)
Other approaches to adding asymmetry include affecting further attacks: make the critical hits have a chance to trigger further critical hits; make critical hits trigger a second attack that skips defenses; or make critical hits cause the opponent to miss an attack. However I’m not going to analyze multi-attack damage distributions here.
Try designing your own
For each use of randomness (damage, attributes, etc.), start by describing the characteristics of the distribution that you want for your gameplay:
- Range: what are the minimum and maximum values, if any? Use scaling and shifting to adjust your distribution to fit this range.
- Variance: how often do you want the values to be close to the average? Add a small number of rolls for large variance, or a large number of rolls for small variance.
- Asymmetry: do you want higher-than-average or lower-than-average values to be more common? Use min, max, or critical bonuses to add asymmetry to your distribution.
Use the playground to play with some of these parameters:
value = 0 + rollDice(3, 8)
# No min
# No max
# No critical bonus
There are lots more ways to structure your random numbers than the playground offers, but I hope it gives you a sense of how much flexibility there already is. Also check out this damage roll calculator. Sometimes though combining dice rolls is not enough to give you what you want.
Arbitrary Shapes
A
Conclusion
Comments
Link Name
Notes
- Probability and Games: Damage Rolls 22 Jan 2012 by Red Blob Games
- A