Role-playing Games Stack Exchange is a question and answer site for gamemasters and players of tabletop, paper-and-pencil role-playing games. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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 + ")";
share|improve this question
Have you looked over the documentation? – Joshua Aslan Smith Jun 5 '14 at 21:59
@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. – redlamp Jun 5 '14 at 22:13
@redlamp: Does my answer below accomplish what you're looking for? – Alan De Smet Jul 4 '14 at 1:04
@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. – redlamp Aug 3 '14 at 16:42

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

\ 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]
share|improve this answer
up vote 2 down vote accepted

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.

— Taylor Wright (@redlamp) June 6, 2014

@redlamp Don't use a mega function, break it up.

— 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 \
share|improve this answer

Not a perfect solution, but you can start off from this program:

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"
share|improve this answer
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! – SnakeDr68 Jun 6 '14 at 0:38
While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. – okeefe Jun 6 '14 at 4:06
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? – doppelgreener Jun 6 '14 at 8:47

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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