OK, I thought I was done with this, but I’m not.
Difficulty
The system as written gives the GM two ways to alter probabilities:
-
Bonuses and Penalties alter the size of a Dice Pool.
-
Target Numbers alter the probability of a Marginal Success on a Dice Pool of a given size.
This may prove confusing, so I’d suggest this:
-
Add or remove dice from the Dice Pool based on external factors like equipment used (or not used), lighting, range to a target (if in ranged combat), etc.
-
Alter the Target Number based on the intrinsic difficulty of the task, i.e. how unusual the task is and/or what happens if it fails. When in doubt, use Normal (5).
As always, the GM’s ruling is final.
Marginal Successes
I added “Marginal Successes” – a 4 or 5 counted as barely a success – partly as a replacement for Pushing a Roll in YZE, and partly in imitation of rolls in Blades in the Dark.
If we eliminate the category and treat all Successes equally, all dice rolls would be Pass/Fail. Each combat round would deal damage either to the Heroes or their adversaries; NPCs would take more damage than the old system, and need more HP.
Moreover, the chances of a Critical Success – more than one die meets or exceeds the Target Number – varies with the Target Number. In combat Heros would do damage more often if the Target Number is 5 or 4, which might mean adjusting the opponents’ HP to compensate.
Using the program below, I’ve calculated how the target number affects the number of Successes.
Dice | 4 | 5 | 6 | 4x2 | 5x2 | 6x2 | 4x3 | 5x3 | 6x3 |
---|---|---|---|---|---|---|---|---|---|
0d | 25.00% | 11.11% | 2.78% | ||||||
1d | 50.00% | 33.33% | 16.67% | ||||||
2d | 75.00% | 55.56% | 30.56% | 25.00% | 11.11% | 2.78% | |||
3d | 87.50% | 70.37% | 42.13% | 50.00% | 25.93% | 7.41% | 12.50% | 3.70% | 0.46% |
4d | 93.75% | 80.25% | 51.77% | 68.75% | 40.74% | 13.19% | 31.25% | 11.11% | 1.62% |
5d | 96.88% | 86.83% | 59.81% | 81.25% | 53.91% | 19.62% | 50.00% | 20.99% | 3.55% |
6d | 98.44% | 91.22% | 66.51% | 89.06% | 64.88% | 26.32% | 65.62% | 31.96% | 6.23% |
7d | 99.22% | 94.15% | 72.09% | 93.75% | 73.66% | 33.02% | 77.34% | 42.94% | 9.58% |
8d | 99.61% | 96.10% | 76.74% | 96.48% | 80.49% | 39.53% | 85.55% | 53.18% | 13.48% |
9d | 99.80% | 97.40% | 80.62% | 98.05% | 85.69% | 45.73% | 91.02% | 62.28% | 17.83% |
10d | 99.90% | 98.27% | 83.85% | 98.93% | 89.60% | 51.55% | 94.53% | 70.09% | 22.48% |
11d | 99.95% | 98.84% | 86.54% | 99.41% | 92.49% | 56.93% | 96.73% | 76.59% | 27.32% |
12d | 99.98% | 99.23% | 88.78% | 99.68% | 94.60% | 61.87% | 98.07% | 81.89% | 32.26% |
If we eliminate Marginal Successes I’d also want to eliminate variable Target Numbers for simplicity. If we fix the Target Number at 5, we get the following probabilities, extended to 6 successes:
Dice | 1+ | 2+ | 3+ | 4+ | 5+ | 6+ |
---|---|---|---|---|---|---|
0d | 11.11% | |||||
1d | 33.33% | |||||
2d | 55.56% | 11.11% | ||||
3d | 70.37% | 25.93% | 3.70% | |||
4d | 80.25% | 40.74% | 11.11% | 1.23% | ||
5d | 86.83% | 53.91% | 20.99% | 4.53% | 0.41% | |
6d | 91.22% | 64.88% | 31.96% | 10.01% | 1.78% | 0.14% |
7d | 94.15% | 73.66% | 42.94% | 17.33% | 4.53% | 0.69% |
8d | 96.10% | 80.49% | 53.18% | 25.86% | 8.79% | 1.97% |
9d | 97.40% | 85.69% | 62.28% | 34.97% | 14.48% | 4.24% |
10d | 98.27% | 89.60% | 70.09% | 44.07% | 21.31% | 7.66% |
Also, I’d rule that combat proceeds in two phases, the Heroes turn and the Hordes’ turn, and that Hordes always do Damage as long as they still have HP. (Rivals and Heroes would still roll simultaneously, and only do damage if they roll well.) This modification would effectively make combat closely resemble the Arkham Horror board game.
Program
This program generated the tables above and in the previous article.
#!/usr/bin/env lua
local NSIDES = 6
-- Chance of rolling `t` or better on one die
local function success_1(t)
if t <= 1 then
return 1.0
elseif t > NSIDES then
return 0.0
else
return (NSIDES + 1 - t) / NSIDES
end
end
-- Special rule for dice pool <= 0:
-- roll 2 dice, get `t` or higher on BOTH
local function success_0(t)
local p = success_1(t)
return p * p
end
-- Classic choose function
local function choose(n, k)
if n < 1 or k < 0 or k > n then
return 0
end
local result = 1
for i = 1, k do
result = result * (n + 1 - i) / i
end
return result
end
-- Classic binomial function
local function binomial(n, k, p)
return choose(n, k) * (p)^k * (1-p)^(n-k)
end
-- chance of rolling at least `k` successes on `n` dice
-- with probability `p`
local function success_at_least(n, k, p)
if k <= 0 then
return 1.0
end
if k == 1 then
return 1 - (1 - p)^n
end
local result = 0
for i = k, n do
result = result + binomial(n, i, p)
end
return result
end
-- Chances of rolling `t` or better at least `k` times on `n` 6-sided dice.
local function success(n, k, t)
if n < 1 then
if k > 1 then
return 0.0
end
return success_0(t)
else
return success_at_least(n, k, success_1(t))
end
end
local function format_col(v)
local k,t = table.unpack(v)
if k == 1 then
return string.format(" %-7d ", t)
else
return string.format(" %dx%-5d ", t, k)
end
end
local function format_percent(p)
if p == 0 then
return string.rep(" ", 9)
end
return string.format(" %6.2f%% ", p * 100)
end
local function print_header(cols)
local rowbuf
rowbuf = { "Dice " }
for i,v in ipairs(cols) do
table.insert(rowbuf, format_col(v))
end
table.insert(rowbuf, "")
print(table.concat(rowbuf, '|'))
rowbuf = { ":---:" }
for d = 1, #cols do
table.insert(rowbuf, "--------:")
end
table.insert(rowbuf, "")
print(table.concat(rowbuf, '|'))
end
local function print_row(n, cols)
local rowbuf = { string.format(" %2dd ", n) }
for i,v in ipairs(cols) do
local k,t = table.unpack(v)
table.insert(rowbuf, format_percent(success(n,k,t)))
end
table.insert(rowbuf, "")
print(table.concat(rowbuf, '|'))
end
local function print_table(maxdice, maxsuccess)
local md, ms = (maxdice or 10), (maxsuccess or 3)
local cols = {}
for i = 1, ms do
for j = 4,6 do
table.insert(cols, {i,j})
end
end
print_header(cols)
for n = 0, md do
print_row(n, cols)
end
end
print_table(12)