How can I take advantage of AnyDice with 20th Anniversary rules? I'm new to AnyDice but very interested in using it.

I would like a wrapper function that accepts the following params.

  • the number of dice to roll
  • the action's difficulty
  • optional: a willpower being spent for a success.
  • optional: a character having a relevant specialty, allowing for second success on 10's.

If the dice pool is higher than difficulty I'd like and indication for automatic success.

Dice mechanics

  • Roll Xd10 against target difficulty, dice equal to or greater than the difficulty are successes.
  • Rolling 10's
    • are always successes.
    • count as 2 successes, if the character has a relevant specialty.
  • Rolling 1's
    • each 1 negates a success down to failure.
    • if there were no successes rolled, the action is botched.
  • optional: before rolling you may spend 1 willpower for an additional success.
    • you can only spend 1 willpower per turn.
  • optional: if Xd10 is greater than the target difficulty you can take the action as an automatic success.
    • not usable in stressful situations.
    • only counts for 1 success.
    • you can roll, or take the automatic success, but not both.

Success results

  • 5 Phenomenal
  • 4 Exceptional
  • 3 Complete
  • 2 Moderate
  • 1 Marginal
  • 0 Failure
  • -1: Botch (only possible when no successes are present)

Psuedocode (this is a loose sketch of what I have in mind)

function roll(int POOL, int DIFFICULTY, bool WILLPOWER, bool SPECIALTY, bool AUTO_SUCCESS = true)
  int  _roll = 0;
  int  SUCCESS = 0;
  int  FAILURE = 0;
  bool BOTCH = false;


  for (int i = 0; i < POOL; i++)
    _roll = 1d10;
    if (_roll >= DIFFICULTY) SUCCESS++;
    if (SPECIALTY && _roll == 10) SUCCESS++;
    if (_roll == 1) FAILURE++;
  if (SUCCESS == 0 && FAILURE > 0) BOTCH == true;

  if (BOTCH)
    output "Botch!\t" + tally(SUCCESS, FAILURE);
  else if (SUCCESS > FAILURE)
    output "Pass.\t" + tally(SUCCESS, FAILURE);
    output "Fail.\t" + tally(SUCCESS, FAILURE);

function string tally(int S, int F)
  return (SUCCESS - FAILURE) + "\t(" + SUCCESS + " - " + FAILURE + ")";
  • \$\begingroup\$ Have you looked over the documentation? \$\endgroup\$ – Joshua Aslan Smith Jun 5 '14 at 21:59
  • \$\begingroup\$ @JoshuaAslanSmith I have, I've also looked over AnyDice questions here as well. I'm not sure how to attain what I'm looking for based on the code I've seen so far. I'm a programmer by trade, so if I could get a little help with formatting I should be able to take it the rest of the way. \$\endgroup\$ – redlamp Jun 5 '14 at 22:13
  • \$\begingroup\$ @redlamp: Does my answer below accomplish what you're looking for? \$\endgroup\$ – Alan De Smet Jul 4 '14 at 1:04
  • \$\begingroup\$ @AlanDeSmet I'm sorry for the delay on posting this answer from the created of AnyDice. I hadn't had much chance to test it until now. \$\endgroup\$ – redlamp Aug 3 '14 at 16:42

I ended up getting a tweet from the creator of AnyDice with an optimized solution. The function names are clear and it works quickly.

@catlikecoding Hey Jasper, could you help me with an #AnyDice question? I'm still learning the ropes with the system. http://t.co/H0qMhIaIGD

— Taylor Wright (@redlamp) June 6, 2014

@redlamp Don't use a mega function, break it up. http://t.co/anUMab5ByK

— Jasper Flick (@catlikecoding) June 6, 2014

The code sample:

function: roll ROLL:s {
 if 1@ROLL < 1 & (#ROLL)@ROLL = -1 {
  result: -1
 result: [highest of 0 and ROLL]

function: roll ROLL:n with willpower {
 result: [highest of 0 and ROLL + 1]

function: specialty N:n {
 if N = 10 { result: 2 }
 if N = 1 { result: -1 }
 result: N >= DIFFICULTY


NORMAL: d{-1:1, 0:(DIFFICULTY - 2), 1:(11 - DIFFICULTY)}

SPECIALTY: [specialty d10]

X: 4

output [roll X d NORMAL] named "normal"
output [roll X d SPECIALTY] named "speciality"
output [roll X d NORMAL with willpower] named "normal willpower"
output [roll X d SPECIALTY with willpower] named "speciality willpower"
\ automatic success is automatic, nothing to show \

I believe the following accomplishes what you want. I left out marking automatic success since it is an entirely different situation.

Warning: this is slow. 1d10 through 7d10 are fine. 8d10 and 9d10 take about 30 seconds for me. 10d10 never finished. I don't think it can be optimized further given the functionality available in AnyDice.

You can try this code out immediately at http://anydice.com/program/3d98

\ Old Storyteller rules (Original World of Darkness) die rolling       \

\ Created by Alan De Smet in 2014. Released into the public domain to  \
\ the fullest extent possible.  This comes WITHOUT ANY WARRANTY.  You  \
\ are asked, but not required, to credit Alan De Smet.                 \

\ Input:                                                               \
\ ROLL - Dice to roll. Only "<something>d10" is meaningful.            \
\ TARGET - the target number. Only "2-10" are meaningful.              \
\ SPECIALIZED - "1" if specialized, "0" if not                         \
\ WILLPOWER - "1" if willpower is spent, "0" if not                    \

\ Output:                                                              \
\ -1    Botch. No successes, at least one 1                            \
\  0    Failure                                                        \
\  1+   Number of successes after subtracting a success for each       \
\             1 rolled.  If at least one success was rolled, 1s cannot \
\             take this below 0.                                       \

\ Example:                                                             \
\ [owod roll 5d10 target 8 specialized 0]                              \

\ Limitations:                                                         \
\ Scales poorly to large numbers of dice. 9d10 takes about 30 seconds. \
\ 10d10 may not work at all.                                           \

function: owod roll ROLL:s target TARGET:n specialized SPECIALIZED:n willpower WILLPOWER:n {

  \ I use "BOTCH" to mean a roll of 1, which isn't how  Storyteller    \
  \ defines it. A super success is a roll of 10 when specialized.      \

  \ Build up lists of which numbers are successes, botches, and  \
  \ super successes.                                             \

  \ Count how many of each type (successes, botches, super successes) \

  \ How many successes does this count as? \

  \ If zero successes and at least one botch, the roll is a botch \
  if (FINALSUCCESSES = 0) & (BOTCHES > 0) {
    \ If you want to know how badly you botched, uncomment the \
    \ next line: \
    \ result: -BOTCHES \
    result: -1
    \ If there are more botches than successes, then we simply fail \
    result: 0

output [owod roll 2d10 target 8 specialized 1 willpower 0]
output [owod roll 2d10 target 8 specialized 1 willpower 1]
  • 1
    \$\begingroup\$ Here's an optimized version of your code. It gives the exact same results (and in fact uses your original unmodified code internally), but adds a wrapper function that relabels the sides of the d10s to reduce the number of irrelevant combinations. With the optimization, even 10-die pools run basically instantly. \$\endgroup\$ – Ilmari Karonen Aug 3 '18 at 20:38
  • \$\begingroup\$ Ilmari: I think your improvement deserves its own answer! \$\endgroup\$ – Alan De Smet Aug 8 '18 at 14:41

Not a perfect solution, but you can start off from this program: http://anydice.com/program/e5f

function: nwod R:n again N:n {
 if N >= R { result: 1 + [nwod R again d10] }
 result: N >= 8

NWOD: [nwod 10 again d10]

loop N over {1..10} {
 output [lowest of 10 and NdNWOD] named "[N]d"
  • 2
    \$\begingroup\$ Welcome to RPG.SE onitek. In general, on RPG.SE link only answers are frowned upon. I'd suggest taking a look at the tour to get an idea how the site operates, then the help center to get answers to any specific questions. For this particular answer, it could be improved by telling (a) exactly what the link is and how it qualifies as an answer to the question and (b) why it's not a perfect solution. If you can't answer those adequately, you might look into deleting your answer as not to attract downvotes. Again welcome, and enjoy the site! \$\endgroup\$ – Chuck Dee Jun 6 '14 at 0:38
  • 3
    \$\begingroup\$ I've added the source to this answer. Would you care to explain what this program does (or what it doesn't do that makes it imperfect) as wraith808 asked? \$\endgroup\$ – doppelgreener Jun 6 '14 at 8:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.