Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

Copyright and other protections apply. Please see the accompanying LICENSE file for rights and restrictions governing use of this software. All rights not expressly waived or licensed are reserved. If that file is missing or appears to be modified from its original, then please contact the author before viewing or using this software in any capacity.

Tests Version License Supported Python versions Bear-ified™

Now you’re playing with …

dyce logo

dyce

dyce is a Python library for dice mechanics and other problems with a finite set of possible outcomes. It counts how many ways each outcome can occur, then calculates exact probabilities.

Suggested audiences and applications:

  • Game designers for crafting and compare game mechanics
  • Tool developers for using calculations in higher level tooling

Overview

  • H represents possible outcomes and their weights as integer counts. A fair, six-sided die can be represented as H({1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1}), or the shorthand H((1, 2, 3, 4, 5, 6)), or simply H(6). The sum of three six-sided dice can be represented as 3 @ H(6).
  • P represents an ordered sequence of histograms. A pool of three separate six-sided dice can be represented as 3 @ P(H(6)), or the shorthand 3 @ P(6). Ps keep each die separate, so you can select any die or group of dice and calculate the distribution of their summed results.
  • P.survey and expand are experimental interfaces useful for modeling mechanics where an outcome of one die affects how others are included. Examples include: exploding dice, conditional re-rolls, or damage that depends on whether an attack hits.
  • Optional Matplotlib and Plotly helpers support visualization.

Example: d20 versus a “target number”

Consider a mechanic popularized by one of the world’s roll playing games1 where a roll on a (typically dodecahedral) twenty-sided die “succeeds” when it is greater than or equal to a specific value (a “target number”). This example compares the outcome distributions for one d20, the higher of two d20s (“advantage”), and the lower of two d20s (“disadvantage”).

>>> from dyce import H, P
>>> d20 = H(20)  # shorthand for an evenly-weighted 20-sided die
>>> d20
H({1: 1, 2: 1, 3: 1, ..., 18: 1, 19: 1, 20: 1})
>>> p2d20 = 2 @ P(d20)  # a pool of two such dice
>>> d20_advantage = p2d20.at(-1)  # right-most index (-1) selects highest
>>> d20_disadvantage = p2d20.at(0)  # left-most index (0) selects lowest
>>> d20_advantage
H({1: 1, 2: 3, 3: 5, ..., 18: 35, 19: 37, 20: 39})
>>> d20_disadvantage
H({1: 39, 2: 37, 3: 35, ..., 18: 5, 19: 3, 20: 1})

With a single d20, the chance of rolling a 15 or higher is 30%. With advantage, it climbs to 51%. With disadvantage, it drops to 9%.

>>> target_number = 15
>>> # How often a d20 is greater than or equal to target_number
>>> d20_vs_target = d20.ge(target_number)
>>> print(d20_vs_target.format())  # built-in text formatting
  avg |    0.30
  std |    0.46
False |  70.00% |#################################
 True |  30.00% |##############
>>> d20_advantage_vs_target = d20_advantage.ge(target_number)
>>> print(d20_advantage_vs_target.format_short())
{avg: 0.51, False: 49.00%, True: 51.00%}
>>> d20_disadvantage_vs_target = d20_disadvantage.ge(target_number)
>>> print(d20_disadvantage_vs_target.format_short())
{avg: 0.09, False: 91.00%, True:  9.00%}
Plot: Comparison of the higher of 2d20 vs. a single d20 and the lower of 2d20 vs. a single d20

Run this example in JupyterLite: Try `dyce`!

As one might expect, with a single d20, each outcome is equally likely, with 10.5 being the average. With advantage, one is likely to roll at least a 15 over half the time, and one is nearly twice as likely to roll a 20. With disadvantage, one is likely to roll at most a 6 over half the time, and one is nearly twice as likely to roll a 1.

Installation

python -m pip install dyce

dyce supports CPython 3.11–3.15 and PyPy 3.11-3.12. It depends on optype for static and runtime type-checking. dyce is available under the MIT License.

dyce will opportunistically use the following, if available:

Explore further

Other efforts

dyce does not stand alone. Other works include:

Please consider contributing an issue if you observe discrepancies or think something should be added to the list.

Donors

When one worries that the flickering light of humanity may be snuffed out at any moment, when one’s heart breaks at the perverse celebration of judgment, vengeance, and death and the demonizing of empathy, compassion, and love, sometimes all that is needed is the kindness of a single stranger to reinvigorate one’s faith that—while all may not be right in the world—there is hope for us human beings.

  1. Hat tip (or profuse apologies) to the Angry GM who is not only one of the world’s greatest role playing game masters, but a remarkably reflective human being for whom I have a tremendous amount of respect and gratitude. ↩

Metadata

Release files for dyce 0.7.0rc12

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for dyce 0.7.0rc12
File Size Uploaded
dyce-0.7.0rc12.tar.gz 1.0 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for dyce 0.7.0rc12
File Interpreter ABI Platform
dyce-0.7.0rc12-py3-none-any.whl Python 3 none any Details

Total release size: 1.1 MB

Release files / dyce-0.7.0rc12.tar.gz

Download URL dyce-0.7.0rc12.tar.gz
Size 1.0 MB
Tags Source
SHA-256 checksum
How to use checksums
297d71341720a49493e8c82a3df228f1c67c890ce4f910700581ad1b88ac538c
BLAKE2b-256 checksum
How to use checksums
5fa3af61ca7a9801b41d81ee34e55e8cf41ff76feab88003cbfd983d25ca11f6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.

Transparency log

Release files / dyce-0.7.0rc12-py3-none-any.whl

Download URL dyce-0.7.0rc12-py3-none-any.whl
Size 70.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9859db42debfe4fa3183f28c36bd66c6e823975f0fe1a061f9553942760b2bbc
BLAKE2b-256 checksum
How to use checksums
8abf16dad5bc750ab70de38af9013617b5a34ece5cdcc53e511d12658c573b92
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.

Transparency log
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page