[RPG] How to model Burning Wheel probabilities in AnyDice

anydiceburning-wheelstatistics

I have a basic intuition about dice in Burning Wheel, but it's handy to be able to look at actual probability distributions to hone your intuition. Especially since important rolls can involve exploding dice or rerolls, which both complicate the mental math a bit.

How can I represent Burning Wheel rolls, including open-ended dice and rerolls, in AnyDice?


Since this question calls for AnyDice mastery rather than deep understanding of BW as a system, here's a quick summary of what we need to model.

Burning Wheel uses a dice-pool system. A test involves rolling a set of d6s. For each die rolled:

  • Black shade ability (typical): 4-6 is a success
  • Gray shade ability: 3-6 is a success
  • White shade ability: 2-6 is a success

Adding up the successes gives you the total success number, which is then compared against the Obstacle to determine overall success or failure.

(For example, if I roll 4D vs. Ob 2, that means I want to roll 4d6, count the number that come up 4+, and then I've won the roll if I got at least two successes total.)

Additionally, you can spend character resources for these special tricks:

  • For a Fate point, you can make a roll "open-ended," so any sixes rolled will give you an extra die to throw in. Those extra dice also explode, &c., &c.
  • A Deeds point or Call-On allow a player to pick up all failed dice and reroll them.
  • (Here's the corner case: if you explode dice first and then reroll failures, only the original failed dice count; just discard any extras that don't count as successes.)

Best Answer

AnyDice handles exploding dice in a peculiar fashion that's poorly-suited for roll-and-count dice pools. I have cobbled together a somewhat inelegant solution, but it appears to work correctly.

Here's the link to the program.

Instead of using dice in the usual manner, I've created several functions that, given parameters of a die, return its output, i.e. the number of successes it has produced.

function: roll ROLL:n threshold T {
  if ROLL >=T {result: 1}
  result: 0
}

function: rollexploding ROLL:n threshold T{
  if ROLL =6 {result: 1+[rollexploding 1d6 threshold T]}
  result: [roll ROLL threshold T]
}

function: rerollfailures ROLL:n threshold T{
  if ROLL < T {result: [roll 1d6 threshold T]}
  result: [roll ROLL threshold T]
}

function: rerollthenexplode ROLL: n threshold T {
  if ROLL < T {result: [rollexploding 1d6 threshold T]}
  result: [rollexploding ROLL threshold T]
}

Then I made a wrapper function that would figure out which of these functions to call, and handle requests for multiple dice being rolled:

function: wrapper DICE:n threshold T explode E reroll R{
  RES:0
  loop N over {1..DICE} {
    if E & R {RES: RES+[rerollthenexplode 1d6 threshold T]}
    else {if E {RES:RES+[rollexploding 1d6 threshold T]}
      else {if R {RES:RES+[rerollfailures 1d6 threshold T]}
        else {RES:RES+[roll 1d6 threshold T]}
      }
    }
  }
  result:RES
}

Finally, I made a bunch of functions that simplify input by providing pre-determined combinations of parameters. I'll provide only 3 of them here:

function: b DICE:n{
  result:[wrapper DICE threshold 4 explode 0 reroll 0]
}

function: be DICE:n{
  result:[wrapper DICE threshold 4 explode 1 reroll 0]
}

function: gr DICE:n{
  result:[wrapper DICE threshold 3 explode 0 reroll 1]
}

To use it, type things like output [b 4]

Related Topic