同事在做的实现框架,给 BUFF 留了几个接口,其中有两个吸引了我的目光。
一个叫做 start 一个 stop 。分别用于 BUFF 产生的时候需要处理的逻辑,和一个用于 BUFF 消失时处理的逻辑。这是一个很自然的设计。尤其在 C++ 程序编写的习惯里,就相当于一个构造过程,一个析构过程。
比如,一个攻击 +5 的 BUFF ,可以在 start 事件处理里修正攻击值(+5),然后在 stop 里做一次逆运算(-5)。
我突然有一种直觉,感觉这个设计不是特别合理。因为它要求程序员去实现一对互逆的逻辑。这段时间我对需要编写事物处理的成对可逆处理的设计特别反感。所以立刻就意识到了实际问题所在。
首先,许多逻辑上成立的可逆运算都是事实上有漏洞的。比如某些特定条件下的浮点加减运算就有可能不可逆(暂时没有去构造一个例子,但是我认为是可以构造出来的);定点数的乘除运算就很容易导致不可逆。
还有更严重的,如果一个 BUFF 会把某个值设置成固定值(比如清 0 或设为 max),那么不借助缓存变量,这个效果就完全不可逆。
当然有经验的数值策划,会把公式里的乘法规则提取出来,安排合理的次序去计算。比如大多数游戏中,乘法加成系数都是先累加再一次乘起来的。(btw, 早期刚接触 diablo 的时候,我完全不能理解:为啥两个加 20% 的装备装到一起是 40% 的效果而不是 44% :D 也有游戏设计的更复杂一些,例如 Eve 里,就有所谓的叠加惩罚。哦,好象又写跑题了。)
我问了一下同事,诸如一些特殊情况如何处理的问题:比如玩家顶着 BUFF 断线,重新上线的数值恢复问题。还有如果在 BUFF 有效期