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í:
1-10 copper coin
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:
one of
turquoise stone (50%)
onyx stone (25%)
malachite stone (15%)
jade stone (10%)
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:
any of
turquoise stone (50%)
onyx stone (25%)
malachite stone (15%)
jade stone (10%)
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 :
:: ancient dragon
glyph = D
groups = dragon
drops
(coins)
2-3(1:8) one of
(any-weapon)
(any-armor)
Aquí, (coins)
, (any-weapon)
, y (any-armor)
son todas las llamadas macro:
(any-armor)
one of
(shield)
(helm)
(boots)
(gloves)
(cloak)
(robe)
(soft-armor)
(hard-armor)
que a su vez llama cosas como:
(cloak)
one near level
cloak (10)
velvet cloak (20)
fur-lined cloak (50)
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:
- Poder especificar qué cosas se descartan completamente fuera del código
- Simple de implementar el sistema central en código.
- Sé capaz de ajustar qué monstruos específicos caen para que el jugador pueda hacer una exploración orientada a objetivos. ("Necesito un collar. Buscaré enanos ya que tienden a soltarlos").
El código C # que implementa esto está aquí .