The trick to modelling these kinds of dice pool mechanics efficiently in AnyDice is to make use of the fact that each die in the pool is rolled and counted (and possibly rerolled) independently of the others.

This allows us to first calculate the probability distribution of successes for a single die of each size, and save it as an AnyDice “custom die”. We can then add together any combination of these custom dice to get the distribution of successes for any dice pool.

So, let’s see how to actually do that. First, we need a function that will calculate the success distribution for one die. If we didn’t have the explosion mechanic, this would be really easy to do — just something like:

```
function: roll ROLL:n target TARGET:n {
result: ROLL >= TARGET
}
output (roll d6 target 5) named "single d6, no explosions"
```

The trick here is that, when you call a function expecting a numeric parameter (i.e. one marked with `:n`

) but actually pass in a die (like `d6`

) instead, AnyDice will automatically call your function for every possible result of rolling the die and collect the results into a new custom die.

Actually, for the simple example above we could’ve just done `output d6 >= 5`

and skipped the function entirely. But we’re going to need a function to implement the explosion mechanic anyway. The new trick there is that we can have the function call itself recursively when an explosion occurs, e.g. like this:

```
function: roll ROLL:n target TARGET:n explode MAX:n limit LIMIT:n {
if ROLL = MAX & LIMIT > 0 {
result: (ROLL >= TARGET) + (roll dMAX target TARGET explode MAX limit LIMIT-1)
} else {
result: (ROLL >= TARGET)
}
}
output (roll d6 target 5 explode 6 limit 3) named "single d6, max 3 explosions"
```

Note how I’m reducing the `LIMIT`

parameter by one for every nested function call, thus ensuring that the rerolls will stop when the limit goes down to 0. Also note that I’m using the `MAX`

parameter for two different purposes: both to specify the roll on which a reroll should happen and to define the size of the die used for the reroll. I could’ve used separate parameters for those, but that would’ve made the function call even more verbose.

Anyway, now that we have a function that lets us roll a single die of any size and count the number of successes, we can do the for each of the die sizes and save the results as custom dice:

```
PROTAGONISM: 2
SIX: (roll d6 target 5 explode 6 limit PROTAGONISM)
EIGHT: (roll d8 target 5 explode 8 limit PROTAGONISM)
TEN: (roll d10 target 5 explode 10 limit PROTAGONISM)
```

And then we can roll any combination of those custom dice that we want to get the distribution of success counts:

```
output 2dSIX + 2dEIGHT + 1dTEN named "2d6 + 2d8 + 1d10, protagonism (PROTAGONISM)"
```

And there we have it. Here’s what the output of the complete program looks like:

One minor detail worth noting in the complete program linked above is that I also added in the line:

```
set "maximum function depth" to PROTAGONISM + 1
```

Normally AnyDice limits the number of nested function calls to 10, and it turns out that this isn’t *quite* enough if you set `PROTAGONISM`

to 10. Setting the limit to one more than the protagonism value is sufficient for our purposes.

However, it also turns out that the protagonism value really doesn’t have all that much effect is practice. For example, if we run the code above in a loop for all protagonism values from 1 to 5 and plot the results as graphs, they look like this:

Notice how all the graphs are basically drawn right on top of each other, and that the mean success count shown in the legend is also almost the same for all of them (approximately 2.56 for protagonism 1, 2.60 for protagonism 2 and 2.61 for all higher values).

Basically this is because getting more than one reroll in a row is very unlikely — a one in 36 chance for two consecutive rerolls on a d6, less for bigger dice and *much* less for longer chains of rerolls. So basically, while it might feel really awesome to get the rare triple explosion on a roll, it happens so rarely that it doesn’t really make any difference to the averages. And with your success counting mechanic, the reward isn’t even all that much — all a reroll gives you is a (chance for) a single extra success point, which may not even make any difference if you’re not just under the difficulty target.

Honestly, I’d recommend either rethinking the protagonism mechanic to give better rewards, or get rid of it completely and just allow unlimited rerolls.