# Anydice cancelling dice

I'm trying a program on Anydice that uses d6s where 1-3 = minor success, and 4-6 = major success. After the roll of 1 to 3 of these, you roll a different d6 where on a 5 or 6 you cancel (Nix) a minor success. This is the program I've come up with after long hours of attempt:

W: {1:3, 2:3}
D: {0:4, 1:2}

function: W:n outcomes {
MAJOR: 0
MINOR: 0
SUCCESSES: 0
if W = 2 { MAJOR: 1 }
if W = 1 { MINOR: 1 }
SUCCESSES: MAJOR + MINOR
result: SUCCESSES
}

loop DICE over {1..3} {
TOTAL: 0
function: D:n cancels {
NIX: 0
if D = 0 { NIX: 0 }
if D = 1 { NIX: 1 }
result: NIX

loop THROW over {1..DICE} { TOTAL: TOTAL + [W dW outcomes] }

if [count 1 in TOTAL > 0] & [count 1 in NIX = 1] { TOTAL: -1 }
}

output TOTAL named "[DICE] D"
}


However I'm getting a

"syntax error: I was expecting a "}" somewhere, to end a code block."

But doesn't look like there are any brackets left to close. Can someone identify what is wrong with the program and enlighten me if there is a better way to do this?

• Welcome to RPG.SE! Take the tour if you haven't already, and check out the help center for more guidance. May 9 at 21:32

Your error message is from not terminating function (/code block) after a result. Other languages might just quietly never run code after returning a value, Anydice helpfully throws you an error message.

As for the rest of the code I'm afraid I'm having a hard time parsing how you're trying to solve it. No worries, we've all been there.

W: {1,2}
D: {0:2,1}

function: roll POOL:s nix NEG:n {
MINOR: (POOL = 1) - NEG
if MINOR < 0 { MINOR: 0}
result: MINOR + (POOL = 2)
}

loop N over {1..3} {
output [roll NdW nix 1dD] named "[N]d6"
}


An few important approaches employed here is that we're passing our W dice as a sequence (that's the :s). That means that when we compare it with a number, we get the count. Passing the NEG as a number means we get the sum of that roll (it doesn't make a difference for one die, but means it's there if you want to roll more of them).

So, we use a function to let us treat the roll as a pool, get the number of minor successes and subtract the number of nixes. Then we check and negate the case that there were more nixes than minor successes, and set the number of minor successes to 0 in that case. Then we return the sum of (remaining) minor and major successes.

Be careful thinking about output as print. While it may function that way, to really harness the power of Anydice (and in many cases generate sensible/correct outputs) it should call the function/roll to be analysed. When you call a function in an output expression, it is evaluated for all possible rolls of that function. That's kinda the thing that makes it work.

• Just to avoid a possible misunderstanding of your last paragraph, there's nothing special about the combination of output and function calls. Your output [roll NdW nix 1dD] does exactly the same thing as TOTAL: [roll NdW nix 1dD] followed by output TOTAL. The "magic" happens when you pass a die (or a collection of dice) to a function expecting a number (or a sequence), whether it happens in an output statement or anywhere else. May 9 at 20:34
• Thanks a lot for the thorough explanation and the tip about output/print (you too Ilmari!). Quick question though: when rolling 1 W die, if there is a chance of getting a 2 and that wouldn't be affected by a nix, why the program is not outputting 2s in that case? May 9 at 22:14
• @Dodecaheye Did you want it to? I was going by your code where you only care about the count of major and minor (I assume that's what the outcomes function is going for. Making Major successes count as double would be as simple as multiplying the (POOL = 2) element by 2. May 10 at 6:48
• @Someone_Evil ah understood, I guess I misunderstand value for weight! Thanks again May 10 at 14:46

When you define a result that's the end of the function. So your cancels-function ends at result: NIX, but the code block isn't ended with a }. The cancels-function isn't used anywhere either, so I'm not sure what you're trying to do.