木匣子

Web/Game/Programming/Life etc.

简单灵活的战利品掉落配置

在游戏中常常需要配置各种产出表,例如怪物的掉落、开启宝箱获得道具等等。简单的做法就是将这些功能分开开发,怪物用简单的概率来判断是否掉落物品,宝箱则根据预先设置好的权重来决定最终获得的道具。

但是需求总是处于变化的,如果策划想要让怪物能像宝箱那样根据权重来决定掉落,或者让宝箱像怪物那样由概率来获得道具(也可能什么也得不到)。

既然如此何不设计一种简单而灵活的,可以兼容这两种方案的配置呢?

结合两者,于是我们就得到了这个杂交的战利品掉落表:

Loot Table

字段名    类型    说明
idx      int     编号
loot     int     战利品ID
count    int     战利品数量
rate     float   掉落概率
group    int     权重组
weight   int     权重

为何说它简单而灵活呢,来看看下面这个案例,以及我们额外定义的几个规则。

配置样本

idx    loot    count    rate    group    weight
1      Coin    100      0.5     -        -
2      BoxA    1        -       1        1
2      BoxB    1        -       1        2
3      Coin    100      0.5     -        -
3      BoxA    1        -       1        1
3      BoxB    1        -       1        2
3      BoxC    1        -       2        2
3      BoxD    1        -       2        2
idx

首先,相同的 idx 表示同一组掉落配置,可以填写在 NPC 或宝箱的产出 ID 中。

rate

若 NPC 或宝箱的_产出ID_为 1,根据配置样本,有一条 rate 为 0.5 的战利品,
说明击败该 NPC 有 50% 的概率可以获得该物品(100 Coin)

group and weight

若 NPC 或宝箱的_产出ID_为 2,根据配置样本,有两条数据,且这些数据都没有 rate 。
我们约定,当没有填写 rate 时,则按 group 和 weight 进行掉落判定(可采用轮盘赌选择算法)

相同 group 内的 weight 累加为 W,由 [0, W) 之间产生一个随机数,看其落在哪一个区间中,则产出相应的物品。

所以 idx 为 2 的配置有 1/3 的概率产出 BoxA,及 2/3 的概率产出 BoxB。

hybrid

既然是兼容两种方案的配置,那就可以产生更有意思的杂交方案:

  • 对于同一个 idx 组,每个配置 rate 的概率都可进行一次独立判定
  • 若有多个 group 组,每个组进行一次独立的轮盘赌判定

若 NPC 或宝箱的_产出ID_为 3,根据配置样本:

  • 有 50% 概率得到 Coin 100 个
  • 一定能获得 BoxA(概率1/3) 或 BoxB(概率2/3) 其中一个
  • 一定能获得 BoxC(概率2/4) 或 BoxD(概率2/4) 其中一个

优化

从配置样本中可以看出 rate 与 group+weight 是正交的,可以通过约定 group: 0 时 weight 即为 rate 来消除这部分的冗余。至于是否有必要做这个优化,就看各自的心情了。个人认为数据量不大的话,直观性比较重要。

小结

通过一种兼容的配置,将产出功能统一起来,使得程序设计更具有通用性。只要符合这样的产出规则的活动,只需要写出相应的配置,使用同一套代码即可完成产出判定。