I'll join a Song of Ice and Fire RPG campaign soon. The system - by Green Ronin - uses a d6-based roll-and-keep mechanism for tests; the procedure for a regular test for a certain ability is
- to roll N dice, where N is equal to your ability score;
- to roll K bonus dice (if any), resulting from specialties or from assistance received;
- discard the lowest-scoring K dice, leaving N;
- sum the results;
- apply any applicable modifiers;
- check if you met or exceeded the difficulty level for the test, and (if you did) by how much.
Let's ignore modifiers, which really only change the difficulty of a test. Working out your chance of success as a function of the difficulty level is easy enough when there's no bonus dice, but what if they're there?
The sum you compute is a sum of order statistics for an iid sample of discrete uniform RVs, so in principle it's possible to work out the distribution using statistical methods, but it's complicated because the order statistics are not stochastically independent, and I'm not a statistician.
An alternate way of solving the problem is to simply generate all possible rolls and apply the above recipe to each to see what the outcome is. I did this in MATLAB; execution time is no problem, but once you start having high scores and/or numbers of bonus dice, memory becomes an issue. Is this an issue in practice? Unfortunately, yes, since having up to 7 bonus dice is apparently contemplated by the rules (see table 9-1 on p. 155 of the rulebook if you have it), and abilities can reach up to 7 for humans, so in theory you could be throwing 14 six-sided dice, with 78,364,164,096 possible results. (Actually, with that amount of data execution time might start to be noticeable too.)
And that's not even talking about different systems; if you have a roll-and-keep system that uses 20-sided rather than 6-sided dice, an exhaustive solution would also quickly break down.
Fortunately there's combinatorics, and fortunately someone worked out the solution:
tecmologist posted a solution in 2010, and
another user (I'm leaving out the name since it's a real name) asked about it in 2012. The latter post contains a correction as well (the upper limit of the sum in the expression for N(B; C, D)), and is readily implemented.
While implementing this I had to take care of some more corner cases: in addition to defining N(0; 0, D) = 1, as tecmologist did, you have to set N(B; 0, D) = 0 if B is greater than zero (distributing a non-zero amount of balls among zero cells is impossible), and the upper limit of the sum should actually be min(floor(B/(D+1)), C), as far as I can tell. With these changes made, the formula from the StackExchange post yields the same results as the exhaustive calculation when the latter are possible, but of course it extends to cases where they're not. For instance, if you're curious about what your chances of success are when do indeed have an ability score of seven and up to seven bonus dice, here you go:
Just to be sure BTW, this of course an extremely unrealistic situation. My character, for instance, has no abilities exceeding four and no bonus dice pools exceeding two; and difficulties of 21+ are already considered Heroic, so the range plotted here is really just to show the shapes of the curves. But still!
BTW, I mentioned that it also matters by how much you exceed a test's difficulty. This is defined in terms of your test result minus the difficulty; each five points of difference give you one additional level of success (on top of the one you get for passing the test in the first place). The maximum number of degrees of success is four, and the ranking is Marginal - Great - Incredible - Astonishing.
Plotting this is also interesting. Here's how your chances are for each for the unrealistic case of an ability score of 7 again:
(This is without bonus dice; I've not updated my script to combine both sorts of calculations yet.)
Getting back to the case where bonus dice are included, another useful article is
this one by possiblywrong, from 2019. It's got less detail than the one by tecmologist (although it may have been inspired by that), but it has code in Python if that's your poison.