O código faz o que você quer?
function: roll ROLL:s {
\ we assume that ROLL always has exactly two dice; AnyDice sorts them in descending order \
HI: 1@ROLL
LO: 2@ROLL
\ handle the special cases first \
if LO = 10 & HI = 10 { result: -1 } \ double 10 = "crit success/fail" \
if LO + HI = 20 { result: 20 } \ mirror pair = crit success \
if LO = HI { result: 0 } \ equal pair = crit failure \
\ at this point, we know there's no equal or mirror pair \
if [absolute LO - 10] < [absolute HI - 10] { result: LO } else { result: HI }
}
output [roll 2d20]
A saída, resumida, é assim:
Roll | AnyDice result | Probability
--------------+----------------+------------
Double 10 | -1 | 0.25 %
Crit success | 20 | 4.50 %
Crit fail | 0 | 4.75 %
Normal N < 10 | N | N - 0.5 %
Normal N = 10 | N | 9.5 %
Normal N > 10 | N | 19.5 - N %
Ou seja, exceto para os crits, você obtém o mesmo tipo de distribuição de probabilidade em forma de triângulo que para um teste normal de 2d20, exceto que neste caso o range de rolls normais é apenas de 1 a 19 (já que a única maneira o rolo mais próximo de 10 poderia ser 20 se você fizesse um double 20, mas isso é uma falha crítica).
Além disso, você pode ver que se um double 10 fosse considerado um sucesso crítico, então as probabilidades de um crit falhar e um sucesso crítico seriam exatamente 4,75%, ou seja, um pouco abaixo da chance de 5% de rolar 1 ou um nat 20 em 1d20. Essa simetria pode ou não ser algo que você gostaria de ter.
Na verdade, da maneira como organizei o código acima, você pode testar os efeitos dessa alteração simplesmente excluindo a linha "double 10" (já que, se essa linha não estiver lá, o código continuará no seguinte " par de espelhos "case". Claro, você também pode facilmente testar o efeito de lidar com um double 10 de outras maneiras (por exemplo, tratá-lo como um crit fail, ou apenas como um normal 10) simplesmente substituindo o valor do resultado -1
no código com qualquer outro número.