之前对AI的多角色支持一做起来就是3个月过去了,(虽然也因为疫情等方方面面有各种的摸鱼),现在终于完成了多角色,也实现了package结构化。在兴致冲冲的准备加入主项目的时候,突然想起来还有一个非常核心的内容没做……也就是对物品数量的支持。
在之前自学GOAP以及其他一些学习材料时,都没有看到对于物品数量的考虑,也就是比如"3单位木块产出1单位书桌"或"角色一次能搬运10kg物品"之类的这种概念。也许是他们的AI都不是面对生产线的吧。因此为了分步简便,在目前为止的AI开发中,我也都是不考虑物品数量的。
现在必须继续增强我的Zephyr GOAP,支持数值,才能应用于我的游戏。这两天人工plan了一遍,确定了几个改造的点:
State增加Amount
也就是3.0的核心了,表达状态的State Component需要有一个Amount的数值成员。
数值比对
以前当前Node的State与世界状态比对时,只要有符合就移除。现在有些比对是需要基于数值来决定移除多少了。
Node上指定Precondition的比对方式
有的比对只需要考虑“是否存在”,比如“世界里是否有餐桌”,比对后不会变动世界状态,也就是不消耗的意思。但有的比对在比对后需要从世界状态中移除对应数量,以避免后续步骤重复比对,比如“拿取某容器内的3个苹果”。因此Node上需要增加一个enum数组,以指示自己的各个precondition究竟与世界状态之间使用哪种比对方式。
生产类Action支持多重生产次数
例如Cook, Produce等Action,需要能够支持一次生产多个目标产物,来适应数量概念。
Node增加ΔCurrentStates(世界状态变化量)
这里我想了比较久,在之前参考的ReGoap里每个node都会完整记录变动后的整个世界状态,我觉得过于浪费内存,考虑在Node上只保留自己对世界状态的变化量,但是要牺牲一定的运算时间,每次进行比对时需要把世界状态与整个父节点中每一个ΔCurrentStates累加。最后折中了一下,选择在Node上保存“自头至此”的所有ΔCurrentStates,这样每次比对时只用加和一次。
自我满足的Action
例如当PickItem要求拿取10个苹果,而世界里是2个容器分别各有5个时,如何表达“连续分别拿取2次”?我考虑的实现方式是PickItem需要增加支持以自己的preconditon为effect。这样就可以两个PickItem前后衔接分取2次苹果。
但是需要避免无限循环,因此在GetTargetState里要检查变动后的世界状态是否还有可满足的State,如果没有了,就不再产生下一个自己。
角色运力
数量概念的加入会明显膨胀Node Graph的node数量,如果再加上角色运力的限制导致一次运输变为多次,有点担心膨胀的程度。所以放在最后实现。
这就是下一步进行AI 3.0的全部内容了,做完就能回到主项目了吧,一定是这样子的,嗯,嗯。
讨论群: 827072601
爱发电: https://afdian.net/@taohuayuan
任务板: https://trello.com/b/StForyw7/taohuayuan
twitter: https://twitter.com/zephyr1125
wiki: https://taohuayuanwiki.a2hosted.com
discord: https://discord.gg/sMuKYE6
暂无关于此日志的评论。