¿Cómo puedo calcular el nivel actual del XP total, cuando cada nivel requiere proporcionalmente más XP?

33

En mi juego, el XP necesario para alcanzar el siguiente nivel es Nivel actual × Umbral de nivel . Teniendo en cuenta eso, ¿cómo puedo obtener mi nivel actual del XP total obtenido?


Por ejemplo:

Level Threshold = 50
Current Level = 1

Comenzando en el nivel 1, necesitaría (1 × 50) = 50 XP para llegar al nivel 2, y así sucesivamente.

Level 1: 50 XP needed to reach level 2
Level 2: 100 more XP needed to reach level 3
Level 3: 150 more XP needed to reach level 4

En otras palabras, la tabla de progresión es la siguiente:

Level 1: 0 XP to 49 XP
Level 2: 50 XP to 149 XP 
Level 3: 150 XP to 299 XP
Level 4: 300 XP to 499 XP

Si tengo 300 XP, llegaré al nivel 4. ¿Cómo puedo calcular eso en general?

Jay van Diyk
fuente
Relacionado con Desbordamiento de pila: Cálculo de una raíz triangular sin sqrt
Damian Yerrick
La cantidad de XP requerida para el siguiente nivel no aumenta cuanto más alto sea el nivel actual.
Mástil
Bueno, la primera pregunta que debe responder es: ¿Cuál es el valor de "umbral" para cada nivel? Según su ejemplo, si suponemos que 300 XP es el mínimo para alcanzar el nivel 4, entonces su umbral aumenta a 75 después del nivel 3. Una vez que determina la frecuencia con la que aumenta el umbral, puede encontrar un algoritmo para calcularlo. , como las otras personas están tratando de hacer en sus respuestas
Taegost
3
Majte da una buena respuesta sobre cómo calcularlo, pero la "mejor" respuesta es simplemente no calcularlo ... almacenar la experiencia general, sino también el nivel actual y el delta de XP. Restablezca el delta cada vez que suba de nivel y tenga toda la información que necesita (nivel, nivel + 1, total xp, delta xp) para calcular fácilmente todo lo que necesita usar / mostrar
Jon Story
@JonStory De hecho. Elaboré sobre esto un poco en mi respuesta porque, bueno, que en realidad calcula dinámicamente el nivel todo el tiempo? Esta pregunta es, en esencia, solo una pregunta matemática, ya que no considera en absoluto el papel de los niveles dentro de un sistema de juego.
zxq9

Respuestas:

33

Al resolver las matemáticas y resolver la Levelcondición condicional de la experiencia XP, obtenemos:

Lmivmil=1+1+8×XPAGS÷502

Por ejemplo, ¿cuál es el nivel del jugador para ?XPAGS=300

1+1+8×300÷502=4 4

De acuerdo a lo pedido.

¿O para qué es el nivel XP = 100000?

1+1+8×100000÷502=63

En términos más generales, para un umbral de inicio arbitrario en el Nivel 1:

Lmivmil=1+1+8×thrmisholre÷502

También puede hacer lo contrario y calcular lo XPnecesario para cualquier nivel dado resolviendo la fórmula anterior para XP.

XPAGS=(Lmivmil2-Lmivmil)×thrmisholre2

Tenga en cuenta que la fórmula anterior funciona con fracciones, pero debe redondear al siguiente valor entero. Por ejemplo, en C ++ / C # podría usar (int) Level.

Para obtener la fórmula de forma cerrada anterior, utilicé ecuaciones de diferencia, suma de Gauss y una fórmula cuadrática.

Si está interesado en la solución de esta fórmula paso a paso ...

Hacemos un algoritmo recursivo comenzando nuestras consideraciones que finalmente Experience(next_level) = Experience(current_level) + current_level*50.

Por ejemplo, para obtener tenemos:XPAGSLmivmil3

XPAGSLmivmil3=XPAGSLmivmil2+2×50

Donde, 2*50proviene de la solicitud del OP que la experiencia necesaria para alcanzar el siguiente nivel es el nivel actual * 50.

Ahora, sustituimos con la misma lógica en la fórmula. Es decir:XpagsLmivmil2

Sustituya en la fórmula anterior:XPAGSLmivmil2=XPAGSLmivmil1+2×50

XpagsLmivmil3=XpagsLmivmil1+1×50+2×50

y es solo 50, que es nuestro punto de partida. Por lo tantoXpagsLmivmil1

XpagsLmivmil3=50+2×50=150

Podemos reconocer un patrón para calcular recursivamente niveles más altos y una cadena finita de sumatorias.

XpagsLmivmilnorte=50+2×50+3×50+...+(norte-1)×50=yo=0 0norte-1yo×50

Donde N es el nivel a alcanzar. Para obtener el XP para el nivel N, necesitamos resolver para N.

XpagsLmivmilnorte÷50=yo=0 0norte-1yo

norte×(norte+1)÷2-norte

XpagsLmivmilnorte÷50=norte(norte+1)÷2-norte

o solo

2(XpagsLmivmilnorte-50)÷50=norte(norte+1)-2norte

Finalmente, poniendo todo de un lado:

0 0=norte2-norte-2×XpagsLmivmilnorte÷50

Esta es ahora una fórmula cuadrática que produce una solución negativa y positiva, de la cual solo lo positivo es relevante ya que no hay niveles negativos. Ahora obtenemos:

norte=1+1+4 4×2×XpagsLmivmilnorte502

El nivel actual condicional en XP y umbral lineal es por lo tanto:

Lmivmil=1+1+8×XPAGS÷thrmisholre2

Lmivmil=XPAGS5.0XPLevel 100

Editar : esta fórmula funciona completamente como debería y genera correctamente el levelcondicional actual XP con una progresión de umbral lineal según lo solicitado por el OP. (La fórmula anterior arrojó "nivel + 1" al suponer que el jugador comenzó desde el Nivel 0, que era mi error: ¡lo había resuelto en mi hora de almuerzo escribiendo en un pañuelo! :)

Majte
fuente
Los comentarios no son para discusión extendida; Esta conversación se ha movido al chat .
Josh
@JoshPetrie El problema para nosotros que acabamos de ver esta pregunta más tarde es que el enlace de chat está roto. ¿Alguna forma de recuperarlo?
2015
@ Y lo recuperé, pero desaparecerá por sí solo en otros ocho días más o menos.
Josh
25

La solución simple y genérica , si no necesita repetir este cálculo millones de veces por segundo (y si lo hace, probablemente esté haciendo algo mal), es usar un bucle:

expLeft = playerExp
level = 1
while level < levelCap and expLeft >= 0:
    expLeft = expLeft - expToAdvanceFrom(level)
    level = level + 1

if expLeft < 0: level = level - 1     # correct overshoot

La gran ventaja de este método, además de no requerir matemáticas complicadas, es que funciona para cualquier función arbitraria de exp-por-nivel. Si lo desea, incluso puede inventar valores de exp arbitrarios por nivel y almacenarlos en una tabla.

Si necesita (por alguna extraña razón) una solución aún más rápida, también puede calcular previamente la cantidad total de experiencia necesaria para alcanzar cada nivel, almacenar esto en una tabla y utilizar una búsqueda binaria para encontrar el nivel del jugador. La precalculación todavía lleva un tiempo proporcional al número total de niveles, pero la búsqueda solo requiere un tiempo proporcional al logaritmo del número de niveles.

Ilmari Karonen
fuente
44
La solución más flexible. Y dado que la velocidad no importa para un cómputo único, supongo que es el mejor.
GameAlchemist
44
@Majte: Quizás no estaba lo suficientemente claro. Estoy no lo que sugiere que cualquiera de las soluciones publicadas requeriría "millones de iteraciones". Lo que quería decir es que, a menos que de alguna manera necesites calcular el nivel del jugador millones de veces por segundo, mi solución (fuerza bruta ingenua) es más que lo suficientemente rápida. Las otras soluciones, basadas en derivar algebraicamente una fórmula de forma cerrada para el nivel en función de exp, pueden ser aún más rápidas, pero para el código que rara vez se llama (y cualquier cosa menor que, digamos, 1,000 veces por segundo seguramente cuenta como "raro" aquí), no habrá una diferencia notable.
Ilmari Karonen
2
Ohh, ya veo, lo siento. Estoy totalmente de acuerdo con usted y ofrece una gran alternativa para los pasos de avance definidos por el usuario por nivel. Pero entonces, probablemente use tablas preprocesadas después de todo.
Majte
2
La simplicidad de esta solución lo convierte en un claro ganador. No descarte el valor de legibilidad y mantenibilidad.
Mauser
1
Las computadoras son buenas para hacer tareas domésticas, no las personas. Desea simplificar la vida de las personas, el programador, a expensas de la computadora si es necesario. Con esta solución, solo tiene que escribir un método, el reenvío, no el reenvío y el reverso. La solución más simple no es la que tiene en el código, sino construir esa tabla de búsqueda. Ram es barato, úsalo.
Mauser
11

La pregunta ha sido respondida con código, pero creo que debería responderse con matemáticas. Alguien puede querer entender en lugar de solo copiar y pegar.

XPNivel+1=XPNivel+NivelLímite

XP

XPNivel=(Nivel-1)NivelLímite2

Nivel

Nivel=Límite2+8XPLímite2Límite+12

(truncar a entero, porque el jugador necesita todos los XP requeridos para obtener cualquiera de los bonos de nivel)

MickLH
fuente
2
Me gusta esta respuesta Claro y conciso.
Almo
Hola Mick Ha pasado un tiempo desde que hice relaciones de recurrencia. ¿No podríamos también especificar el caso base XP_Level(0) = 50y luego podemos evitar resolver? ¿Algún beneficio, pros y contras? Creo que sería bueno tocar esta respuesta. +1
Vaughan Hilts
@VaughanHilts No estoy seguro de cómo funciona tu notación o de lo que estás preguntando, ¿puedes enviarme un ping en el chat de gamedev?
MickLH
Entendí que la respuesta del código es mucho más fácil que esto.
Pharap
Sigue trabajando en ello @Pharap. Cuando era adolescente, también entendía el código más fácilmente que las matemáticas, pero con experiencia y conocimiento las matemáticas se volverán obvias en todas partes de la vida.
MickLH
10

Aquí hay un enfoque para resolver el problema usando álgebra básica. Si no te importan los pasos, salta al final.

Una cosa fácil de lograr es, dado un nivel n, la experiencia total enecesaria para obtener ese nivel:

e = sum from k=1 to n of (t(k-1))

El ttérmino representa el aumento de XP necesario por nivel: 50, en el ejemplo.

Podemos resolver lo anterior usando la fórmula para secuencias aritméticas ( identidad de suma ):

e = t/2 * n(n-1)

Sin embargo, queremos la fórmula opuesta: el nivel del jugador dada su experiencia total. Lo que realmente queremos hacer es resolver el nivel n,. Primero, agrupemos los términos:

n^2 - n - 2e/t = 0

Ahora podemos usar la fórmula cuadrática:

n = (1 + sqrt(1+8e/t))/2

Ecuación final:

level = 0.5 + sqrt(1 + 8*(total experience)/(threshold)) / 2
Caosed0
fuente
1
Gracias por la respuesta. Pero, ¿qué pasa si quiero cambiar el umbral a otra variable? En lugar de 50, me gustaría usar 50000 o 1000 0 para el caso. ¿Cómo debo modificar la ecuación?
JayVDiyk
2
Sí, las soluciones deberían ser las mismas. Quería exponer los pasos para la solución en caso de que alguien estuviera interesado. @JayVDiyk: editará la publicación.
Caosed0
Eso fue un poco descarado de su parte, ya que comenté que publicaré la solución completa después del trabajo;) está bien, no me importa. Lo habitual es responder con una referencia a la respuesta correcta y anotar la extensión. Mente de Nerver, me encantaba haberlo resuelto. Deseo que se publiquen más preguntas como esta aquí.
Majte
Lo siento, debe haber perdido ese comentario. No quise robártelo ni nada por el estilo; lo tendré en cuenta la próxima vez. ¡Su respuesta es definitivamente más completa que la mía después de la edición!
Caosed0
1
+1; sin ofender a la intención de @Majte, personalmente considero que su explicación es más legible.
Ilmari Karonen
3

Es muy importante conocer todas las matemáticas involucradas aquí por todo tipo de razones, algunas de ellas aplicables al desarrollo de juegos.

PERO

Este es un sitio de desarrollo de juegos, no un sitio de matemáticas. Entonces, analicemos cómo funcionan estas cosas, no como series algorítmicas, sino como conjuntos , porque ese es el tipo de matemática que se aplica a la nivelación en juegos que realmente podría desarrollar para vender, y este es el sistema que subyace a la mayoría (pero no a todas) la nivelación sistemas (al menos históricamente).

Los jugadores tienden a preferir números agradables y redondos que son fáciles de recordar y visualizar, y en ninguna parte es esto más importante que en un sistema de juego basado en niveles donde el jugador necesita X cantidades de xp para avanzar al nivel Y.

Hay dos buenas razones para elegir números redondos:

  • El nivel de experiencia en sí es un bonito número redondo "100; 200; 1,000,000; etc."
  • El delta entre niveles tiende a ser otro buen número redondo que el jugador puede mirar y calcular en su cabeza.

Los números redondos son agradables. El propósito de los juegos es ser agradable. El placer es importante, especialmente porque los dilemas del juego a menudo serán cualquier cosa menos agradables por diseño.

¿Por qué es importante tener esto en cuenta?

La mayoría de los algoritmos de series compuestas no producen buenos números redondos.

La mayoría de las series no se detienen en un punto bonito (cada respuesta que he visto hasta ahora solo continúa para siempre). ¿Asi que que hacemos? Nos aproximamos y luego determinamos qué conjunto de niveles debe aplicarse al sistema de juego .

¿Cómo sabemos qué aproximaciones son apropiadas? Consideramos cuál es el punto de nivelación dentro del sistema de juego.

La mayoría de los juegos tienen límites de nivel que se activan en algún momento. Hay algunas maneras en que esto puede desarrollarse:

  • El límite se encuentra relativamente temprano, donde el sistema de niveles solo existe para ayudar a los jugadores a superar la primera fase del juego de una manera enfocada para obligarlos a aprender el sistema completo del juego. Una vez que están "completamente desarrollados" comienza el juego largo.
  • La ganancia de XP frente al nivel de dificultad tiene una cierta economía, donde sí, hay un límite de nivel, pero está tan lejos que esperamos que los jugadores completen el juego aproximadamente a la mitad de la tabla de nivelación. En los juegos de rol de estilo DQ / FF con múltiples personajes / clases, es más común que diferentes personajes / clases se nivelen más fácilmente al adquirir experiencia a diferentes velocidades que cambiar el XP requerido para cada nivel por clase de personaje . De esa forma, los jugadores pueden recordar fácilmente los lindos números redondos como objetivos universales, y saber que cada personaje avanza hacia ellos a un ritmo arbitrario establecido por el sistema de juego ( XP + (XP * Modifier)o lo que sea).
  • Los límites de nivel se basan en la categoría de personaje externo. Es decir, algún factor fuera del sistema de juego propiamente dicho dicta el aspecto del sistema de niveles. Esto se está volviendo más común ya que muchos juegos son de pago para ganar pero gratuitos. Un jugador gratuito puede estar limitado a nivel 70, un suscriptor puede estar limitado a nivel 80, una compra única puede avanzar a alguien un nivel más allá de un límite universal, etc.
  • Los límites de nivel son universales y están vinculados al mundo del juego de alguna manera. Este sistema ha sido popularizado por WoW.
  • Cualquier otro sistema de límite de nivel que pueda imaginar que mejore el juego de una manera más inteligente que simplemente recompensar a los jugadores por perder más minutos de su vida en su mundo inventado que los otros jugadores.

No son unos sistemas de juego donde no hay límite de nivel y el sistema se determina mediante algoritmos. Por lo general, sistemas como este utilizan un sistema X-powers-of-Y para hacer que los números exploten rápidamente. Esto hace que sea muy fácil llegar al nivel L-1, se espera razonablemente que la mayoría de los jugadores lleguen al nivel L, excesivamente difícil llegar al nivel L + 1, y los jugadores envejecerán y morirán antes de llegar a L + 2. En este caso, "L" es un nivel que ha decidido que es el nivel objetivo apropiado para jugar y en el que normalmente habría limitado el sistema, pero dejaría la opción abierta para que las personas se engañen y piensen que es una buena idea XP para siempre. (Siniestro!) En este tipo de sistema, las matemáticas que se encuentran aquí tienen mucho sentido. Pero es un caso muy estrecho, y rara vez se encuentra en los juegos reales.

¿Asi que que hacemos?

Calcular los niveles y XP? No. ¿ Determinar los niveles y XP? Sí.

Usted determina qué significan los niveles y luego decide qué conjunto de niveles debería estar disponible. Esta decisión se reduce a la granularidad dentro del sistema de juego (¿Existe una gran diferencia en el poder entre los niveles? ¿Cada nivel confiere una nueva habilidad? Etc.) y si los niveles se usan o no como un sistema de activación ("No se puede ir a la siguiente ciudad hasta que tengas 10 años, niño ", o un sistema de escalera competitivo aplica niveles basados ​​en niveles, etc.).

El código para esto es bastante sencillo, y es solo determinación de rango:

level(XP) when XP < 100  -> 1;
level(XP) when XP < 200  -> 2;
level(XP) when XP < 500  -> 3;
level(XP) when XP < 1000 -> 4;
% ...more levels...
level(XP) when XP > 1000000 -> 70. % level cap

O con una declaración if, o un caso, o una cadena de if / elif, o cualquiera que sea el idioma en el que esté utilizando soportes (Esta parte es el elemento menos interesante de cualquier sistema de juego, solo proporciono dos formas porque sucede que esté en modo Erlang en este momento, y la sintaxis anterior puede no ser obvia para todos.):

level(XP) ->
    if
        XP < 100  -> 1;
        XP < 200  -> 2;
        XP < 500  -> 3;
        XP < 1000 -> 4;
        % ...more levels...
        XP > 1000000 -> 70 % level cap
    end.

¿Es asombrosa la matemática? No, en absoluto. ¿Es la implementación manual de la determinación del elemento establecido? Sí. Eso es todo lo que es, y esto es más o menos la forma en que he visto en realidad hace en la mayoría de los juegos a lo largo de los años.

Como nota al margen, esto no debe hacerse cada vez que el jugador gana experiencia. Por lo general, realiza un seguimiento de "XP to go" como un valor, y una vez que el jugador agota o supera el valor "to go" (de cualquier forma que lo esté haciendo), calcula esto una vez para averiguar dónde está realmente el jugador en, almacene eso, calcule el próximo "ir" menos las sobras (si se permite llevar XP hacia adelante) y repita.

zxq9
fuente