Dice standard library
This reference lists everything built into .dice scripts beyond basic Starlark (variables, for loops, lists). New here? Work through the tutorial firstâit introduces notation like 2d6 and 4d6dl1, which the playground expands into the functions below.
Naming: face matching (keep / remove / convert / ignore), count, and pool p_* methods follow API conventions.
Core ideas
DieRoll â a finished numeric roll (or total) with exact chances for each possible result. Example: 2d6 is a DieRoll; so is 4d6dl1. Use output("name", roll) to print its table in the playground.
DicePool â several dice rolled together but not added yet. Use this when the rule cares about individual faces (highest die, count successes, Blades-style pools). Call .sum() on the pool when you only need the total.
Outcomes â chances for named outcome bands (miss / partial / hit, crit fail / success, and so on) instead of raw numbers.
Combining rolls (operators)
| You write | Meaning at the table |
|---|---|
a + b | Two independent rolls added together (e.g. 1d6 + 1d6 or 2d6 + 1d4). |
roll + 5 | Flat modifier added to every outcome of roll (same as shift(roll, 5)). |
roll - 3 | Subtract 3 from every outcome. |
a - b | Independent rolls subtracted (less common; niche mechanics). |
roll * 10 | Multiply each outcome (e.g. tens die reading). |
roll // 2 | Halve each outcome, round down (typical âhalf damage on saveâ). |
Dice notation (1d20, 3d6kh2, â¦) is sugar for these functionsâsee the dice notation lesson.
Builtin functions (by topic)
Building dice and totals
Start here for ordinary dice, custom faces, and summed pools.
d
↗def d(sides: int) -> DieRoll
One fair die with faces 1 through sides, each equally likely.
Parameters
-
sides: (required)Number of faces (must be at least 1).
Details
Same idea as 1d6 or 1d20 in dice notation. Example: d(6) for a d6, d(20) for a d20.
die_faces
↗def die_faces(faces: list[int]) -> DieRoll
A die with custom face values (listed in order; duplicates count as extra weight).
Parameters
-
faces: (required)List of integer face values.
Details
Use for dice that are not uniformâdie_faces([1, 2, 2, 3]) is twice as likely to show 2 as 1 or 3.
die_faces.bucket
↗def die_faces.bucket(scale: Scale, *bands) -> Outcomes
Label numeric totals using bands on scale, or pass cut list / bands to override.
die_faces.cdf
↗def die_faces.cdf(value: int) -> float
Chance the total is this number or lower (cumulative from the bottom).
Parameters
-
value: (required)Upper cap (inclusive).
Details
Less common than p_ge for âbeat the DCâ checks; useful when rules ask âat most Xâ.
die_faces.clamp
↗def die_faces.clamp(min: int, max: int) -> DieRoll
Cap every outcome at min and max (inclusive), merging probability at the bounds.
Parameters
-
min: (required)Lower bound (inclusive).
-
max: (required)Upper bound (inclusive).
Details
Example: (3d6 + 5).clamp(3, 18) for a boosted roll that cannot exceed 18.
die_faces.convert
↗def die_faces.convert(spec, to: int) -> DieRoll
Remap matching faces to to; other faces unchanged.
die_faces.ignore
↗def die_faces.ignore(spec) -> DieRoll
Remap matching faces to 0 (convert(spec, 0)).
die_faces.keep
↗def die_faces.keep(spec) -> DieRoll
Keep only faces matching spec; drop others and renormalize. Not .p_ge() on totals.
die_faces.mean
↗def die_faces.mean() -> float
Average result if you rolled this distribution many timesâthe mean on the output table.
die_faces.p_ge
↗def die_faces.p_ge(value: int) -> float
Chance of meeting or beating a target numberâyour go-to for âneed 15+ on 2d10â.
Parameters
-
value: (required)Target total (inclusive)âsuccess if roll ⥠this.
Details
Example: output("success", (2d10 + 3).p_ge(15)).
die_faces.pmf
↗def die_faces.pmf(value: int) -> float
Chance of rolling exactly this number (one outcome, not âthis or higherâ).
Parameters
-
value: (required)The total you care about.
Details
Example: output("pct_seven", 2d6.pmf(7)) for the probability of a 7 on 2d6.
die_faces.remove
↗def die_faces.remove(spec) -> DieRoll
Drop faces matching spec; renormalize the rest.
die_faces.support_size
↗def die_faces.support_size() -> int
How many different totals can occur with non-zero chance (size of the result table).
dice_pool
↗def dice_pool(count: int, sides: int) -> DicePool
Roll count separate fair diceânot added together yet.
Parameters
-
count: (required)How many dice.
-
sides: (required)Faces per die (each die is 1..=sides).
Details
Use when the rule looks at individual results (highest die, count 10s, etc.). Add with
.sum() or the sum(...) function when you only need the total. Example: dice_pool(4, 6) for four d6s.
dice_pool.bucket
↗def dice_pool.bucket(scale: Scale, *spec) -> Outcomes
Label the pool total using bands on scale (sums first).
dice_pool.convert
↗def dice_pool.convert(spec, to: int) -> DicePool
Remap matching faces to to on every die.
dice_pool.count
↗def dice_pool.count(spec) -> DieRoll
Distribution of how many dice match spec.
dice_pool.ignore
↗def dice_pool.ignore(spec) -> DicePool
Remap matching faces to 0 on every die.
dice_pool.keep
↗def dice_pool.keep(spec) -> DicePool
Keep only matching faces on every die; drop others and renormalize each die.
dice_pool.middle_of
↗def dice_pool.middle_of(keep: int) -> DieRoll
dice_pool.order_stat
↗def dice_pool.order_stat(k: int) -> DieRoll
dice_pool.p_any
↗def dice_pool.p_any(*spec) -> float
P(at least one die matches the optional face spec).
dice_pool.p_at_least
↗def dice_pool.p_at_least(k: int, *spec) -> float
P(at least k dice match the optional face spec).
dice_pool.p_none
↗def dice_pool.p_none(*spec) -> float
P(no die matches the optional face spec).
dice_pool.remove
↗def dice_pool.remove(spec) -> DicePool
Drop matching faces on every die; renormalize each die.
dice_pool.sum
↗def dice_pool.sum() -> DieRoll
Add every die in the pool into one totalâturns dice_pool(4, 6) into the same idea as 4d6.
sum
↗def sum(value) -> DieRoll
Total a dice pool, or leave a DieRoll unchanged.
sum(dice_pool(4, 6)) is the distribution of 4d6 summedâequivalent to 4d6 notation.
If you already have a DieRoll, sum returns it as-is.
drop_lowest
drop_lowest
↗def drop_lowest(count: int, sides: int, drop: int) -> DieRoll
Roll several dice, drop the lowest results, sum the restâ4d6 drop lowest 1 is drop_lowest(4, 6, 1).
Parameters
-
count: (required)Dice rolled.
-
sides: (required)Faces per die.
-
drop: (required)How many lowest dice to remove before summing.
Details
Same as 4d6dl1 in dice notation.
drop_highest
drop_highest
↗def drop_highest(count: int, sides: int, drop: int) -> DieRoll
Roll dice, drop the highest results, sum the rest (4d6dh1 notation).
Parameters
-
count: (required)Dice rolled.
-
sides: (required)Faces per die.
-
drop: (required)How many highest dice to remove before summing.
keep_highest
keep_highest
↗def keep_highest(count: int, sides: int, keep: int) -> DieRoll
Roll dice, keep only the highest few, sum thoseâ4d6 keep highest 3 is keep_highest(4, 6, 3) (4d6kh3).
Parameters
-
count: (required)Dice rolled.
-
sides: (required)Faces per die.
-
keep: (required)How many highest dice to sum.
keep_lowest
keep_lowest
↗def keep_lowest(count: int, sides: int, keep: int) -> DieRoll
Roll dice, keep only the lowest few, sum those (4d6kl3 notation).
Parameters
-
count: (required)Dice rolled.
-
sides: (required)Faces per die.
-
keep: (required)How many lowest dice to sum.
explode
↗def explode(dist: DieRoll, max_depth: int = 2) -> DieRoll
Exploding die: on the highest face, roll again and add, up to max_depth extra rolls (default 2).
Parameters
-
dist: (required)Usually a single die from
d(...). -
max_depth: (defaults to:2)Cap on how many times the die can explode (0 = no explode).
Details
Common in games where max on a die triggers another die (Savage Worldsâstyle). Example:
explode(d(4)) for one exploding d4.
open_ended_d100
↗def open_ended_d100(max_chain: int = 8) -> DieRoll
Rolemaster open-ended roll on 1â100 (d100): low open on 01â05, high open on 96â00; rerolls chain on 96â00 only. max_chain caps consecutive 96â00 rerolls (default 8).
open_ended_d100.bucket
↗def open_ended_d100.bucket(scale: Scale, *bands) -> Outcomes
Label numeric totals using bands on scale, or pass cut list / bands to override.
open_ended_d100.cdf
↗def open_ended_d100.cdf(value: int) -> float
Chance the total is this number or lower (cumulative from the bottom).
Parameters
-
value: (required)Upper cap (inclusive).
Details
Less common than p_ge for âbeat the DCâ checks; useful when rules ask âat most Xâ.
open_ended_d100.clamp
↗def open_ended_d100.clamp(min: int, max: int) -> DieRoll
Cap every outcome at min and max (inclusive), merging probability at the bounds.
Parameters
-
min: (required)Lower bound (inclusive).
-
max: (required)Upper bound (inclusive).
Details
Example: (3d6 + 5).clamp(3, 18) for a boosted roll that cannot exceed 18.
open_ended_d100.convert
↗def open_ended_d100.convert(spec, to: int) -> DieRoll
Remap matching faces to to; other faces unchanged.
open_ended_d100.ignore
↗def open_ended_d100.ignore(spec) -> DieRoll
Remap matching faces to 0 (convert(spec, 0)).
open_ended_d100.keep
↗def open_ended_d100.keep(spec) -> DieRoll
Keep only faces matching spec; drop others and renormalize. Not .p_ge() on totals.
open_ended_d100.mean
↗def open_ended_d100.mean() -> float
Average result if you rolled this distribution many timesâthe mean on the output table.
open_ended_d100.p_ge
↗def open_ended_d100.p_ge(value: int) -> float
Chance of meeting or beating a target numberâyour go-to for âneed 15+ on 2d10â.
Parameters
-
value: (required)Target total (inclusive)âsuccess if roll ⥠this.
Details
Example: output("success", (2d10 + 3).p_ge(15)).
open_ended_d100.pmf
↗def open_ended_d100.pmf(value: int) -> float
Chance of rolling exactly this number (one outcome, not âthis or higherâ).
Parameters
-
value: (required)The total you care about.
Details
Example: output("pct_seven", 2d6.pmf(7)) for the probability of a 7 on 2d6.
open_ended_d100.remove
↗def open_ended_d100.remove(spec) -> DieRoll
Drop faces matching spec; renormalize the rest.
open_ended_d100.support_size
↗def open_ended_d100.support_size() -> int
How many different totals can occur with non-zero chance (size of the result table).
shift
↗def shift(dist: DieRoll, delta: int) -> DieRoll
Add a flat modifier to every outcomeâ**+3 to the roll** without rolling another die.
Parameters
-
dist: (required)The roll (e.g.
2d10as aDieRoll). -
delta: (required)Modifier to add (can be negative).
Details
Same effect as roll + 3 when roll is a DieRoll. Prefer roll + 3 in scripts when it reads clearer.
through
↗def through(lo: int, hi: int) -> IntBand
Inclusive closed integer interval (same as desugared 6..94).
at_most
↗def at_most(hi: int) -> IntBand
All integers at or below hi (desugared ..hi).
at_least
↗def at_least(lo: int) -> IntBand
All integers at or above lo (desugared lo..).
Inclusive ranges
Integer bands for face filters and bucketing. In .dice scripts you can also write 6..94, ..6, and 10.. (inclusive endpoints).
through
↗def through(lo: int, hi: int) -> IntBand
Inclusive closed integer interval (same as desugared 6..94).
at_most
↗def at_most(hi: int) -> IntBand
All integers at or below hi (desugared ..hi).
at_least
↗def at_least(lo: int) -> IntBand
All integers at or above lo (desugared lo..).
Pool rules (faces still matter)
These need a DicePool from dice_pool before you total the dice.
count
↗def count(pool: DicePool, spec) -> DieRoll
How many dice in the pool match a face spec?
Parameters
-
pool: (required)From
dice_pool. -
spec: (required)int face, list of ints, or
IntBand/ desugared range (e.g.5..for 5+).
Details
The result is a DieRoll over counts (0, 1, 2, â¦). Same as pool.count(spec).
order_stat
↗def order_stat(pool: DicePool, k: int) -> DieRoll
The kth highest die in the pool (k = 1 is the highest, 2 is second-highest, â¦).
Parameters
-
k: (required)Rank from the top (1 = best die).
Details
Blades in the Dark and similar games use the highest die; some rules use second-highest.
order_stat.bucket
↗def order_stat.bucket(scale: Scale, *bands) -> Outcomes
Label numeric totals using bands on scale, or pass cut list / bands to override.
order_stat.cdf
↗def order_stat.cdf(value: int) -> float
Chance the total is this number or lower (cumulative from the bottom).
Parameters
-
value: (required)Upper cap (inclusive).
Details
Less common than p_ge for âbeat the DCâ checks; useful when rules ask âat most Xâ.
order_stat.clamp
↗def order_stat.clamp(min: int, max: int) -> DieRoll
Cap every outcome at min and max (inclusive), merging probability at the bounds.
Parameters
-
min: (required)Lower bound (inclusive).
-
max: (required)Upper bound (inclusive).
Details
Example: (3d6 + 5).clamp(3, 18) for a boosted roll that cannot exceed 18.
order_stat.convert
↗def order_stat.convert(spec, to: int) -> DieRoll
Remap matching faces to to; other faces unchanged.
order_stat.ignore
↗def order_stat.ignore(spec) -> DieRoll
Remap matching faces to 0 (convert(spec, 0)).
order_stat.keep
↗def order_stat.keep(spec) -> DieRoll
Keep only faces matching spec; drop others and renormalize. Not .p_ge() on totals.
order_stat.mean
↗def order_stat.mean() -> float
Average result if you rolled this distribution many timesâthe mean on the output table.
order_stat.p_ge
↗def order_stat.p_ge(value: int) -> float
Chance of meeting or beating a target numberâyour go-to for âneed 15+ on 2d10â.
Parameters
-
value: (required)Target total (inclusive)âsuccess if roll ⥠this.
Details
Example: output("success", (2d10 + 3).p_ge(15)).
order_stat.pmf
↗def order_stat.pmf(value: int) -> float
Chance of rolling exactly this number (one outcome, not âthis or higherâ).
Parameters
-
value: (required)The total you care about.
Details
Example: output("pct_seven", 2d6.pmf(7)) for the probability of a 7 on 2d6.
order_stat.remove
↗def order_stat.remove(spec) -> DieRoll
Drop faces matching spec; renormalize the rest.
order_stat.support_size
↗def order_stat.support_size() -> int
How many different totals can occur with non-zero chance (size of the result table).
middle_of
↗def middle_of(pool: DicePool, keep: int) -> DieRoll
Sum the middle keep dice after sorting the pool low to high.
Parameters
-
keep: (required)How many dice in the middle to sum.
Details
Niche rules that drop extremes from both ends; less common than keep-highest / drop-lowest.
middle_of.bucket
↗def middle_of.bucket(scale: Scale, *bands) -> Outcomes
Label numeric totals using bands on scale, or pass cut list / bands to override.
middle_of.cdf
↗def middle_of.cdf(value: int) -> float
Chance the total is this number or lower (cumulative from the bottom).
Parameters
-
value: (required)Upper cap (inclusive).
Details
Less common than p_ge for âbeat the DCâ checks; useful when rules ask âat most Xâ.
middle_of.clamp
↗def middle_of.clamp(min: int, max: int) -> DieRoll
Cap every outcome at min and max (inclusive), merging probability at the bounds.
Parameters
-
min: (required)Lower bound (inclusive).
-
max: (required)Upper bound (inclusive).
Details
Example: (3d6 + 5).clamp(3, 18) for a boosted roll that cannot exceed 18.
middle_of.convert
↗def middle_of.convert(spec, to: int) -> DieRoll
Remap matching faces to to; other faces unchanged.
middle_of.ignore
↗def middle_of.ignore(spec) -> DieRoll
Remap matching faces to 0 (convert(spec, 0)).
middle_of.keep
↗def middle_of.keep(spec) -> DieRoll
Keep only faces matching spec; drop others and renormalize. Not .p_ge() on totals.
middle_of.mean
↗def middle_of.mean() -> float
Average result if you rolled this distribution many timesâthe mean on the output table.
middle_of.p_ge
↗def middle_of.p_ge(value: int) -> float
Chance of meeting or beating a target numberâyour go-to for âneed 15+ on 2d10â.
Parameters
-
value: (required)Target total (inclusive)âsuccess if roll ⥠this.
Details
Example: output("success", (2d10 + 3).p_ge(15)).
middle_of.pmf
↗def middle_of.pmf(value: int) -> float
Chance of rolling exactly this number (one outcome, not âthis or higherâ).
Parameters
-
value: (required)The total you care about.
Details
Example: output("pct_seven", 2d6.pmf(7)) for the probability of a 7 on 2d6.
middle_of.remove
↗def middle_of.remove(spec) -> DieRoll
Drop faces matching spec; renormalize the rest.
middle_of.support_size
↗def middle_of.support_size() -> int
How many different totals can occur with non-zero chance (size of the result table).
pool_map
↗def pool_map(pool: DicePool, map_fn) -> DieRoll
Custom rule: for every way the pool can land, run your function on the list of faces and use its integer result.
Parameters
-
map_fn: (required)Starlark function
(faces) -> int.
Details
Advancedâuse when no built-in pool helper fits (e.g. âsum only dice that matched another dieâ). The function receives one argument: the list of rolled values, sorted as the engine stores them.
pool_map.bucket
↗def pool_map.bucket(scale: Scale, *bands) -> Outcomes
Label numeric totals using bands on scale, or pass cut list / bands to override.
pool_map.cdf
↗def pool_map.cdf(value: int) -> float
Chance the total is this number or lower (cumulative from the bottom).
Parameters
-
value: (required)Upper cap (inclusive).
Details
Less common than p_ge for âbeat the DCâ checks; useful when rules ask âat most Xâ.
pool_map.clamp
↗def pool_map.clamp(min: int, max: int) -> DieRoll
Cap every outcome at min and max (inclusive), merging probability at the bounds.
Parameters
-
min: (required)Lower bound (inclusive).
-
max: (required)Upper bound (inclusive).
Details
Example: (3d6 + 5).clamp(3, 18) for a boosted roll that cannot exceed 18.
pool_map.convert
↗def pool_map.convert(spec, to: int) -> DieRoll
Remap matching faces to to; other faces unchanged.
pool_map.ignore
↗def pool_map.ignore(spec) -> DieRoll
Remap matching faces to 0 (convert(spec, 0)).
pool_map.keep
↗def pool_map.keep(spec) -> DieRoll
Keep only faces matching spec; drop others and renormalize. Not .p_ge() on totals.
pool_map.mean
↗def pool_map.mean() -> float
Average result if you rolled this distribution many timesâthe mean on the output table.
pool_map.p_ge
↗def pool_map.p_ge(value: int) -> float
Chance of meeting or beating a target numberâyour go-to for âneed 15+ on 2d10â.
Parameters
-
value: (required)Target total (inclusive)âsuccess if roll ⥠this.
Details
Example: output("success", (2d10 + 3).p_ge(15)).
pool_map.pmf
↗def pool_map.pmf(value: int) -> float
Chance of rolling exactly this number (one outcome, not âthis or higherâ).
Parameters
-
value: (required)The total you care about.
Details
Example: output("pct_seven", 2d6.pmf(7)) for the probability of a 7 on 2d6.
pool_map.remove
↗def pool_map.remove(spec) -> DieRoll
Drop faces matching spec; renormalize the rest.
pool_map.support_size
↗def pool_map.support_size() -> int
How many different totals can occur with non-zero chance (size of the result table).
success_pool
↗def success_pool(
count: int,
sides: int,
mode: str = "baseline",
) -> DieRoll
Count successes on a dice pool (Storyteller / WoD-style d10 pools and variants).
Parameters
-
count: (required)Dice in the pool.
-
sides: (required)Usually 10 for classic WoD.
-
mode: (defaults to:"baseline")How ones and explosions interactâmatch your tableâs house rules.
Details
Returns a DieRoll over how many successes you rolled. mode controls 1s and 10s:
"baseline" (default), "ones_cancel", "ones_remove", or "implode".
success_pool.bucket
↗def success_pool.bucket(scale: Scale, *bands) -> Outcomes
Label numeric totals using bands on scale, or pass cut list / bands to override.
success_pool.cdf
↗def success_pool.cdf(value: int) -> float
Chance the total is this number or lower (cumulative from the bottom).
Parameters
-
value: (required)Upper cap (inclusive).
Details
Less common than p_ge for âbeat the DCâ checks; useful when rules ask âat most Xâ.
success_pool.clamp
↗def success_pool.clamp(min: int, max: int) -> DieRoll
Cap every outcome at min and max (inclusive), merging probability at the bounds.
Parameters
-
min: (required)Lower bound (inclusive).
-
max: (required)Upper bound (inclusive).
Details
Example: (3d6 + 5).clamp(3, 18) for a boosted roll that cannot exceed 18.
success_pool.convert
↗def success_pool.convert(spec, to: int) -> DieRoll
Remap matching faces to to; other faces unchanged.
success_pool.ignore
↗def success_pool.ignore(spec) -> DieRoll
Remap matching faces to 0 (convert(spec, 0)).
success_pool.keep
↗def success_pool.keep(spec) -> DieRoll
Keep only faces matching spec; drop others and renormalize. Not .p_ge() on totals.
success_pool.mean
↗def success_pool.mean() -> float
Average result if you rolled this distribution many timesâthe mean on the output table.
success_pool.p_ge
↗def success_pool.p_ge(value: int) -> float
Chance of meeting or beating a target numberâyour go-to for âneed 15+ on 2d10â.
Parameters
-
value: (required)Target total (inclusive)âsuccess if roll ⥠this.
Details
Example: output("success", (2d10 + 3).p_ge(15)).
success_pool.pmf
↗def success_pool.pmf(value: int) -> float
Chance of rolling exactly this number (one outcome, not âthis or higherâ).
Parameters
-
value: (required)The total you care about.
Details
Example: output("pct_seven", 2d6.pmf(7)) for the probability of a 7 on 2d6.
success_pool.remove
↗def success_pool.remove(spec) -> DieRoll
Drop faces matching spec; renormalize the rest.
success_pool.support_size
↗def success_pool.support_size() -> int
How many different totals can occur with non-zero chance (size of the result table).
Named outcomes
Turn numeric totals or special roll rules into labeled results.
scale
↗def scale() -> Scale
Start an ordered outcome scale; chain .step(label) or .step(label, band) on the result.
Overlapping bands are allowed: early=True steps match first, then other steps (declaration order).
Declaration order still defines ladder rank for p_at_least / p_at_most. (with is reserved in Starlark.)
Example: scale().step("MISS", ..6).step("PARTIAL", 7..9).
bucket
↗def bucket(dist: DieRoll, scale: Scale, *spec) -> Outcomes
Split a numeric total into named bands.
Parameters
-
dist: (required)Numeric roll (e.g.
2d6 + stat). -
scale: (required)Built with
scale()and.step.
Details
With bands on scale (from scale().step(..., band)), call bucket(roll, scale) or
roll.bucket(scale). Overlapping bands: early=True steps first, then other steps in order.
Otherwise pass Nâ1 cut ints or N explicit bands (override).
classify
↗def classify(dist: DieRoll, scale: Scale, classify) -> Outcomes
Label each exact roll value with your own ruleânatural 1s, natural 20s, custom crits.
Parameters
-
classify: (required)Starlark function
(value) -> str.
Details
Your function takes the numeric result and returns one of the strings on scale.
Example: map only 1 and 20 to special labels, bucket everything else by total.
joint_classify
↗def joint_classify(
d1: DieRoll,
d2: DieRoll,
scale: Scale,
classify,
) -> Outcomes
Label outcomes that depend on two dice togetherâadvantage, disadvantage, or paired rolls.
Parameters
-
d1: (required),
d2: Independent rolls (e.g. two d20s for advantage). -
classify: (required)Starlark function
(w, b) -> strreturning a label onscale.
Details
Every combination of d1 and d2 is classified by your (left, right) -> str function.
joint_classify.p_at_least
↗def joint_classify.p_at_least(label: str) -> float
Chance of this outcome or any better one on the scaleâe.g. âpartial success or full successâ.
joint_classify.p_at_most
↗def joint_classify.p_at_most(label: str) -> float
Chance of this outcome or any worse oneâe.g. âfailure or partial failureâ.
joint_classify.pmf
↗def joint_classify.pmf(label: str) -> float
Chance of landing on exactly this named outcome (one band on the ladder).
Showing results
Always end scripts with output so the playground prints tables and charts.
output
↗def output(*args) -> None
Send a result to the playground Output panel (text, json, and graph tabs).
Almost every script should call this at least once. Pass a name and a value:
a full distribution (DieRoll), named outcomes (Outcomes), a probability (float),
or a table (prob_table(...)). One argument works but naming outputs helps you read results.
prob_table
↗def prob_table(rows: list) -> ProbTable
One table of labeled probabilitiesâgrids of âchance to hit DC X at modifier Yâ.
Parameters
-
rows: (required)List of
(string, float)pairs.
Details
Each row is (description, probability). Rows are independent (they do not have to add to 100%).
Build a list in a loop, then pass it here once: output("grid", prob_table(rows)).
DieRoll methods
Ask questions about a numeric DieRoll after you build it (often inside output(..., roll.p_ge(15))).
mean
↗def mean() -> float
Average result if you rolled this distribution many timesâthe mean on the output table.
pmf
↗def pmf(value: int) -> float
Chance of rolling exactly this number (one outcome, not âthis or higherâ).
Parameters
-
value: (required)The total you care about.
Details
Example: output("pct_seven", 2d6.pmf(7)) for the probability of a 7 on 2d6.
p_ge
p_ge
↗def p_ge(value: int) -> float
Chance of meeting or beating a target numberâyour go-to for âneed 15+ on 2d10â.
Parameters
-
value: (required)Target total (inclusive)âsuccess if roll ⥠this.
Details
Example: output("success", (2d10 + 3).p_ge(15)).
cdf
↗def cdf(value: int) -> float
Chance the total is this number or lower (cumulative from the bottom).
Parameters
-
value: (required)Upper cap (inclusive).
Details
Less common than p_ge for âbeat the DCâ checks; useful when rules ask âat most Xâ.
clamp
↗def clamp(min: int, max: int) -> DieRoll
Cap every outcome at min and max (inclusive), merging probability at the bounds.
Parameters
-
min: (required)Lower bound (inclusive).
-
max: (required)Upper bound (inclusive).
Details
Example: (3d6 + 5).clamp(3, 18) for a boosted roll that cannot exceed 18.
support_size
support_size
↗def support_size() -> int
How many different totals can occur with non-zero chance (size of the result table).
keep
↗def keep(spec) -> DieRoll
Keep only faces matching spec; drop others and renormalize. Not .p_ge() on totals.
remove
↗def remove(spec) -> DieRoll
Drop faces matching spec; renormalize the rest.
convert
↗def convert(spec, to: int) -> DieRoll
Remap matching faces to to; other faces unchanged.
ignore
↗def ignore(spec) -> DieRoll
Remap matching faces to 0 (convert(spec, 0)).
bucket
↗def bucket(scale: Scale, *bands) -> Outcomes
Label numeric totals using bands on scale, or pass cut list / bands to override.
DicePool methods
Face filters (keep / remove / convert / ignore), match counts (count), pool match probabilities (p_any / p_none / p_at_least), or total the pool. See API conventions.
sum
↗def sum() -> DieRoll
Add every die in the pool into one totalâturns dice_pool(4, 6) into the same idea as 4d6.
keep
↗def keep(spec) -> DicePool
Keep only matching faces on every die; drop others and renormalize each die.
remove
↗def remove(spec) -> DicePool
Drop matching faces on every die; renormalize each die.
convert
↗def convert(spec, to: int) -> DicePool
Remap matching faces to to on every die.
ignore
↗def ignore(spec) -> DicePool
Remap matching faces to 0 on every die.
count
↗def count(spec) -> DieRoll
Distribution of how many dice match spec.
order_stat
order_stat
↗def order_stat(k: int) -> DieRoll
middle_of
middle_of
↗def middle_of(keep: int) -> DieRoll
p_any
p_any
↗def p_any(*spec) -> float
P(at least one die matches the optional face spec).
p_none
p_none
↗def p_none(*spec) -> float
P(no die matches the optional face spec).
p_at_least
p_at_least
↗def p_at_least(k: int, *spec) -> float
P(at least k dice match the optional face spec).
bucket
↗def bucket(scale: Scale, *spec) -> Outcomes
Label the pool total using bands on scale (sums first).
Outcomes methods
Query named outcome bands (PbtA moves, graded success, etc.).
pmf
↗def pmf(label: str) -> float
Chance of landing on exactly this named outcome (one band on the ladder).
p_at_least
p_at_least
↗def p_at_least(label: str) -> float
Chance of this outcome or any better one on the scaleâe.g. âpartial success or full successâ.
p_at_most
p_at_most
↗def p_at_most(label: str) -> float
Chance of this outcome or any worse oneâe.g. âfailure or partial failureâ.
Scale methods
Build ordered outcome labels and optional numeric bands after scale().
step
↗def step(label: str, *band, early: bool = False) -> Scale
Append one outcome label (low â high). With no band, the step is for classify only.
With a band (IntBand or desugared ..6, 7..9, 10..), the step buckets numeric totals.
Bands may overlap: early steps (see early=True) are checked first, then other steps, each in declaration order.
Declaration order still defines ladder rank for p_at_least / p_at_most.