Nth Die of 5D20 Plus Bump & Meta Die mechanic help #12
-
Hey posita, thanks for your help with my D20 dicepool plus roll points mechanic. I am not totally satisfied with that mechanic So I am evaluating another one, this one is fairly novel, So I am running into problems on the scripting. The Mechanic Your dice are split between Standard dice, and bump dice. Specify which is which. Your dicepool is made up of 1 to 5 standard dice and 0 to 4 bump dice, in a combination of 5. The number your roll is determined from your stat, and follows a die code progression. The dice code is shown as xD+yB#N Where xD is the number of standard dice, yB is the number of bump dice, and #n Is your 'Set Die' Which die of the 5 you read to determine your result. A stat of 0 corresponds to 5D+0B#1 So now that we got our dice we roll them we then sort the 5 dice lowest to highest, left to right, with each 'die slot' corresponding to #n number at the end of the die code. Easy enough, then we have the bump dice rule. If your set die is a bump die, you bump 1 slot to the right, the next higher die to determine your result. YOu only ever bump once, and to the right, ever. No chaining bumps, no matter how many bump dice are in your pool. THis gives us more granularity, but also makes the odds hard to calculate. Also, when sorting the dice, bump dice take the rightmost slots if you have equal numbers. A quick example. My stat is 13, so I have a dicepool of 2D+3B#3. Which means I roll 2 standard dice, 3 Bump dice (all twenty sided btw.) and take the die in the 3rd die slot as my result die. If I rolled a 1 5, 7, 10, 13 I would take the die in the 3rd slot, the 7 and use it as my result. However, in this case it is a bump die, thus I bump 1 slot to the right and use the 10 result in the 4th die slot. Even though it is a bump die, I don't get to bump again, only one bump, ever. YOu also roll a sixth die, The meta die, if the meta die matches your (bumped) set die, your set die explodes, reroll and add the result to your running die total. If it matches the meta die again, you roll and add again, and so on. The meta die also generates side results Boons and Banes, on a 1 and 20, independent of success on the check. if the Meta Die comes up a 1, the action generated a bane, a negative circumstance. If it came up a 20, it generated a Boon, an positive circumstance, kind of like Genesys' system. ONly the match die and explosion is particularly important for our needs. So if my meta die came up a 10 on the previous roll, a 1 5, 7, 10, 13 I would reroll the 10 bumped set die, and add the result to a running die total. If it came up 10 again, it would match the meta die (which is never rerolled) and I would reroll and add again. If it came up a 20, I'd be done rolling since it doesn't match the meta die, but my die total would be a whopping 40. (10+10+20=40) OK so that complicates things. I don't have enough python chops to properly handle the Match die explosions and the semi-indepdeent nature of the Bump die. THis was very easy to handle in Troll I used an indepedent D5 to determine if your die was a bump die. I.e with 1D+4B#3, you have an 80% chance of it being a bump die and bumping to the die result in the 4th slot. so I was checking 4 or less on D5 then take die result at 4th slot, otherwise 3rd slot. Pretty easy logic. Finally, to represent Higher Scale/Superhuman abilities, you add up to 5 boost dice or spoiler dice, Boost dice are extra bump dice, of which after you roll, you take the 5 dice with the highest results rolled as you dicepool, setting aside the others. While spoiler dice are extra standard dice you add to your dicepool. up to 5 extra, and take the 5 lowest to figure your results as normal. So A LOT of complication and chrome on the basic idea. Which, once you pick the concept is pretty fast and relatively low math, just sort, read and go. So if you could help me figure up the odds with some nice visualizations I;d appreciate it Incidentally, I swiped the basic mechanic concept from a very old RPG.net design forum post. Which I can't find right now, though my implementation is different. thank you for any help. |
Beta Was this translation helpful? Give feedback.
Replies: 5 comments 24 replies
-
@wmrobmuadib, apologies for being unresponsive. (Busy summer.) I think I understand (at least some of) the mechanic. I can work on a representation, but I wanted to check to see if this was still relevant to you, or if you had moved onto something else? This is going to be a bit tricky, since you're keeping track of a numeric result as well as the presence of a boon/bane. There are technical solutions to this, but very few are likely to be satisfying visually. I have some ideas, but time will tell if they pan out.... |
Beta Was this translation helpful? Give feedback.
-
Questions:
|
Beta Was this translation helpful? Give feedback.
-
Another stupid question without the benefit of additional context: Why is five a good pool size? Why not three? |
Beta Was this translation helpful? Give feedback.
-
The good news is that I have several working implementations (one using just from dyce import H
from dyce.evaluation import explode
from fractions import Fraction
d20 = H(20)
limit = Fraction(1, 10_000)
# See <https://posita.github.io/dyce/0.6/dyce.evaluation/#dyce.evaluation.explode> for a
# more thorough explanation, but basically, this will tell explode to continue branching
# until the overall likelihood of any branch of outcomes is less than or equal to 1 in
# 10,000
print(explode(d20, predicate=lambda result: result.outcome == 3, limit=limit))
print(explode(d20, predicate=lambda result: result.outcome == 14, limit=limit)) Running the above will yield:
Visually: Here's what I get with my work-in-progress implementations for your first five stats without explosions:
Visually: When calculating results with even just a single explosion, my
Visually: So not a huge difference, but noticeable. These were all generated locally using Python running directly on my (reasonably modern) laptop. Unfortunately, this means that trying to produce these in-browser (e.g., via Pyodide/Jupyter Lite) will likely take roughly five times as long, which would likely render useless any attempt at an interactive UI that could compare multiple stats. I'm happy to try to throw something together though, if you think it would be useful? Either way, I'll post my implementations as soon as I have an opportunity to clean them up a bit. |
Beta Was this translation helpful? Give feedback.
-
Okay, I think I have something reasonably close, but it will very likely not perform adequately with (dis)advantages of three or more. (As of this writing, advantage calculations take substantially longer than disadvantage calculations with both implementations, but I haven't dug in to figure out the source of the disparity.) There's a I will say, it is one of the more complicated implementations for a single dice mechanic I've seen, which likely makes performance optimizations difficult without something bespoke to this mechanic. That said the I also provided a crude, regex-based notation parser for a format that loosely resembles what I proposed in #12 (reply in thread). I haven't tested it, but you could probably adapt it to one resembling your own with something like: NOTATION_RE: ClassVar = re.compile(
r"""
^
(?:\[(?P<override>[^]]+)\])?\s*
(?P<std>[1-9]\d*)\s*D\s*
\+
(?P<bump>(?:[1-9]\d*)?\d)\s*B\s*
\#\s*
(?P<bonuses>(?:[1-9]\d*\s*/\s*)*) # one-indexed (not zero-) for readability
(?P<set>[1-9]\d*)\s* # one-indexed (not zero-) for readability
(?:<\s*(?P<ex_std>[1-9]\d*)|>\s*(?P<ex_bump>[1-9]\d*)\s*)?
(?:\#\s*(?P<comment>.*))?
$
""",
re.IGNORECASE | re.VERBOSE,
)
BONUS_RE: ClassVar = re.compile(
r"(?P<bonus>[1-9]\d*)\s*/\s*", re.IGNORECASE | re.VERBOSE
) That should support notations like:
There's a browser version , but, it's probably better in this case to run it natively (for performance reasons). If you have Docker installed, this is probably the quickest path to get started: docker pull jupyter/scipy-notebook:latest
git clone https://github.com/posita/dyce-notebooks.git dyce-nb
docker run --name jupyterlab-dyce --publish 8888:8888 --interactive --tty --mount "type=bind,src=${PWD}/dyce-nb,target=/home/jovyan/work/dyce-nb" After opening the link provided printed on startup, you should be able to navigate to |
Beta Was this translation helpful? Give feedback.
Okay, I think I have something reasonably close, but it will very likely not perform adequately with (dis)advantages of three or more. (As of this writing, advantage calculations take substantially longer than disadvantage calculations with both implementations, but I haven't dug in to figure out the source of the disparity.)
There's a
dyce
-based implementation and an attempt at anicepool
-based implementation. As of this writing theicepool
implementation is not very efficient, though. I'm wondering if I'm using the library effectively, or if it's an artifact of dealing with multiple pools and not having a short circuit mechanism (see HighDiceRoller/icepool#81), or ... ? Also included is…