Skip to main content

Compute outcome probabilities for Risus: The Anything RPG

Project description

This is a simple set of functions to compute probabilities for Risus: The Anything RPG.

Risus was designed by S. John Ross and is currently published by Big Dice games: https://www.risusrpg.com/

builds.sr.ht status

Installing

This project is on pypi at https://pypi.org/project/risus-py/. It can be installed thus:

pip install risus-py

This risus.engine depends on icepool (https://highdiceroller.github.io/icepool/), and risus.table depends on numpy and pandas. These should all be automatically installed by pip.

Testing

All the modules are tested from their docstring examples. After installation, you can execute the tests by running risus as a module:

python3 -m risus

If all goes well, this should appear to hang for an instant and return nothing. It will complain in case of a problem.

Development

Clone the git repository.

git clone https://git.sr.ht/~p0mf/risus-py

When trying out new features, I use pip install -e to install an editable copy of risus in a virtual environment:

pip install -e .

I build risus-py using the PyPA build (https://github.com/pypa/build) module and upload it to PyPI using twine (https://twine.readthedocs.io/en/stable/):

python3 -m build && twine upload dist/*

This monster is the entire release pipeline: it installs locally, tests, then builds for distribution and uploads.

pip install -e . && python -m risus && rm -rf dist/* && python -m build && twine upload dist/*

Wishlist

Features

  • Pumps and double pumps.
  • Factor out rule variations (explosions, breakthroughs).
  • Web application using pyodide and chart.js, like the other icepool applications.

Efficiency

  • Parallelized computation, and other optimizations. Is it possible to do better than quadratic time (in the maximum value of the potencies considered) when constructing a table?

Polish

  • Clean up documentation: there's still some quirkiness to the way the README is integrated into the module documentation. Given how easy it is to pull up documentation locally with pdoc, static site hosting is a low priority.
  • Rationalize rules variations: for now, the engine passes around a whole mess of configuration flags.

Infrastructure

  • Automate build test and release, potentially as a continuous integration job on sourcehut.

Basic API Calls

See the documentation for the module for an overview of possible calls. It can be accessed with pdoc (https://pdoc.dev/), from your terminal once risus-py has been installed. This command will open the documentation in your default browser:

pdoc risus

In short, there are functions to compute win/loss chances for combat, team_combat (including inappropriate clichés), single_action_conflict, and target_number rolls. All the calls return float, and take a bool argument percent to indicate whether the returned value should be scaled 0 to 100 (True) or 0 to 1 (False). The default is False.

Tables

More complex variations are possible: the risus.table module contains function to generate xarrays of victory probabilities. The file app/dataset.py is an example of simple web interface using dtale. Here are some example tables.

Combat:

Ordinary

As an example, here is how you could calculate an ordinary combat table for up to (10) versus (10).

>>> import pandas as pd
>>> from risus.table import make_combat_table
>>> make_combat_table(10, percent=True).round(1).to_pandas()

enemy_potency      1      2      3      4      5      6     7     8     9     10
attack_potency
1                50.0    5.0    0.1    0.0    0.0    0.0   0.0   0.0   0.0   0.0
2                95.0   50.0    8.2    0.3    0.0    0.0   0.0   0.0   0.0   0.0
3                99.9   91.8   50.0   10.5    0.7    0.0   0.0   0.0   0.0   0.0
4               100.0   99.7   89.5   50.0   12.2    1.1   0.0   0.0   0.0   0.0
5               100.0  100.0   99.3   87.8   50.0   13.7   1.5   0.1   0.0   0.0
6               100.0  100.0  100.0   98.9   86.3   50.0  14.8   1.9   0.1   0.0
7               100.0  100.0  100.0  100.0   98.5   85.2  50.0  15.8   2.3   0.1
8               100.0  100.0  100.0  100.0   99.9   98.1  84.2  50.0  16.7   2.7
9               100.0  100.0  100.0  100.0  100.0   99.9  97.7  83.3  50.0  17.5
10              100.0  100.0  100.0  100.0  100.0  100.0  99.9  97.3  82.5  50.0

Boxcars and Breakthroughs

A similar series of manipulations produces one with boxcars and breakthroughs in effect.

>>> make_combat_table(10, percent=True, breakthrough=True).round(1).to_pandas()

enemy_potency      1      2      3      4      5      6     7     8     9     10
attack_potency
1                51.6    9.4    0.6    0.0    0.0    0.0   0.0   0.0   0.0   0.0
2                95.2   52.3    9.6    0.5    0.0    0.0   0.0   0.0   0.0   0.0
3                99.9   92.2   50.9   10.9    0.7    0.0   0.0   0.0   0.0   0.0
4               100.0   99.7   89.7   50.3   12.4    1.1   0.0   0.0   0.0   0.0
5               100.0  100.0   99.4   87.8   50.1   13.7   1.5   0.1   0.0   0.0
6               100.0  100.0  100.0   98.9   86.4   50.0  14.8   1.9   0.1   0.0
7               100.0  100.0  100.0  100.0   98.5   85.2  50.0  15.8   2.3   0.1
8               100.0  100.0  100.0  100.0   99.9   98.1  84.2  50.0  16.7   2.7
9               100.0  100.0  100.0  100.0  100.0   99.9  97.7  83.3  50.0  17.5
10              100.0  100.0  100.0  100.0  100.0  100.0  99.9  97.3  82.5  50.0

Single-action conflict:

The function make_single_action_conflict_table takes a number representing to size of the square table to produce.

Ordinary

enemy_potency      1      2      3      4     5     6     7     8     9     10
attack_potency
1                50.0   10.0    1.2    0.1   0.0   0.0   0.0   0.0   0.0   0.0
2                90.0   50.0   16.3    3.7   0.6   0.1   0.0   0.0   0.0   0.0
3                98.8   83.7   50.0   20.5   6.3   1.5   0.3   0.0   0.0   0.0
4                99.9   96.3   79.5   50.0  23.5   8.6   2.6   0.6   0.1   0.0
5               100.0   99.4   93.7   76.5  50.0  25.7  10.7   3.7   1.1   0.3
6               100.0   99.9   98.5   91.4  74.3  50.0  27.5  12.6   4.9   1.6
7               100.0  100.0   99.7   97.4  89.3  72.5  50.0  28.9  14.2   6.0
8               100.0  100.0  100.0   99.4  96.3  87.4  71.1  50.0  30.1  15.7
9               100.0  100.0  100.0   99.9  98.9  95.1  85.8  69.9  50.0  31.2
10              100.0  100.0  100.0  100.0  99.7  98.4  94.0  84.3  68.8  50.0

Boxcars and Breakthroughs

enemy_potency               1      2      3      4     5     6     7     8     9     10
attack_potency
1                         51.6   18.2    6.9    2.7   1.1   0.0   0.0   0.0   0.0   0.0
2                         90.0   50.0   17.4    5.4   2.1   0.9   0.4   0.1   0.1   0.0
3                         98.8   83.7   50.0   20.6   6.5   1.8   0.6   0.3   0.1   0.1
4                         99.9   96.3   79.5   50.0  23.5   8.6   2.6   0.7   0.2   0.1
5                        100.0   99.4   93.7   76.5  50.0  25.7  10.7   3.7   1.1   0.3
6                        100.0   99.9   98.5   91.4  74.3  50.0  27.5  12.6   4.9   1.6
7                        100.0  100.0   99.7   97.4  89.3  72.5  50.0  28.9  14.2   6.0
8                        100.0  100.0  100.0   99.4  96.3  87.4  71.1  50.0  30.1  15.7
9                        100.0  100.0  100.0   99.9  98.9  95.1  85.8  69.9  50.0  31.2
10                       100.0  100.0  100.0  100.0  99.7  98.4  94.0  84.3  68.8  50.0

Target number:

Here's a target number table for games with big pumpers: you feelin' lucky, punk?

attack_potency     1      2      3      4      5      6      7      8      9      10     11     12
enemy_potency
1               100.0  100.0  100.0  100.0  100.0  100.0  100.0  100.0  100.0  100.0  100.0  100.0
2                83.3  100.0  100.0  100.0  100.0  100.0  100.0  100.0  100.0  100.0  100.0  100.0
3                66.7   97.2  100.0  100.0  100.0  100.0  100.0  100.0  100.0  100.0  100.0  100.0
4                50.0   91.7   99.5  100.0  100.0  100.0  100.0  100.0  100.0  100.0  100.0  100.0
5                33.3   83.3   98.1   99.9  100.0  100.0  100.0  100.0  100.0  100.0  100.0  100.0
6                16.7   72.2   95.4   99.6  100.0  100.0  100.0  100.0  100.0  100.0  100.0  100.0
7                 0.0   58.3   90.7   98.8   99.9  100.0  100.0  100.0  100.0  100.0  100.0  100.0
8                 0.0   41.7   83.8   97.3   99.7  100.0  100.0  100.0  100.0  100.0  100.0  100.0
9                 0.0   27.8   74.1   94.6   99.3   99.9  100.0  100.0  100.0  100.0  100.0  100.0
10                0.0   16.7   62.5   90.3   98.4   99.8  100.0  100.0  100.0  100.0  100.0  100.0
11                0.0    8.3   50.0   84.1   96.8   99.5  100.0  100.0  100.0  100.0  100.0  100.0
12                0.0    2.8   37.5   76.1   94.1   99.0   99.9  100.0  100.0  100.0  100.0  100.0
13                0.0    0.0   25.9   66.4   90.2   98.0   99.7  100.0  100.0  100.0  100.0  100.0
14                0.0    0.0   16.2   55.6   84.8   96.4   99.4   99.9  100.0  100.0  100.0  100.0
15                0.0    0.0    9.3   44.4   77.9   93.9   98.8   99.8  100.0  100.0  100.0  100.0
16                0.0    0.0    4.6   33.6   69.5   90.4   97.8   99.6  100.0  100.0  100.0  100.0
17                0.0    0.0    1.9   23.9   60.0   85.5   96.2   99.3   99.9  100.0  100.0  100.0
18                0.0    0.0    0.5   15.9   50.0   79.4   93.9   98.6   99.8  100.0  100.0  100.0
19                0.0    0.0    0.0    9.7   40.0   72.1   90.6   97.6   99.5   99.9  100.0  100.0
20                0.0    0.0    0.0    5.4   30.5   63.7   86.3   96.1   99.1   99.9  100.0  100.0
21                0.0    0.0    0.0    2.7   22.1   54.6   80.8   93.9   98.5   99.7  100.0  100.0
22                0.0    0.0    0.0    1.2   15.2   45.4   74.3   90.9   97.5   99.5   99.9  100.0
23                0.0    0.0    0.0    0.4    9.8   36.3   66.8   87.0   96.1   99.1   99.8  100.0
24                0.0    0.0    0.0    0.1    5.9   27.9   58.6   82.1   94.0   98.4   99.7   99.9
25                0.0    0.0    0.0    0.0    3.2   20.6   50.0   76.2   91.3   97.5   99.4   99.9
26                0.0    0.0    0.0    0.0    1.6   14.5   41.4   69.5   87.7   96.1   99.0   99.8
27                0.0    0.0    0.0    0.0    0.7    9.6   33.2   62.0   83.3   94.2   98.4   99.6
28                0.0    0.0    0.0    0.0    0.3    6.1   25.7   54.0   78.0   91.7   97.5   99.4
29                0.0    0.0    0.0    0.0    0.1    3.6   19.2   46.0   71.8   88.4   96.2   99.0
30                0.0    0.0    0.0    0.0    0.0    2.0   13.7   38.0   65.0   84.3   94.4   98.3
31                0.0    0.0    0.0    0.0    0.0    1.0    9.4   30.5   57.6   79.5   92.0   97.5
32                0.0    0.0    0.0    0.0    0.0    0.5    6.1   23.8   50.0   73.9   89.0   96.2
33                0.0    0.0    0.0    0.0    0.0    0.2    3.8   17.9   42.4   67.6   85.3   94.6
34                0.0    0.0    0.0    0.0    0.0    0.1    2.2   13.0   35.0   60.8   80.9   92.4
35                0.0    0.0    0.0    0.0    0.0    0.0    1.2    9.1   28.2   53.6   75.8   89.6
36                0.0    0.0    0.0    0.0    0.0    0.0    0.6    6.1   22.0   46.4   70.0   86.2
37                0.0    0.0    0.0    0.0    0.0    0.0    0.3    3.9   16.7   39.2   63.6   82.2
38                0.0    0.0    0.0    0.0    0.0    0.0    0.1    2.4   12.3   32.4   56.9   77.4
39                0.0    0.0    0.0    0.0    0.0    0.0    0.0    1.4    8.7   26.1   50.0   72.1
40                0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.7    6.0   20.5   43.1   66.2
41                0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.4    3.9   15.7   36.4   59.9
42                0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.2    2.5   11.6   30.0   53.3
43                0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.1    1.5    8.3   24.2   46.7
44                0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.9    5.8   19.1   40.1
45                0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.5    3.9   14.7   33.8
46                0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.2    2.5   11.0   27.9
47                0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.1    1.6    8.0   22.6
48                0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.9    5.6   17.8
49                0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.5    3.8   13.8
50                0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.3    2.5   10.4
51                0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.1    1.6    7.6
52                0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.1    1.0    5.4
53                0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.6    3.8
54                0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.3    2.5
55                0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.2    1.7
56                0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.1    1.0
57                0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.6
58                0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.4
59                0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.2
60                0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.0    0.1

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

risus-py-0.1.0.tar.gz (26.7 kB view details)

Uploaded Source

Built Distribution

risus_py-0.1.0-py3-none-any.whl (24.8 kB view details)

Uploaded Python 3

File details

Details for the file risus-py-0.1.0.tar.gz.

File metadata

  • Download URL: risus-py-0.1.0.tar.gz
  • Upload date:
  • Size: 26.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.10.7

File hashes

Hashes for risus-py-0.1.0.tar.gz
Algorithm Hash digest
SHA256 84bb17ab40b1b3c1f992ad6932ae39f385fdd833bfe30c6d2a7ab348ee5ba68a
MD5 16893001c45a9a298465a222275c51ad
BLAKE2b-256 926eb11d6f7961c5f14ba1eada630e9cdfc2b3e36296d8fb5335b4fa7cc703a1

See more details on using hashes here.

Provenance

File details

Details for the file risus_py-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: risus_py-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 24.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.10.7

File hashes

Hashes for risus_py-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e4c46b8691aac113589782b74fc45664c3a7f9059e2d69927866d100da17fa63
MD5 4b65d5216f3de090dc3e60e14f1d09a4
BLAKE2b-256 3fa8829e1440c4ae4a429a40486fb091bb5309919fcfb78ce8d036482bc3e93c

See more details on using hashes here.

Provenance

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page