Retorno decrescente simples com tampa


19

Problema

O jogador obtém 5 pontos por nível até o nível 80, com um máximo de 400. Existem 5 estatísticas a serem distribuídas e nenhum limite máximo para o quanto você pode adicionar a uma estatística.

  • Força
  • Resistência
  • Inteligência
  • Agilidade
  • Sorte - Concede chance crítica e dano crítico

Eu gostaria de implementar uma equação de retorno decrescente em, digamos, Sorte. Por chance crítica, eu não desejo que o jogador consiga atingir 100% de chance crítica.

Haverá um limite ao qual atingirá quando o crescimento cada vez menor diminuir para 0 por ponto adicionado.

Exemplo: se a chance máxima crítica que eu quero que o jogador tenha seja de 40%, cada ponto na sorte aumentará a chance crítica cada vez menor, até que a chance crítica atinja cerca de 40%. Pelo qual 1 sorte dará uma quantia muito, muito minúscula.

Alguma solução? Obrigado e sua ajuda é muito apreciada!


Possível duplicata de Como desenvolver fórmulas de dano de RPG? - tl; dr a palavra-chave que você procura é curva sigmóide
BlueRaja - Danny Pflughoeft

@BlueRaja Eu acho que não é uma duplicata. Esta pergunta é sobre funções de retorno decrescente em geral - essa é sobre cálculo de danos. Por acaso, as respostas para essa questão discutiram principalmente funções de retorno decrescente, mas acho que as perguntas ainda são claramente diferentes.
Anko

Respostas:


30

Você quer começar com uma função assintótica. Ou seja, um que começa em um número ae se aproxima de outro número b, mas nunca chega a alcançá-lo. Provavelmente será mais fácil se a = 0e b = 1. Você pega essa equação, insere o número de pontos de estatística (pontos de sorte) que o personagem possui e obtém o valor real de estatística (Chance Crítica) como a saída.

Um exemplo muito simples é y = x / (x + n)onde nestá uma constante positiva. Aqui xestá sua entrada, onde você alimenta o número de pontos estatísticos e yé sua saída, onde obtém o valor final.

Para n = 5verificar como é:

y = x / (x + 5) plotagem para x em [0,100]

Quando você se alimenta, x = 0você chega y = 0, mas não importa o tamanho que xvocê coloca, ynunca chega a 1. Perfeito.

Agora, você pode sintonizar isso com o desejo do seu coração. Você pode multiplicar por um fator de escala para definir o 'limite' para o que quiser. y = a * x / (x + 5). Se você deseja que o limite seja de 40%, multiplique por 0,4. y = .4 * x / (x + n). Agora, quando você se alimentar x, yaumentará, mas nunca alcançará 0,4.

Ajuste npara definir o quão rápido ou lento a equação aumenta. n = 100vai aumentar muito mais devagar que n = 5:

y = plotagem de x / (x + 100) para x em [0,400]

Você pode resolver essa equação nse souber que deseja o valor de estatística que deseja atingir em um número específico de pontos de estatística. Digamos que o personagem tenha 35% de chance de crítico em 100 pontos de sorte. Resolução .35 = .4 * 100 / (100 + n)de nrendimentos n = 14.29.

Esses números também não precisam ser constantes brutas. Talvez outras estatísticas entrem no cálculo dos valores de n. Talvez alguns personagens tenham caracteres diferentes n, de modo que eles se adaptem melhor ao seu status 'preferido'.

Se você deseja uma curva com formato diferente ou mais complexo, existem muitos outros exemplos de funções assintóticas que você também pode usar. Vou deixar você explorar isso como quiser.


3
Minha curva favorita é a exponencial. Basta ter uma proporção fixa da piscina restante em cada nível.
John Dvorak

@ JanDvorak, por uma questão de integridade, você pode fornecer um exemplo? Existem muitas curvas exponenciais e um leitor pode não saber como aplicar sua sugestão apenas no comentário anterior.
Adam

Este é um bom ponto de partida e a matemática é bem explicada, mas lembre-se de que você não pode simplesmente escolher uma função que pareça boa; esse problema requer uma análise cuidadosa e muitos ajustes. Por exemplo, uma das desvantagens deste método é o desencorajamento da especialização. Se todas as cinco estatísticas forem igualmente viáveis, os pontos gastos na menos desenvolvida serão os mais valiosos (e o menos desenvolvido). A construção ideal seria uma distribuição igual de pontos, o que torna a escolha do jogador em como gastá-los menos interessante.
Marcks Thomas

@MarcksThomas Isso presume que não há sinergia entre atributos ou capacidade de isolar taticamente um atributo e "vencer" com ele. Como exemplo, imagine um arqueiro incrível que aumenta sua agilidade a ponto de os inimigos morrerem antes de alcançá-los: mesmo que a agilidade tenha diminuído a eficácia, a tática escolhida torna os outros atributos sem importância. Outra tática envolvendo força pode ser igualmente eficaz, de modo que os atributos são de "valor igual", mas as táticas geralmente significam que a especialização é dominante. Se o seu sistema de atributos também recompensa a especialização, o jogo diverge.
Yakk

Eu chamo isso de sistema "tirar pedras da sacola". O valor P = x/(x+n)é a probabilidade, dada uma bolsa com n pedras negras ex pedras brancas, que você desenhe uma pedra branca para fora da bolsa cega. Uma abordagem que você pode fazer é definir os critérios X = sua sorte e N = a sorte deles. Sua chance de crit é de 50% se você tiver a mesma sorte que seu inimigo. Se você deseja que a chance de base seja 10%, então X = sua sorte, N = 9x a sorte deles.
Yakk

10

Uma boa base seria uma função arctan, pois passa pela origem e exibe uma assíntota horizontal.

arctan

Dimensione-o por 40 / (pi/2)ou 80/pipara o limite desejado. Em seguida, transforme luckpara obter a inclinação da curva desejada.

critical = 80/pi * arctan(f(luck))

8

Eu realmente gosto da maneira como os jogos do Souls lidam com esse problema. Em vez de fazer com que cada estatística dê bônus com base em uma função contínua, como foi sugerido, ela oferece bônus em uma função linear por partes.

Não me lembro dos números exatos em cima da minha cabeça, mas as funções estão ao longo das linhas a seguir (cada estatística tem suas próprias constantes)

{0 <= x <20: y = 4x, 20 <= x <30: y = 3x + 20, 30 <= x <40: y = 2x + 50, 40 <= x <60: y = 1x + 90 , 60 <= x: y = 0,5x + 120}

Enredo

Este método oferece muitos benefícios para o designer e o player. O designer se beneficia, pois você pode ajustar o benefício exato por ponto em uma habilidade de maneira bastante trivial, e o jogador se beneficia por saber exatamente quanto benefício verá de nível para nível.

No caso de uma função contínua, alguns níveis podem oferecer um benefício que não é refletido nos números devido ao alias de medição. Claro que o último nível deu a você um aumento de 0,9 no bônus XYZ, mas como o valor real passou de 23,52 para 24,42, e você arredondou o número antes de exibi-lo, o jogador não percebe que algo mudou.

Da perspectiva do UX, eu definitivamente sugeriria uma função linear por partes. No entanto, o uso de uma função contínua pode ser mais fácil de ajustar posteriormente, pois os jogadores não estarão tão ligados às constantes redondas.


11
Aproximação de uma curva que não requer muita matemática e simples de alterar. Eu gosto disso. :)
Casey Kuball

> você arredonda o número antes de exibi-lo => uma maneira de compensar é ceilo valor do aumento antes da adição e permite apenas níveis de número inteiro. ou floorentão, x <= 0: x = 1para evitar passar acidentalmente a tampa macia.
20915 Bob

11
Embora você ainda possa executar uma função por partes, ela não tem o efeito que você está procurando aqui. O valor da sorte é uma porcentagem, com um máximo de 400 classificações. Isso significa que todo ponto de classificação deve resultar em um ganho abaixo de 1% no valor, mesmo em uma função linear com 100% de sorte. O truque está apenas mostrando pontos decimais suficientes para que y (399) seja diferente de y (400). Sua função faz a mesma coisa, aumentando y muito, para que os aumentos sempre sejam integrais. Em x = 40, y é mais de 4 vezes o valor de x.
quer

@MichaelS Eu estava apenas dando um exemplo do tipo de função usada em Dark Souls. Ele precisaria ser balanceado de maneira diferente, dependendo da situação em que for aplicado, mas meu argumento ainda é que os jogadores entenderão o efeito de uma função linear por partes muito mais facilmente do que uma curva ou seção cônica arco-tangente.
21415 Kaslai

3

Jan Dvorak aponta a função exponencial em um comentário. Eu vou explicar aqui.

Observe que as operações exponenciais (e trigonométricas) são consideravelmente mais caras em termos computacionais do que as operações de raiz quadrada, que são muito piores que a matemática básica, então você provavelmente estará melhor com a abordagem de Adam se fizer esses cálculos muitas vezes por segundo . Se você apenas calcula os valores quando o jogador nivela, troca de equipamento etc., a velocidade não é importante, então use o que lhe der a melhor curva.

Uma função exponencial é alguma base, B , a alguma potência, x , y=B^x. Os matemáticos geralmente usam uma base de e , (~ = 2.718), mas não há razão para que você não possa usar 2 ou 10, se preferir.

y=e^x se parece com isso: y = e ^ x

Observe que o lado esquerdo está se movendo assintoticamente para 0. Portanto, podemos girar o eixo x fazendo y=e^(-x) , mas ele ainda está descendo de 1 a 0 e queremos que ele suba. Para que possamos rodar no eixo y com y=-e^(-x) . Agora está subindo de -1 a 0. Podemos adicionar 1 para obter y=1- e^(-x) e está subindo de 0 a 1.

y = 1-e ^ (- x)

A partir daqui, é apenas uma questão de dimensioná-lo vertical e horizontalmente. Podemos multiplicar a coisa toda por algum valor, vamos chamá-la de A , que define o limite assintótico. Então podemos multiplicar x por um valor de taxa de variação, k , para ajustar a rapidez com que ela se aproxima do limite.

Isso nos dá uma equação final de y=A*(1 - e^(-k*x)). Usando valores de k=0.012e A=0.5, podemos definir o limite para 50% e deixá-lo bem próximo desse limite x=400.

y = 0,5 * (1-e ^ (- 0,012 * k))

Agora, você pode fazer alguns ajustes nisso. Um ajuste que fiz foi mudar para A=0.5041, portanto, se arredondarmos para uma porcentagem com 2 casas decimais (como 32,23%), y (399) = 49,99% e y (400) = 50,00%. A partir de y (347), existem vários locais em que são necessários dois pontos para obter uma variação de 0,01%. Mas esse último ponto possível ainda oferece um benefício (quase) tangível e chega a 50%.

Como alternativa, poderíamos ajustar o kvalor para ter um efeito semelhante. Em k=0.02305, o valor é arredondado para 49,99% em y=399e 50,00% em y=400. No entanto, isso tem o problema de que o gráfico é muito raso no final - são necessários 48 pontos para obter o último centésimo de por cento (de y(352)=49.99%para y(399)=49.99%até y(400)=50.00%) e a última chance de 1% de crítico leva 230 pontos (de y(170)=49.01%para y(400)=50.00%) o que provavelmente diminui demais os retornos.

Se você quiser, poderá ajustar A e k, para diminuir para um limite um pouco mais alto a uma taxa mais lenta, para fornecer algo entre decaimento linear e exponencial. Fazendo y=0.6*(1-e^(-0.00447*x)), você acaba com isso: y = 0,6 * (1-e ^ (- 0,00447 * x))

Observe que a curva continua além de 50%, mas como existe um limite rígido de 400 pontos, o jogador não pode passar por esse ponto (e se conseguirem passar por ele, ainda há um limite rígido de 60% de crítico). Com esta equação, você pode usar 1 casa decimal e ainda ver ganhos a cada 2 a 3 pontos, com uma marca final de y(399)=49.9%até y(400)=50.0%.

Matematicamente, as equações anteriores podem parecer melhores, uma vez que estão se aproximando de 50%, mas pessoalmente acho que ganhos de 0,1% a cada par de pontos são melhores do que ganhos de 0,01%. Mesmo com A=0.05041e k=0.012, são necessários 102 pontos para passar de y(298)=49.00%para y(400)=50.00%. 25% dos seus pontos gastos em 2% do seu crítico provavelmente estão diminuídos demais. A equação de 60% leva apenas 20 pontos para o último percentual (que ainda é 5 vezes maior que os 4 pontos necessários para o primeiro percentual).

Com essas últimas equações, apenas as pluguei em uma planilha e ajustei manualmente os valores até que parecessem bons. Você teria que fazer algo semelhante se quisesse um limite diferente.


2
A nota sobre a velocidade relativa das operações matemáticas está correta, mas provavelmente irrelevante para as estatísticas dos jogadores. Os gargalos nos jogos modernos costumam lidar com muitos milhares de itens por quadro (por exemplo, física e renderização). É improvável que scripts de jogabilidade que provavelmente executam algumas dezenas de vezes por quadro sejam um pontinho em relação a isso, e geralmente estão cheios de erros de cache de qualquer maneira, o que deixará a CPU bastante tempo para mexer no polegar para fazer as contas que quiser. tl; dr: Não se sinta pressionado para evitar ops caros menos que você está shaders escrita ou outras coisas que precisa ser executado enormes lotes
DMGregory

-1

Para uma solução muito simples, que tal raiz quadrada x 2

A raiz quadrada de 400 (máximo possível) é 20, 20 * 2 = 40.


Por que o voto negativo? Ele resolve a pergunta e é simples, o que também foi solicitado.
Catwood

11
Eu não sou o defensor do voto negativo, mas provavelmente foi porque sua resposta é excessivamente específica e não fornece nenhuma informação que ainda não foi fornecida (uma raiz quadrada é apenas exponenciação do poder de 1/2) e você não explica o razões pelas quais isso poderia ser útil.
Kaslai

Não reduzi o voto, mas não acho que seja uma boa resposta, porque não é muito flexível - a raiz quadrada não é assintótica; portanto, se o nível máximo mudar, você precisará alterar a fórmula para manter o máximo stat o mesmo.
BlueRaja - Danny Pflughoeft
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.