Advertisement
  1. Game Development
  2. Platform Agnostic

Cómo Resolver la Frustración de los Jugadores: Técnicas de Generación de Números Aleatorios

by
Read Time:10 minsLanguages:

Spanish (Español) translation by Ricardo Mayén (you can also view the original English article)

Si entablas una conversación con un aficionado a los juegos de rol, no tardarás en escuchar una queja sobre los resultados aleatorios y el botín, y lo frustrantes que pueden ser. Muchos jugadores han dado a conocer esta irritación, y aunque algunos desarrolladores han creado soluciones innovadoras, muchos siguen obligándonos a pasar por exasperantes pruebas de perseverancia.

Hay una forma mejor. Al modificar la forma en que los desarrolladores utilizamos los números aleatorios y sus generadores, podemos crear experiencias atractivas que busquen esa cantidad "perfecta" de dificultad sin llevar a los jugadores al límite. Pero antes de entrar en materia, vamos a repasar algunos aspectos básicos de los generadores de números aleatorios (o RNG, por sus siglas en inglés).

El Generador de Números Aleatorios y Su Uso

Los números aleatorios nos rodean y se utilizan para añadir variación a nuestro software. En general, los principales usos de los RNG son representar eventos caóticos, mostrar volatilidad o comportarse como un limitador artificial.

Es probable que interactúes con números aleatorios, o con los resultados de tus acciones, todos los días. Se utilizan en ensayos científicos, videojuegos, animaciones, arte y casi todas las aplicaciones de tu ordenador. Por ejemplo, es probable que un RNG esté implementado en las animaciones básicas de tu teléfono.

Ahora que hemos visto lo que es un RNG, vamos a ver su implementación y cómo puede mejorar nuestros juegos.

El Generador Estándar de Números Aleatorios

Casi todos los lenguajes de programación utilizan un RNG estándar en las funciones básicas. Funciona devolviendo un valor aleatorio entre dos números. Los RNG estándar pueden implementarse en docenas de formas diferentes a través de diferentes sistemas, pero todos tienen generalmente el mismo efecto: devolver un número aleatorio donde cada valor en el rango tiene la misma probabilidad de ser devuelto.

En el caso de los juegos, se suelen utilizar para simular el lanzamiento de dados. Lo ideal es que sólo se utilicen en situaciones en las que se desea que cada resultado se produzca un número igual de veces.

Si quieres experimentar con la rareza o con diferentes tasas de aleatoriedad, este siguiente método es más adecuado para ti.

Números Aleatorios Ponderados y Ranuras de Rareza

Este tipo de RNG es la base de cualquier juego de rol con rareza de objetos. Específicamente, cuando se necesita un resultado aleatorio pero se quiere que algunos ocurran con menos frecuencia que otros. En la mayoría de las clases de probabilidad, esto se representa comúnmente con una bolsa de canicas. Con los RNGs ponderados, tu bolsa puede tener tres canicas azules y una roja. Como sólo queremos una canica, obtendremos una roja o una azul, pero es mucho más probable que sea azul.

¿Por qué es importante la aleatoriedad ponderada? Utilicemos los eventos del juego de SimCity como ejemplo. Si cada evento se seleccionara con métodos no ponderados, el potencial de cada evento sería estadísticamente el mismo. Esto hace que sea tan probable que recibas una propuesta para un nuevo casino como que experimentes un terremoto en el juego. Añadiendo una ponderación, podemos garantizar que estos eventos se produzcan en una cantidad proporcional que preserve la jugabilidad.

Sus Formas y Usos

Agrupación de los Mismos Artículos

En muchos cursos o libros de informática, este método suele denominarse "bolsa". El nombre es bastante acertado, ya que utiliza clases u objetos para crear una representación virtual de una bolsa literal.

Funciona básicamente así: hay un contenedor en el que se pueden colocar los objetos donde se almacenan, una función para colocar un objeto en la "bolsa", y una función para seleccionar al azar un elemento de la "bolsa". Volviendo a nuestro ejemplo de la canica, esto significa que tratarías tu bolsa como si contuviera una canica azul, una canica azul, una canica azul y una canica roja.

Utilizando este método de aleatorización, podemos determinar aproximadamente el ritmo al que se produce un resultado para ayudar a homogeneizar la experiencia de cada jugador. Si simplificáramos los resultados en una escala de "Muy malo" a "Muy bueno", ahora hemos hecho mucho más viable que un jugador experimente una cadena innecesaria de resultados no deseados (como recibir el resultado "Muy malo" 20 veces seguidas).

Sin embargo, sigue siendo estadísticamente posible recibir una serie de malos resultados, sólo que cada vez menos. En breve veremos un método que va un poco más allá para reducir los resultados no deseados.

Aquí hay un ejemplo rápido de pseudocódigo de lo que podría ser una clase de bolsa:

Implementación de la ranura de rareza

Al igual que la implementación de la agrupación de antes, la asignación de rarezas es un método de estandarización para determinar las tasas (normalmente para hacer que el proceso de diseño del juego y la recompensa al jugador sean más fáciles de mantener).

En lugar de determinar individualmente la tasa de cada artículo en un juego, se creará una rareza representativa, donde la tasa de un "Común" podría representar una probabilidad de 20 en X de un determinado resultado, mientras que "Raro" podría representar una probabilidad de 1 en X.

Este método no altera mucho la función real de la bolsa en sí, sino que puede utilizarse para aumentar la eficiencia del desarrollador, permitiendo asignar rápidamente una probabilidad estadística a un número exponencialmente grande de elementos.

Además, la asignación de rarezas es útil para moldear la percepción de un jugador, ya que le permite comprender fácilmente la frecuencia con la que puede ocurrir un evento sin eliminar su inmersión mediante el cálculo de números.

He aquí un ejemplo sencillo de cómo podríamos añadir ranuras de rareza a nuestra bolsa:

Números Aleatorios de Tasa Variable

Ya hemos hablado de algunas de las formas más comunes de tratar la aleatoriedad en los juegos, así que vamos a profundizar en una más avanzada. El concepto de utilizar tasas variables comienza de forma similar a la bolsa de antes: tenemos un número determinado de resultados, y sabemos con qué frecuencia queremos que ocurran. La diferencia con esta ejecución es que queremos ajustar el potencial de los resultados a medida que se producen.

¿Por qué habríamos de hacerlo? Por ejemplo, los juegos con aspecto coleccionable. Si tienes diez resultados posibles para el objeto que recibes, siendo nueve "comunes" y uno "raro", entonces tus posibilidades son bastante sencillas: el 90% de las veces, un jugador obtendrá el común, y el 10% de las veces obtendrá el raro. El problema viene cuando tenemos en cuenta los sorteos múltiples.

Veamos tus posibilidades de obtener una serie de resultados comunes:

  • En el primer sorteo, hay un 90% de posibilidades de sacar un común.
  • Con dos sorteos, hay un 81% de posibilidades de haber sacado todos los comunes.
  • Con 10 sorteos, todavía hay un 35% de posibilidades de que todos sean comunes.
  • Con 20 sorteos, hay un 12% de posibilidades de que todos sean comunes.

Aunque la proporción inicial de 9:1 parecía ser la ideal al principio, sólo acabó representando el resultado medio, y dejó a 1 de cada 10 jugadores gastando el doble de tiempo del previsto para conseguir ese raro. Además, el 4% de los jugadores tardaría tres veces más en conseguir el raro, y un desafortunado 1,5% emplearía cuatro veces más.

Cómo los Índices Variables Resuelven Este Problema

La solución es implementar un rango de rareza en nuestros objetos. Para ello se define una rareza máxima y mínima para cada objeto (o ranura de rareza, si se quiere combinar con el ejemplo anterior). Por ejemplo, demos a nuestro artículo común un valor de rareza mínimo de 1, con un máximo de 9. El raro tendrá un valor mínimo y máximo de 1.

Ahora, con el escenario de antes, tendremos diez artículos, y nueve de ellos son una instancia de un común, mientras que uno de ellos es un raro. En el primer sorteo, hay un 90% de posibilidades de obtener el común. Ahora, con las tasas variables, después de que se extraiga ese común, vamos a reducir su valor de rareza en 1.

Esto hace que nuestro próximo sorteo tenga un total de nueve objetos, ocho de los cuales son comunes, lo que da un 89% de posibilidades de sacar un común. Después de cada resultado común, la rareza de ese objeto disminuye, lo que hace más probable sacar un raro hasta que llegamos a un tope con dos objetos en la bolsa, uno común y otro raro.

Mientras que antes había un 35% de posibilidades de sacar 10 comunes seguidos, ahora sólo hay un 5% de posibilidades. Para los resultados atípicos, como sacar 20 comunes seguidos, las posibilidades se reducen ahora al 0,5%, e incluso más abajo. Esto crea un resultado más consistente para nuestros jugadores, y evita esos casos extremos en los que un jugador tiene repetidamente un mal resultado.

Creación de Una Clase de Tipo Variable

La implementación más básica del índice variable sería retirar un artículo de la bolsa, en lugar de devolverlo, así:

Aunque una versión tan sencilla conlleva algunos problemas (como que la bolsa acabe alcanzando un estado de aleatorización estándar), representa los pequeños cambios que pueden ayudar a estabilizar los resultados de la aleatorización.

Ampliación de la idea

Aunque esto cubre la idea básica de los índices variables, todavía hay bastantes cosas que considerar para tus propias implementaciones:

  • Quitar elementos de la bolsa ayuda a crear resultados consistentes, pero al final se regresa a los problemas de la aleatorización estándar. ¿Cómo podríamos dar forma a las funciones para permitir tanto los aumentos como las disminuciones de elementos para evitar esto?

  • ¿Qué ocurre cuando se trata de miles o millones de artículos? Utilizar una bolsa llena de bolsas podría ser una solución para esto. Por ejemplo, crear una bolsa para cada rareza (todos los objetos comunes en una bolsa, los raros en otra) y colocar cada uno de ellos en ranuras dentro de una bolsa grande puede proporcionar un gran número de nuevas posibilidades de manipulación.

El Caso de los Números Aleatorios Menos Tediosos

Muchos juegos siguen usando la generación de números aleatorios estándar para crear dificultad. Al hacerlo, se crea un sistema en el que la mitad de las experiencias de los jugadores caen en cualquier lado de lo previsto. Si no se controla, se crea la posibilidad de que se repitan las malas experiencias en una cantidad no prevista.

Al limitar los límites de los resultados, se garantiza una experiencia de usuario más cohesiva, lo que permite que un mayor número de jugadores disfrute de su juego sin el tedio continuo.

Conclusión

La generación de números aleatorios es un elemento básico del buen diseño de juegos. Asegúrate de que compruebas las estadísticas e implementas el mejor tipo de generación para cada escenario para mejorar la experiencia del jugador.

¿Te gusta otro método que no consideré? ¿Tienes preguntas sobre la generación de números aleatorios en el diseño de tu juego? Déjame un comentario abajo, y haré lo posible por responderte.

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.