路过看到mod相关的话题,我没用cocos做过mod,不过随便说一下我对mod框架的理解。
支持mod的框架我认为要做下面几点:
1.(引擎)资源的顺序覆盖与新增
mod可以增加资源,也可以对游戏本身的资源进行覆盖,后加载的mod可以覆盖前加载mod的资源。
这一点最好是有一个VFS(Virtual File System),以路径索引资源(好覆盖),并支持按优先级挂载多个目录和pack包。godot就是这种形式,一般自研引擎也是类似这种方式。
2.(游戏)mod的加载列表
不管是用mod 管理器,还是steam,要加载mod必须支持一个配置列表,包括加载的顺序和其他参数。在游戏启动的时候根据这个列表来依次加载mod。如果想做的更好,就做一个mod launcher工具。
3.mod 本身的结构以及入口
mod 本身应该组织成一个包的形式,包括mod文件夹,里面的资源内容(资源路径和游戏本身一致好覆盖),还有mod根文件夹下的入口脚本(init.lua init.js 等),游戏加载mod后,从入口脚本调用mod的初始化。
4.(游戏)针对mod提供的API
游戏针对Mod提供的API分为几类:
a) 实体数据库(配置)的增删查改。例如增加一种敌人,修改某个道具的属性等。
b) 游戏的全局数据查询接口。玩家数据等查询接口。
c) 游戏战斗场景的查询与控制接口。包括场景信息查询,实体对象的操作(创建,销毁,动作)等,一般用于战斗类mod。
d) Hook,包括游戏生命周期,各种实体动作的回调,各种事件的回调。例如OnSceneLoad,OnAttack等。
e) (可选)UI界面相关的API,用于扩展和新增UI界面。
mod初始化的时候,根据情况注册Hook,修改配置,在Hook内,调用各种查询和控制接口。
5.(游戏,可选)Debug Console
如果需要支持mod,最好游戏里面要有一个debug console,用于执行各种命令,这个是测试mod不可或缺的部分。
6.(工具,可选)Mod Editor
提供一个专门给Mod的编辑器,或者一个专门给mod的模版工程。编辑器就不用说了,模版工程的话可以不用暴露游戏内的实际代码,仅提供游戏给与的接口即可,游戏核心部分可以以加密或者二进制(dll)的形式提供。
另外聊一下关于cocos 支持mod,我没用cocos做过mod,只能大致上聊一下方向。
cocos 支持mod最大的一点困难,是资源的顺序覆盖与新增,由于cocos 和 unity一样,是以uuid为资源索引,导致新增和替换资源比较困难。
如果顺着cocos本来的资源方案,资源包可以做成asset bundle的形式,符合cocos uuid的资源路径,并且可以通过config插入uuid到资源的映射表。顺序覆盖可以通过fileUtils.setSearchPaths来做。这个API支持挂载多个资源目录,原来是用于热更的资源覆盖,也可以作为支持mod的资源覆盖的基础。这个方式也还是要改一点引擎才能做好细节。
或者可以魔改cocos的资源索引方案,以loadRemote为基础,以资源路径为索引重新构建工程的资源引用。在之上构建一套Virtual File System即可。
执行脚本应该也没问题,js本身就有带着eval等可以执行字符串的能力。
其他基本上问题都不大,就是要定制不少细节。
另外还有一些外置的mod框架,例如unity的mod可以用HarmonyX等等,java的游戏也有,例如杀戮尖塔的mod启动器,如果在游戏内做不方便,也可以考虑这种外挂式的mod框架,不过cocos没有类似的。

