Vamos calcular tudo no servidor
Devido a natureza dos jogos online, é muito importante que o servidor seja a fonte da verdade, ou seja, o servidor é quem vai calcular tudo, e o cliente vai apenas mostrar o que o servidor calculou. Mas não seria melhor calcular no cliente? Assim economizamos dinheiro com servidores.
Sim, no mundo ideal isso seria muito vantajoso. Mas no mundo real os usuarios são maliciosos e podem alterar o código fonte que roda no navegador para trapacear no jogo. Por exemplo, se o cliente calculasse o dano que o jogador recebe, o jogador poderia alterar o código fonte para que o dano que ele recebe seja 0, assim ele nunca morreria.
Existem exceções, se nós estivessimos fazendo um client que é protegido, ou seja os usuarios não tivessem acesso ao código fonte poderiamos sim fazer o client calcular algumas coisas, mas de novo ainda seria possivel criarem cheats para o jogo e ai teriamos outro problema criar anti-cheats para o jogo. O que torna inviavel.
Nesse caso é melhor mantermos o calculo todo no servidor e o client apenas mostrar o que o servidor calculou.
Controller ou Banco de dados
Existem varias formas de gerenciar essas mecanicas, podemos delegar todo o peso de fazer os calculos pro banco usando funções e passando os parametros assim o banco ja retornaria para nós tudo calculado e a regra de negócios não ficaria na API, por mais que eu ache essa uma abordagem interessante, ela demanda muito conhecimento de banco de dados e tem o fato que a hora de processamento do banco de dados é muito mais cara que a hora de processamento do servidor, então vamos manter na API mesmo.
Calculando status
Os status como Critico, Dano, Velocidade de Ataque, etc... São calculados toda vez que o usuario muda um equipamento ou adiciona um ponto de atributo.
Critico = 5 + (Sorte / 12)
Velocidade de Ataque (Ataques por segundo) = 1 + (Agilidade / 100)
Dano = 5 + (Força / 5)
Poder Magico = 5 + (Inteligencia / 5)
Vida = 100 + (Fé * 2.75)
Chance de Esquiva (%) = 1 + (Agilidade / 100)
Defesa = (Vida + (Força / 10) + (Inteligencia / 5)) / (4 - Chance de Esquiva)
Mana = 100 + (Inteligencia * 2.75)
Multiplicador de Critico = 2 + (Força / 100)
Esses calculos são arbitrarios, mas você pode alterar eles como quiser para deixar o jogo mais balanceado.
Calculando dano DPS
Agora vamos a parte mais complexa, calcular o dano por segundo (DPS) do jogador, para isso vamos usar a seguinte formula:
DPS = ((Dano + Poder Magico) _ Velocidade de Ataque) _ (Chance de Critico * Multiplicador de Critico)
Esse numero vai dizer quanto de dano o jogador vai dar por segundo, mas ele sozinho não é tudo ele serve só como base para calcularmos quanto de dano o jogador é capaz de causar no adversario, quanto maior o DPS maiores as chances de vitória contra o oponente.
Skills
Para facilitar o calculo vamos considerar que cada skill do jogador adiciona um valor fixo de DPS, Defesa, Vida, Critico, etc... Por exemplo, se o jogador tiver uma skill que adiciona 10 de dano, vamos considerar que o jogador tem 10 de dano a mais, se o jogador tiver uma skill que adiciona 10 de defesa, vamos considerar que o jogador tem 10 de defesa a mais.
O jogador poderá escolher as skills que quiser antes da batalha, desde que ele tenha mana suficiente.
Calculando porcentagens de chance
Agora que temos o DPS do jogador, vamos calcular as porcentagens de chance de vitoria e derrota.
Primeiro calculamos a chance bruta de cada oponente:
chanceBrutaOp1 = (DPS - defesaOponente * 0.25) / vidaOponente;
chanceBrutaOp2 = (DPSOponente - defesa * 0.25) / vida;
Depois aplicamos o fator RNG de cada oponente:
chanceRngOp1 = chanceBrutaOp1 + RNG;
chanceRngOp2 = chanceBrutaOp2 + RNGOponente;
Normalizamos as chances:
somaChances = chanceRngOp1 + chanceRngOp2;
chanceNormalizadaOp1 = (chanceRngOp1 / somaChances) * 100;
chanceNormalizadaOp2 = (chanceRngOp2 / somaChances) * 100;
Por fim calculamos as chances de vitoria e derrota:
chanceVitoriaOp1 = chanceNormalizadaOp1;
chanceDerrotaOp1 = 100 - chanceVitoriaOp1;