# How do I use AnyDice with Classic World of Darkness / 20th Anniversary?

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;

if (WILLPOWER) SUCCESS++;

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);
else
output "Fail.\t" + tally(SUCCESS, FAILURE);
}

function string tally(int S, int F)
{
return (SUCCESS - FAILURE) + "\t(" + SUCCESS + " - " + FAILURE + ")";
}

• 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 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
}

DIFFICULTY: 7

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.                                             \
MAXSUCCESS: 10
SUPERSUCCESSROLLS: {11}
if SPECIALIZED {
MAXSUCCESS: 9
SUPERSUCCESSROLLS: {10}
}
SUCCESSROLLS: {TARGET..MAXSUCCESS}
BOTCHROLLS: {1}

\ Count how many of each type (successes, botches, super successes) \
SUPERSUCCESSES: [count SUPERSUCCESSROLLS in ROLL]
SUCCESSES: [count SUCCESSROLLS in ROLL]
BOTCHES: [count BOTCHROLLS in ROLL]

\ How many successes does this count as? \
FINALSUCCESSES: SUCCESSES+(SUPERSUCCESSES*2)+WILLPOWER

\ 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 BOTCHES > FINALSUCCESSES {
\ If there are more botches than successes, then we simply fail \
result: 0
}
result: FINALSUCCESSES-BOTCHES
}

output [owod roll 2d10 target 8 specialized 1 willpower 0]
output [owod roll 2d10 target 8 specialized 1 willpower 1]

• 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. – Ilmari Karonen Aug 3 '18 at 20:38
• Ilmari: I think your improvement deserves its own answer! – 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"
}