(RPG) Diseño de tabla de colocación

18

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)

Extrakun
fuente
44
¿Por qué es difícil extender los diccionarios de porcentajes al agregar nuevos elementos? Quiero decir, si no necesitas tener todos los porcentajes para hacer una suma del 100% (y es un caso solo si quieres que un monstruo siempre suelte un solo elemento, lo cual es bastante extraño para mí), no veo un problema.
2010
1
Diga Orco => {'daga', 'espada' 'armadura'}, y tengo un nuevo tipo de elemento, digamos runa; Tendré que actualizar todos los diccionarios asociados con cada tipo de monstruo directamente. Por supuesto, esto no es nada que otra capa de indirección no pueda resolver. Entonces la pregunta es, ¿cómo se ve esa capa?
Extrakun
No estoy seguro de por qué crees que actualizar un diccionario es difícil. En Python, la extensión de un diccionario con nuevos valores se realiza con un solo método, por ejemplo. ¿Podrías aclarar dónde crees que es la dificultad?
Kylotan
2
Extrakun, si miras mi respuesta a continuación, hay una respuesta a tu pregunta de "otra capa de indirección". En lugar de tratar las gotas como una tabla plana, puede construirlas a partir de expresiones anidadas. Si permite macros con nombre (es decir, funciones), puede reutilizar fragmentos de una tabla desplegable en diferentes entidades.
munificente
2
Acabas de toparte con la 'trampa' del desarrollo del juego. Claro, puedes hacer un juego en dos días, pero luego vienen los cinco años de agregar contenido. Y agregar contenido es una rutina. MOLIENDA.
Tor Valamo

Respuestas:

22

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:

  1. Poder especificar qué cosas se descartan completamente fuera del código
  2. Simple de implementar el sistema central en código.
  3. 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í .

munificente
fuente
Esta es una implementación que no he visto antes. ¡Gracias!
Extrakun
12

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.

Hendrik Brummermann
fuente
8

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.

Richard Fabian
fuente
3

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%.

Kylotan
fuente