Para um roguelike em que eu estava trabalhando, implementei um sistema orientado a dados bastante flexível para gerar quedas. Eu documentei aqui . É essencialmente um pouco DSL para selecionar vários itens escolhidos aleatoriamente.
Uma gota simples se parece com:
1-10 copper coin
Diz apenas para soltar um número aleatório de moedas de cobre entre 1 e 10. As coisas ficam mais flexíveis quando você adiciona galhos:
one of
turquoise stone (50%)
onyx stone (25%)
malachite stone (15%)
jade stone (10%)
Um "um de" seleciona um de seus ramos filhos com base nas probabilidades fornecidas e avalia isso. Gotas podem soltar mais de um item:
any of
turquoise stone (50%)
onyx stone (25%)
malachite stone (15%)
jade stone (10%)
Isso avaliará todas as sub-filiais e as descartará se passar uma rolagem contra sua probabilidade. Existem também alguns outros ramos para selecionar um item com base no nível da masmorra e do jogador.
Como elas podem se tornar complexas, também permite definir macros nomeadas, essencialmente funções que expandem uma expressão de ramificação e podem ser reutilizadas em várias descargas. Dessa forma, se, por exemplo, todos os anões descartam o mesmo tipo de pilhagem, é possível criar uma única macro para isso e usá-la em todos esses tipos de monstros, em vez de copiar e colar grandes tabelas de descarte.
Um exemplo da queda de um monstro :
:: ancient dragon
glyph = D
groups = dragon
drops
(coins)
2-3(1:8) one of
(any-weapon)
(any-armor)
Aqui, (coins)
, (any-weapon)
, e (any-armor)
são todas as chamadas de macro:
(any-armor)
one of
(shield)
(helm)
(boots)
(gloves)
(cloak)
(robe)
(soft-armor)
(hard-armor)
que por sua vez chama coisas como:
(cloak)
one near level
cloak (10)
velvet cloak (20)
fur-lined cloak (50)
Você pode aninhar expressões de descarte arbitrariamente profundamente como uma linguagem de programação real. Isso fornece a composição que uma abordagem simples baseada em tabela não oferece.
Como todos os sistemas orientados a dados, você pode se sobrecarregar criando quedas impenetrávelmente complexas, mas ele atende aos meus objetivos:
- Ser capaz de especificar quais coisas são descartadas completamente fora do código.
- Simples de implementar o sistema principal em código.
- Seja capaz de ajustar o que monstros específicos deixam cair para que o jogador possa fazer uma exploração orientada a objetivos. ("Eu preciso de um colar. Vou procurar anões, pois eles tendem a largá-los.")
O código C # que implementa isso está aqui .