Without knowing the full rules, it's pretty hard to say, but this is the most obvious way: just store the progression in an array and look up by index. const steps = [ -12, -10, -8, -6, -4, -2, 2, 4, 6, 8, 10, 12, 20 ]; // Set the base 0 index to '-2' so that a skill of '1' represents the '2' const baseIndex = 5; const getDiceStep = (skill) => { const step = steps[Math.min(Math.max(skill + baseIndex,0), steps.length - 1)]; return `1d${step}`; } // Example character skill level and mod const characterSkill = 3; const modifier = 3; const exampleBaseRoll = getDiceStep(characterSkill); const exampleModifiedRoll = getDiceStep(characterSkill + modifier); console.log(exampleBaseRoll, exampleModifiedRoll); // Expected output: 1d6 1d12 If you're trying to put it straight into the dice parser without any javascript, it's going to get ugly. You'll need to use a formula for progression which means no steps based on physical dice, no real customisation. And some trickery for negative values. And no way of stopping 0 being a value when the modifier is a negative equal to the skill (without ruling out negative rolls): [[ [[floor((?{character_skill} + ?{Modifier|0})/99999)]]*1d[[abs((?{character_skill} + ?{Modifier|0})*2)]] ]] The ?{character_skill} queries are stand-ins for attributes, so you'd have @{character_skill} on a working sheet, instead of a query.