# Why won't AnyDice let me store dice rolls in variables?

I'm trying to emulate a "Fate-like" distribution that imitates 1d6-1d6. That's not really the point, so much as I don't understand the error it gives me.

function: ff {
BLUE: d6
RED: d6
if BLUE < RED {
result: BLUE
}
if BLUE > RED {
result: -RED
}
result: 0
}

output [ff] named "absolute"
output 1d6 - 1d6 named "1d6-1d6"
output 4d{-1,0,1} named "4dF"


• The code provided doesn't run; can you include the whole "program"? Or, better: can you cut away code to provide a minimal case that exhibits the issue (eg., the last two lines can trivially be removed)? Commented May 24, 2023 at 19:06
• This answer to an earlier question goes into some detail on this. Commented May 24, 2023 at 19:17

As I noted in an answer to an earlier question, a "die" variable in AnyDice represents a certain probability distribution over the integers.* Every time you use the die in an expression, AnyDice treats it as a separate, independent roll with that distribution.

DIE: 1d6
output DIE - DIE named "you'd think this should be zero, but it's not..."


If DIE represented a specific number rolled using 1d6, then DIE - DIE should always be zero. But it's not, as running the program above will easily demonstrate.

In fact, what's going on is that DIE here is just an alias for 1d6, so DIE - DIE is the same as 1d6 - 1d6; i.e. (the distribution of) the difference between two separate 1d6 rolls.

*) AnyDice variables can also store a "collection of dice" such as 3d6, which in some sense represents a probability distribution not just over single integers but over sequences of them. But only a very limited set of such distributions is supported: you can't even have a collection containing dice of two different types, much less a collection of a variable number of dice or a collection of dice whose values are not independent. And if you use such a collection of dice in a context where AnyDice expects a single number (or die), AnyDice will just convert the collection of dice into the probability distribution of their sum.

The fact that your RED and BLUE variables are probability distributions, rather than fixed numbers, is also why you're getting the error saying that "Boolean values can only be numbers".

(Again, I've mentioned this in a couple of answers before, but I quick recap might be useful.)

Basically, the error message means what it says — you can't do something like:

if d2 = 1 { \ do something \ } else { \ do something else \ }


because AnyDice would have to somehow execute both paths, since d2 can be either 1 or 2, and combine the resulting arbitrary program states into some kind of weird "quantum superposition". AnyDice is pretty clever, but it's not that clever.

What AnyDice is just smart enough to do, however, is call a function for every possible number (or sequence) you can roll on a particular die (or a collection of dice) and collect the results of the function back into a "custom die" (i.e. a probability distribution) weighted by their likelihood.

You can use this to "freeze" one or more dice by passing them into a function that expects a number (or a sequence) as a parameter, like this:

function: evaluate RED:n and BLUE:n {
if BLUE < RED {
result: BLUE
}
if BLUE > RED {
result: -RED
}
result: 0
}

output [evaluate d6 and d6]


Here, the :n after RED and BLUE in the function definition tells AnyDice that these parameter are supposed to be numbers (not sequences or dice). When you call the function and pass a die for such a parameter, AnyDice will automatically call the function with every number you could roll on the die and collect the results into a new probability distribution based on the how likely each roll is.

Thus, inside the function the parameters RED and BLUE are indeed fixed numbers, and you can use them in if conditions just fine.

(And yes, your mechanic indeed gives exactly the same distribution of results as simply subtracting one of the dice from the other. That's actually a rather interesting observation!)