The following text is © 2024 by Frank Mitchell. All rights reserved.
Lore Revisited
Last time I defined Lore thus:
Lore is a measure of how much the character understands the working of magic. It’s stated in the same terms as a system’s skills: percentiles in D100, modifiers to a d20 roll in d20, a number of dice in dice pool systems, etc.
After some thought I decided I’d rather have a system-independent definition of Lore to match the system-independent definition of Essence.
Lore is independent of what host system skills a magician uses to translate a ritual from Ancient Illyrian or whatever. It’s the ability to see beyond the details of the ritual to its fundamentals, and perform only what’s necessary.
Since I settled on d6es for Essence, I’ve decided the mechanic for deciphering and understanding a Ritual will be as follows:
- If the character has never performed a ritual before, their Lore always starts at 0. The lists of Known Rituals, Used Rituals, and Unknown Rituals start off empty.
- The character has a starting dice pool equal to their Lore.
- Subtract two dice if they are inventing a ritual from scratch.
- Subtract one die if they are attempting to modify a ritual.
- Subtract one die if the ritual was translated from a language the ritualist does not know well.
- Subtract one die if the ritual isn’t part of the character’s Tradition, as noted by the spell or decided by the GM.
- Add one die if they have deciphered this ritual before.
- Add two dice if they have successfully performed this ritual before.
- If the dice pool is 0 the player rolls two dice; the result is the lower die. Otherwise the player rolls the dice pool; the result is the highest die.
- The result of the Lore check must be equal or greater to the
Ritual Difficulty, a number from 1 (Trivial) to 6 (Very Difficult).
- If the Ritual Difficulty is 1, no roll need be made; it succeeds automatically.
- If the Lore Check succeeds, the character may add the Ritual to their list of Known Rituals. If it fails, the character adds that ritual to their list of Unknown Rituals. They may not attempt to decipher that particular ritual again until their Lore increases.
- At the end of each session in which the Ritualist performs a Lore Check,
whether it succeeds or fails, the player may rolls their most difficult
Lore Check again. If the Check fails, the character’s Lore increases by
one. They also remove all Rituals from the set of Unknown Rituals.
- From this it follows that Lore increases more quickly from trying to decipher difficult rituals, as often as possible.
Optional Rule: Recording and Memorizing Rituals
Under the rules above, once a character deciphers a ritual, they know it forever. Here we consider whether the ritual is recorded and/or memorized.
- A character may translate a ritual from its original source to their own spellbook, Book of Shadows, etc. Doing so requires only time, ink, and paper.
- A character may cast a ritual from their own notes without making
a Lore Check.
- Many ritual magicians keep small chapbooks with one ritual each instead of or in addition to large tomes full of rituals. The latter may be written in a form of code which must first be broken using mundane skills.
- A character may also memorize a single ritual with no difficulty. To remember additional rituals, the character must make a Lore Check. Failure to remember the ritual means returning to either the original source (requiring a Lore Check to re-decipher it) or one’s own notes (which requires no check).
Performing a Ritual
The procedure for handling Ritual Magic in a game using these rules is this:
- The Ritual Leader assembles any required Assistants, implements, and
Offerings at an appointed place and time.
- Assistants are co-celebrants who lend their Essence to the Ritual.
- Implements are tools or components that are not consumed during the Ritual.
- Offerings are components that are consumed, or at least transformed, during the ritual. They may be raw materials, finished goods, animal sacrifices, or in the darkest rituals human sacrifices.
- The Leader begins the ritual, with Assistants joining in as required.
- If a Offering is required, the Offering is made at the end of the Ritual.
- The Leader’s player collects a pool of d6s by adding the following:
- The Leader’s Essence
- The Assistants’ Essence
- Essence derived from the Time and Place.
- Essence derived from any Relics present.
- Essence derived from the Offering(s).
- The Essence Pool loses one die for every repeated attempt at a ritual until all Ritualists get a full night’s sleep. Certain other influence, such as ritual contamination, may subtract from the die pool.
- The player rolls all Essence Dice and compares the total to the
ritual’s Essence Threshold(s). The total must equal or exceed
the (highest) threshold in order to get the corresponding effect.
If the total falls under the (lowest) Threshold, the ritual failed.
- If the player does not want to roll a large number of dice, they may subtract pairs of dice and add 7 to the Essence Total for each pair. The player must still roll at least five dice unless the Total already exceeds the threshold for the desired effect.
- The ritual has the effects determined by the Essence Total.
Next Time
In the next segment we will drill down into the game description of a ritual, and some sample rituals that nearly every ritual magician would know.
Appendix A: Lore Check vs. Ritual Difficulty
Below are the probabilities of beating each Ritual Difficulty by number of Lore dice.
Dice | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|
0d | 69.44% | 44.44% | 25.00% | 11.11% | 2.78% |
1d | 83.33% | 66.67% | 50.00% | 33.33% | 16.67% |
2d | 97.22% | 88.89% | 75.00% | 55.56% | 30.56% |
3d | 99.54% | 96.30% | 87.50% | 70.37% | 42.13% |
4d | 99.92% | 98.77% | 93.75% | 80.25% | 51.77% |
5d | 99.99% | 99.59% | 96.88% | 86.83% | 59.81% |
6d | 100.00% | 99.86% | 98.44% | 91.22% | 66.51% |
7d | 100.00% | 99.95% | 99.22% | 94.15% | 72.09% |
8d | 100.00% | 99.98% | 99.61% | 96.10% | 76.74% |
9d | 100.00% | 99.99% | 99.80% | 97.40% | 80.62% |
10d | 100.00% | 100.00% | 99.90% | 98.27% | 83.85% |
11d | 100.00% | 100.00% | 99.95% | 98.84% | 86.54% |
12d | 100.00% | 100.00% | 99.98% | 99.23% | 88.78% |
Difficulty 1 rituals always have a 100% chance of being deciphered.
Appendix B: Essence Check vs. Essence Threshold
Below are the probabilities of succeeding at a specific Threshold (TN) with a number of Essence Dice. This will prove useful when we begin defining Ritual Thresholds next time.
Note that instead of using Thresholds that are multiples of 3.5 rounded up, I decided to use a straight 3.
TN | 1D | 2D | 3D | 4D | 5D | 6D | 7D | 8D |
---|---|---|---|---|---|---|---|---|
3 | 66.67% | 97.22% | 100.00% | 100.00% | 100.00% | 100.00% | 100.00% | 100.00% |
6 | 16.67% | 72.22% | 95.37% | 99.61% | 99.99% | 100.00% | 100.00% | 100.00% |
9 | 27.78% | 74.07% | 94.60% | 99.28% | 99.94% | 100.00% | 100.00% | |
12 | 2.78% | 37.50% | 76.08% | 94.12% | 99.01% | 99.88% | 99.99% | |
15 | 9.26% | 44.37% | 77.85% | 93.92% | 98.79% | 99.82% | ||
18 | 0.46% | 15.90% | 50.00% | 79.42% | 93.88% | 98.63% | ||
21 | 2.70% | 22.15% | 54.64% | 80.83% | 93.93% | |||
24 | 0.08% | 5.88% | 27.94% | 58.58% | 82.11% | |||
27 | 0.72% | 9.65% | 33.22% | 61.98% | ||||
30 | 0.01% | 1.97% | 13.72% | 38.02% | ||||
33 | 0.18% | 3.79% | 17.89% | |||||
36 | 0.00% | 0.61% | 6.07% | |||||
39 | 0.04% | 1.37% | ||||||
42 | 0.00% | 0.18% |
TN | 9D | 10D | 11D | 12D | 13D | 14D | 15D | 16D |
---|---|---|---|---|---|---|---|---|
15 | 99.98% | 100.00% | 100.00% | 100.00% | 100.00% | 100.00% | 100.00% | 100.00% |
18 | 99.76% | 99.97% | 100.00% | 100.00% | 100.00% | 100.00% | 100.00% | 100.00% |
21 | 98.51% | 99.71% | 99.95% | 99.99% | 100.00% | 100.00% | 100.00% | 100.00% |
24 | 94.04% | 98.43% | 99.66% | 99.94% | 99.99% | 100.00% | 100.00% | 100.00% |
27 | 83.28% | 94.20% | 98.37% | 99.63% | 99.93% | 99.99% | 100.00% | 100.00% |
30 | 64.96% | 84.35% | 94.38% | 98.34% | 99.59% | 99.92% | 99.99% | 100.00% |
33 | 42.39% | 67.60% | 85.33% | 94.57% | 98.33% | 99.57% | 99.90% | 99.98% |
36 | 22.04% | 46.37% | 69.96% | 86.24% | 94.77% | 98.33% | 99.55% | 99.89% |
39 | 8.71% | 26.11% | 50.00% | 72.08% | 87.07% | 94.98% | 98.34% | 99.53% |
42 | 2.47% | 11.60% | 30.04% | 53.33% | 74.00% | 87.85% | 95.19% | 98.37% |
45 | 0.46% | 3.90% | 14.67% | 33.81% | 56.38% | 75.75% | 88.57% | 95.39% |
48 | 0.05% | 0.94% | 5.62% | 17.83% | 37.40% | 59.19% | 77.34% | 89.24% |
51 | 0.00% | 0.15% | 1.63% | 7.60% | 21.04% | 40.81% | 61.77% | 78.80% |
54 | 0.00% | 0.01% | 0.34% | 2.54% | 9.79% | 24.25% | 44.05% | 64.16% |
57 | 0.00% | 0.05% | 0.64% | 3.67% | 12.15% | 27.44% | 47.11% | |
60 | 0.00% | 0.00% | 0.11% | 1.08% | 5.02% | 14.64% | 30.57% | |
63 | 0.00% | 0.01% | 0.24% | 1.67% | 6.56% | 17.22% | ||
66 | 0.00% | 0.00% | 0.04% | 0.43% | 2.42% | 8.27% | ||
69 | 0.00% | 0.00% | 0.08% | 0.72% | 3.34% | |||
72 | 0.00% | 0.00% | 0.01% | 0.17% | 1.11% | |||
75 | 0.00% | 0.00% | 0.03% | 0.29% | ||||
78 | 0.00% | 0.00% | 0.00% | 0.06% |
TN | 17D | 18D | 19D | 20D | 21D | 22D | 23D | 24D |
---|---|---|---|---|---|---|---|---|
36 | 99.98% | 100.00% | 100.00% | 100.00% | 100.00% | 100.00% | 100.00% | 100.00% |
39 | 99.88% | 99.98% | 100.00% | 100.00% | 100.00% | 100.00% | 100.00% | 100.00% |
42 | 99.52% | 99.88% | 99.97% | 99.99% | 100.00% | 100.00% | 100.00% | 100.00% |
45 | 98.39% | 99.51% | 99.87% | 99.97% | 99.99% | 100.00% | 100.00% | 100.00% |
48 | 95.59% | 98.43% | 99.51% | 99.86% | 99.97% | 99.99% | 100.00% | 100.00% |
51 | 89.86% | 95.79% | 98.47% | 99.51% | 99.86% | 99.96% | 99.99% | 100.00% |
54 | 80.14% | 90.44% | 95.98% | 98.51% | 99.51% | 99.86% | 99.96% | 99.99% |
57 | 66.37% | 81.38% | 90.98% | 96.16% | 98.55% | 99.51% | 99.85% | 99.96% |
60 | 50.00% | 68.42% | 82.52% | 91.49% | 96.34% | 98.59% | 99.52% | 99.85% |
63 | 33.63% | 52.73% | 70.32% | 83.58% | 91.97% | 96.51% | 98.64% | 99.52% |
66 | 19.86% | 36.60% | 55.30% | 72.09% | 84.56% | 92.41% | 96.67% | 98.69% |
69 | 10.14% | 22.54% | 39.49% | 57.73% | 73.73% | 85.47% | 92.83% | 96.82% |
72 | 4.41% | 12.13% | 25.23% | 42.27% | 60.02% | 75.26% | 86.32% | 93.22% |
75 | 1.61% | 5.64% | 14.23% | 27.91% | 44.95% | 62.18% | 76.69% | 87.11% |
78 | 0.48% | 2.23% | 7.01% | 16.42% | 30.58% | 47.53% | 64.21% | 78.03% |
81 | 0.12% | 0.74% | 2.97% | 8.51% | 18.67% | 33.21% | 50.00% | 66.13% |
84 | 0.02% | 0.20% | 1.07% | 3.84% | 10.13% | 20.97% | 35.79% | 52.37% |
87 | 0.00% | 0.04% | 0.32% | 1.49% | 4.83% | 11.86% | 23.31% | 38.32% |
90 | 0.00% | 0.01% | 0.08% | 0.49% | 2.01% | 5.95% | 13.68% | 25.66% |
93 | 0.00% | 0.00% | 0.02% | 0.14% | 0.72% | 2.62% | 7.17% | 15.57% |
96 | 0.00% | 0.00% | 0.00% | 0.03% | 0.22% | 1.00% | 3.33% | 8.50% |
99 | 0.00% | 0.00% | 0.00% | 0.01% | 0.06% | 0.33% | 1.36% | 4.14% |
102 | 0.00% | 0.00% | 0.00% | 0.00% | 0.01% | 0.09% | 0.48% | 1.79% |
105 | 0.00% | 0.00% | 0.00% | 0.00% | 0.02% | 0.15% | 0.68% | |
108 | 0.00% | 0.00% | 0.00% | 0.00% | 0.00% | 0.04% | 0.22% | |
111 | 0.00% | 0.00% | 0.00% | 0.00% | 0.01% | 0.06% | ||
114 | 0.00% | 0.00% | 0.00% | 0.00% | 0.00% | 0.02% |
Appendix C: Program for Lore Checks
Generator for this table.
#!/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
-- Chances of rolling `t` or better on `n` 6-sided dice.
local function success(n, t)
local p = success_1(t)
if n < 1 then
-- Special rule for dice pool <= 0:
-- roll 2 dice, get `t` or higher on BOTH
return p * p
else
return 1 - (1 - p)^n
end
end
local function format_col(t)
return string.format(" %-7d ", t)
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()
local rowbuf
rowbuf = { "Dice " }
for t = 2,NSIDES do
table.insert(rowbuf, format_col(t))
end
table.insert(rowbuf, "")
print(table.concat(rowbuf, '|'))
rowbuf = { ":---:" }
for t = 2,NSIDES do
table.insert(rowbuf, "--------:")
end
table.insert(rowbuf, "")
print(table.concat(rowbuf, '|'))
end
local function print_row(n)
local rowbuf = { string.format(" %2dd ", n) }
for t = 2,NSIDES do
table.insert(rowbuf, format_percent(success(n,t)))
end
table.insert(rowbuf, "")
print(table.concat(rowbuf, '|'))
end
local function print_table(maxdice)
local md = (maxdice or 10)
print_header()
for n = 0, md do
print_row(n)
end
end
print_table(12)
Appendix D: Program for Essence Checks
Generator for this table.
Modified from an earlier version.
#!/usr/bin/env lua
local NSIDES <const> = 6
local MAXDICE <const> = 24
local PAGESIZ <const> = 8
local CACHE = {}
--[[
-- Chance that a roll of `ndice`D`nsides` == `target`
]]--
local function p_roll_eq(ndice, nsides, target)
if ndice == 1 then
if target >= 1 and target <= nsides then
return (1/nsides)
end
elseif target >= ndice and target <= ndice * nsides then
local key = string.format("%02d\t%02d\t%02d", ndice, nsides, target)
local result = CACHE[key]
if result then
return result
end
-- sum(1, nsides, p(one die is i) * p(remaining dice == target - i))
local sum = 0.0
for i = 1, nsides do
sum = sum + p_roll_eq(1, nsides, i)
* p_roll_eq(ndice - 1, nsides, target - i)
end
CACHE[key] = sum
return sum
end
return 0.0
end
--[[
-- Chance that a roll of `ndice` D `nsides` >= `target`
]]--
local function p_roll_ge(ndice, nsides, target)
local sum = 0.0
for t = target, nsides * ndice do
sum = sum + p_roll_eq(ndice, nsides, t)
end
return sum
end
local function format_header(mindice, maxdice)
local buf = { "", " TN " }
for n = mindice, maxdice do
table.insert(buf, string.format(" %6dD ", n))
end
table.insert(buf, "")
return table.concat(buf, "|")
end
local function format_bar(mindice, maxdice)
local buf = { "", ":---:" }
for n = 1, maxdice - mindice + 1 do
table.insert(buf, "--------:")
end
table.insert(buf, "")
return table.concat(buf, "|")
end
local function format_row(target, results)
local buf = { "",
string.format(" %3d ", target),
}
for n = 1, #results do
if results[n] == 0.0 then
table.insert(buf, string.rep(' ', 9))
else
table.insert(buf, string.format(" %6.2f%% ", results[n] * 100))
end
end
table.insert(buf, "")
return table.concat(buf, "|")
end
local function feq(f1, f2)
return math.abs(f1 - f2) < 0.0001
end
local function print_table(nsides, mindice, maxdice)
print(format_header(mindice, maxdice))
print(format_bar(mindice, maxdice))
local step = nsides // 2
local max = maxdice * nsides
local min = step
for t = min, max, step do
-- Avoid rows with all 100% or all 0%
if not (feq(p_roll_ge(mindice, nsides, t), 1.0)
or feq(p_roll_ge(maxdice, nsides, t), 0.0)) then
local result = {}
for d = mindice, maxdice do
local i = 1 + d - mindice
result[i] = p_roll_ge(d, nsides, t)
end
print(format_row(t, result))
end
end
end
local function min(a, b)
if a < b then
return a
else
return b
end
end
local function print_pages(nsides, maxdice, pagesiz)
for p = 1, maxdice, pagesiz do
print()
print_table(nsides, p, min(maxdice, p + pagesiz - 1))
end
end
print_pages(NSIDES, MAXDICE, PAGESIZ)