Okay, I can explain how it works with the Blades sheet, it should be straightforward to add an extra case for number of dice < 0. Basically, whenever the number of action dots changes, a sheet worker runs that sets an attribute (let's call it prowl_formula) to the value returned by the buildRollFormula function below. const diceMagic = function (num) {
if (num > 0) {
return `dice=${
[...Array(num).keys()].map(() => "[[d6]]").join("&"+"#44"+"; ")
}`;
} else {
return "zerodice=[[d6]]&" + "#44" + "; [[d6]]";
}
};
const buildRollFormula = function (base) {
return ` {{?{Bonus dice|${
[0, 1, 2, 3, 4, 5, 6, -1, -2, -3].map(n => `${n},${diceMagic(n + (parseInt(base) || 0))}`).join("|")
}}}}`;
}; E.g. on("change:prowl", () => {
getAttrs(["prowl"], v => {
setAttrs({
"prowl_formula": buildRollFormula(v["prowl"])
});
});
}); The attribute prowl_formula will then have a built-in query asking for bonus dice from -3 to 6. Depending on what the sum of bonus dice and skill is, the value sent to chat after the user answers the query will be either "{{zerodice=[[d6]], [[d6]]}}" (for <= 0) or something like "{{dice=[[d6]], [[d6]], [[d6]]}}". This part is calculated by the diceMagic function (where you'd have to add extra logic treating 0 and less than 0 differently). Now, the roll button for Prowl just includes the value of the prowl_formula attribute, which is then interpreted by the roll template. The reason to have "dice" and "zerodice" here ist that they both display differently, with some extra text appearing if we send zerodice. The corresponding part in the roll template looks similar to this: {{#dice}}{{dice}}{{/dice}}{{#zerodice}}
<div class="zerodice">{{zerodice}}</div>
<div class="zerodice2" data-i18n="zerodice"></div>
{{/zerodice}} You could send something like "{{negativedice=1}}" and add some extra logic here that displays "Failure" when that one is sent, instead of dice or zerodice. Extra remarks Since you said that you're not familiar with Javascript or coding for Roll20, I thought I'd explain two things: [...Array(num).keys()].map(() => "[[d6]]") There's no magic here. This just produces an array with num elements, all of which are the string "[[d6]]" The reason I use "&"+"#44"+"; " all over the place is that this is the HTML code for a comma. This is necessary because commas are syntactically relevant in Roll20 query expressions, so I have to escape them if I want them to be used in the query results.