Supongo que esta pregunta se refiere más a juegos como MMO y juegos similares a Diablo.
¿Cuáles son los diseños habituales para implementar una tabla de caída, donde un monstruo podría soltar diferentes tipos de elementos dependiendo de un porcentaje? Supongo que la forma más sencilla es tener un diccionario de 'porcentaje de peso' para los tipos de elementos, pero esto es difícil de ampliar si deseamos introducir nuevos tipos de elementos (por ejemplo, cuando la expansión D2 incluye runas y nuevos elementos de clase)
game-design
rpg
Extrakun
fuente
fuente
Respuestas:
Para un roguelike en el que estaba trabajando, implementé un sistema basado en datos bastante flexible para generar gotas. Lo he documentado aquí . Es esencialmente un pequeño DSL para seleccionar una serie de elementos elegidos al azar.
Una simple caída se ve así:
Solo dice que deje caer un número aleatorio de monedas de cobre entre 1 y 10. Las cosas se vuelven más flexibles cuando agrega ramas:
Un "uno de" selecciona una de sus ramas secundarias en función de las probabilidades dadas y luego la evalúa. Las gotas pueden dejar caer más de un artículo:
Esto evaluará todas las subramificaciones y las soltará si pasa una tirada contra su probabilidad. También hay algunas otras ramas para seleccionar un elemento en función de la mazmorra y el nivel del jugador.
Debido a que estos pueden volverse complejos, también le permite definir macros con nombre, esencialmente funciones que expanden una expresión de ramificación y pueden reutilizarse en varias gotas. De esa manera, si, por ejemplo, todos los enanos sueltan el mismo tipo de botín, puedes hacer una sola macro para eso y usarla en todos esos tipos de monstruos en lugar de copiar y pegar tablas de caída enormes.
Un ejemplo de la caída de un monstruo :
Aquí,
(coins)
,(any-weapon)
, y(any-armor)
son todas las llamadas macro:que a su vez llama cosas como:
Puede anidar expresiones de caída arbitrariamente profundamente como un lenguaje de programación real. Esto le brinda la componibilidad que un enfoque simple basado en tablas no le dará.
Al igual que todos los sistemas basados en datos, puede abrumarse construyendo caídas impenetrablemente complejas, pero cumple mis objetivos:
El código C # que implementa esto está aquí .
fuente
En Stendhal nuestras tablas de botín son listas. Cada entrada contiene el nombre del artículo, una cantidad mínima y máxima y la probabilidad. La estructura interna es muy similar a la que mostramos en la página web de la criatura .
Es importante para nosotros que los diseñadores de juegos que tienen un gran conocimiento del mundo puedan definir tales cosas. Es decir, sin comprender la lógica compleja en el nivel del código del programa. Por lo tanto, no tenemos las definiciones de criaturas y elementos en el código del programa, pero las movimos a archivos .xml como elves.xml o club.xml . Tenemos un editor gui para ellos, pero la mayoría de los diseñadores de juegos modifican el archivo .xml directamente.
Para hacer que las criaturas y los elementos sean fácilmente extensibles, utilizamos un sistema de bloques de construcción: no hay una clase de programa para "elfo" o "elfo arquero". Pero hay una serie de clases relacionadas con el comportamiento, como "cobarde", "patrulla", "agresivo", "arquero", "sanador". Los diseñadores pueden definir nuevas criaturas seleccionando esos comportamientos sin escribir el código del programa: por ejemplo, para crear un "elfo arquero" dibuje un duende duende con un arco y lo defina como "ofensivo", "arquero". Luego defina el nivel y los atributos similares y agregue algunos elementos élficos a la tabla de botín.
Para los artículos tenemos un enfoque similar, pero actualmente está limitado a un comportamiento: un diseñador puede agregar un nuevo artículo y definir un comportamiento como "ConsumableItem", "KeyItem" o "AttackItem", "Spell", "Scroll" sin tener que programar la lógica.
fuente
En los juegos de mesa D&D hay un concepto de tipos de botín. La mayoría de los monstruos caerán de una o más de las tablas y estas tablas serían lo que actualizarías en tu expansión. Los monstruos aún soltarían "65% común, 10% gemas, 15% arte, 10% herramientas", pero actualizarías lo que había en cada una de estas tablas.
Por ejemplo, las gemas contienen ranuras con rangos aleatorios que devuelven "1 gema (25%) 2 gemas (50%) 5 gemas (75%) 100 gemas". y cuando desee agregar gemas de runas especiales, actualice la tabla a "1 gema (25%) 2 gemas (50%) 5 gemas (75%) 100 gemas (95%) 1 runegem".
Pero, por otro lado, si ya tiene una ponderación porcentual, ¿por qué no simplemente actualizar todas las tablas de monstruos en su expansión? Seguramente tablas como esta son pequeñas cargas útiles en comparación con texturas y mallas. Además, tampoco necesita mantener los porcentajes contando hasta 100, eso es solo una suposición que hizo para comenzar y puede calcular el total real antes de generar su valor aleatorio. Si las ponderaciones suman 120, solo genera un valor de 1-120 en lugar de 1-100.
fuente
En la superficie, esto parece lo mismo que el problema de "selección aleatoria ponderada".
Algoritmo para determinar eventos aleatorios
Asigne probabilidades relativas a cada evento, sume, luego elija un número aleatorio dentro de ese rango para decidir qué evento desea.
Incluso si prefiere usar porcentajes, que es el mismo sistema, recién escalado a 100, está sobreestimando lo difícil que es agregar cosas. Si tiene el 100% y luego agrega el 20% en una expansión, simplemente divida todos los valores entre (120/100) y volverá a un total del 100%.
fuente