自动化工厂流水线(Automation / Factory)游戏策划专题进阶tech11 / 21 已发布

Mod 管线与配方扩展

配方数据驱动 · 物品注册 · 事件钩子 · 模组兼容协议

· 15 分钟阅读
Mod 管线与配方扩展:让玩家改写工厂的供应链 Mod Pipeline & Recipe Extension — 自动化工厂流水线(Automation / Factory)游戏策划专题

Mod 管线与配方扩展:让玩家改写工厂的供应链 Mod Pipeline & Recipe Extension

为什么配方数据驱动是第一块基石

做自动化工厂游戏,做到中期你一定会被问一个问题:"这游戏能打Mod吗?" 玩家问这句话的时候,眼睛是亮的。他们不是在问功能,是在问你能不能把这座工厂的钥匙交给他。一个不能Mod的自动化游戏,就像一台焊死了机箱的电脑,能跑,但没人愿意为它配最好的显卡。

说句实话,Mod支持这事,在很多策划心里排位很低。它不像传送带、科技树、物流机器人那么"显性",甚至感觉像是个后期补丁。但我的看法不一样:配方数据驱动,是Mod生态的第一块基石。它不是功能,是权力——你把"什么能合成什么、多少产出多少"这条供应链的命门,交给玩家了。

我这回不是纸上谈兵。两年前我参与过一个独立工厂游戏的项目,主程是个暴脾气,坚持"配方就写死在C++里,改起来最快"。结果游戏上线第一周,Steam评论区全是"求Mod"和"这游戏锁死了"。我们连夜把配方全部搬进JSON,花了两周,换来的是三年后工坊里两万个Mod。配方数据驱动不是锦上添花,是底盘。底盘不换,上面盖多少楼都塌。

这篇文章就是拆这台底盘。配方怎么注册、物品怎么起id、事件怎么广播,以及——单位最重要的——怎么让不同Mod不在同一张产线上打架。看完了你会发现,所谓Mod支持,本质是一个"把自己的代码壳温柔地剥开"的过程。

第1层:配方数据驱动,先把供应链拆成JSON

配方,落在工厂游戏里,就是"输入什么、输出什么、多久一个循环"。这个听起来简单,但设计上有个反向诱惑:写死在代码里最省事。你想想看,代码里写一个数组,"铁板=铁锭x1,耗时1秒",完事,跑得飞快,改起来直接重新编译。你省了事,但把Modder的路全堵死了。

数据驱动的配方,至少是这个样子的:配方描述文件是纯文本,可能是个JSON,可能是个ini,类型、名称、输入槽、输出槽、周期时长、产出概率,全都是一行行的数据。玩家装了个Mod,游戏启动时扫描Mod文件夹,发现"哎,这个配方文件比我原版的还新",那就注册进游戏——无需改一行引擎代码,玩家就拥有了给你工厂加产线的权力。

这里面有个手感差别,你细品:写死配方的游戏,Modder想加合成,得求着你主程开放API,改完得跟着你发版本;而数据驱动的游戏,Modder能落地当天就解包看配方,晚上就能写一个"铜矿直接出电路板"的邪道配方发工坊。双方付出的不是同一个量级的努力,前者卡的是你开发团队的脖子,后者只是给玩家递了把改锥。

真实案例我掰开揉碎讲一个:《星露谷》的配方扩展走的是谁都能看懂的XML路线。官方游戏里,从种子到农作物到加工品,那一整套配方全在Content文件夹里躺着,能直接打开改。社区有个经典Mod叫"Automate",做的就是让箱子、熔炉、酿造桶之间自动流转物品。如果没有底层的透明配方数据,这个Mod根本做不出来——它得让游戏知道"这个箱子是输入,那个桶是输出"。Modder靠读XML就能推断数据流,这是数据驱动给整个社区的回声。

我自己也翻过车。我们当时把配方全迁到JSON之后,忘了给Modder留注释,表单里全是"id_104"这种编号。结果第一个Mod作者上来就问:"这个104到底是什么?" 我他妈也忘了。后来我们加了item_name字段,又补了配方示例文件,这才算真正"数据驱动"——不只是给机器读,是给人读。

配方数据驱动的产出,不是技术架构,是社区文化的温度。你给玩家一把改锥,他能给你造一辆车。

第2层:物品注册表,每个物品都要有身份证

配方能加,那物品也得能加。你总不能Modder造了一个"暗钢锭",结果游戏里跟原版的铁锭长得一模一样吧。这一步的技术难点,在物品注册表,说白了就是给每个物品发一张永久的身份证。

这张身份证上有两个信息:一个是id,用字符串表示,唯一、稳定、改不了,就是"iron-plate"、"alien-alloy"这种;另一个是显示名,给玩家看的,"铁板"、"星外合金",这个允许改,也允许翻译成各种语言。凡是Modder新加的配方,必须向注册表登记"我要产出这个新物品",游戏才认他。

身份证机制有个铁律:id一旦定下,版本更新绝不能变。你原版把"iron-plate"改名叫"铁矿石",没问题,显示名能改;但你如果把这个id整个删了,那所有存了铁板的玩家存档全都变红叉。这是社区血泪换来的教训。我上一次做模拟经营,改过一个燃料物品的id,结果发了补丁以后论坛炸了——无数玩家存档里那块燃料图标变成"?",就因为我手贱动户口本了。

那注册表具体怎么让Modder的暗钢锭进游戏?两步。第一步,Mod文件夹里放着物品定义文件,填id、显示名、图标路径、最大堆叠数;第二步,游戏启动时扫描所有Mod,往注册表里塞。如果两个Mod都注册了同一个id怎么办?这就是冲突——后面第4层细说。

我拿《缺氧》来拆。这个游戏全名是"OnI",它的Mod生态很热闹,核心Mod"TrueTiles"能改建筑材质,"GasOverlay"能改气体显示,但这一切全建立在基础物品和建筑注册表不乱来的前提下。《缺氧》的建筑是数据对象,新建筑要注册"ID"和"名称",Modder在去往注册表的路上还经常走错路——Mod加载顺序不一样,没注册到的物品就变"缺失"图标。开发组后来在游戏里加了自动校验,检测到缺失id就弹窗提示"该存档依赖的Mod未加载",这才让玩家心里有底。

连《泰拉瑞亚》这种以刷刷刷知名的游戏,它的TModLoader也在干一模一样的事。物品注册表本质是给整个生态上了保险——Modder新加的"虚空锭"就算没贴图,注册表也能兜底显示个问号,存档不会直接报废。

说句大白话,物品注册表就是你游戏的户口本系统。没有这个,Modder加物品等于在别人家户口本上乱涂,你措手不及,他一脸无辜。

第3层:事件钩子,当工厂说话时谁在听

光有配方和物品还不够。Modder想做的第二件大事,是在你游戏的某个时刻插一脚。比如:"当玩家解锁电力科技时,触发我的Mod的专属事件,发一个钻石电钻"。这个"插一脚"的机制,就叫事件钩子(Event Hook)。

事件钩子的原理不复杂,但设计上有讲究。你游戏里得有一个全局的事件总线——你可以把它想成一个广播站。当"合成完成"、"建筑放置"、"科技解锁"发生的时候,广播站喊一句"注意注意,玩家合成了一条传送带",然后所有Mod注册过的事件监听器都能听到,想干的自己来。这就是"钩子":不是Mod主动轮询"有没有等到",而是游戏主动通知"到点了"。

双方向同步。

如果游戏不做事件钩子,Modder只能用一个丑陋而悲哀的招:每帧检查游戏状态,"现在是不是解锁了电力?"——帧率掉,手感差,还被其他Modder嘲笑。做钩子,本质上是你把一部分"触发权"让渡给Mod,你保留了"发生什么",Mod决定"接着干什么"。

掉落率这个问题是事件钩子的经典应用场地。《冰汽时代》虽然不是一个自动化工厂游戏,但它的"新伦敦档案馆"Mod社区把事件钩子用到了极致——Mod可以监听"城市温度骤降"事件,然后弹出特殊的报告,甚至改变一部分人心情。注意,原版游戏就这么设计:气象变化时会广播"cold_snap",Modder只需要写一个脚本监听这个信号,就能让城市产生新的叙事分支。这不是作弊,这是给了玩家第二人生。

《矮人要塞》是另一码事。它整个游戏建立在"模拟世界"的机制上,每个生物、每个事件的生成与消耗全靠钩子式的逻辑堆叠。支持Mod的方式很原始——让你直接改游戏初始参数去生成新神话生物,但这也算是广义的事件钩子:新生物被创造出来了,它会触发"诞生"事件,然后世界的传说记录器会跟进。这个游戏证明了:哪怕是最土的"改数据形成事件",也是Mod生态的骨架。

给个具体手感——你用Mod给工厂加了一个"自动灭火无人机",你要监听什么事件?你至少要听"建筑起火"、"火焰蔓延"、"消防队到达"三个信号。钩子齐全,你的Mod就能做出"无人机优先扑灭燃料罐区域"这种智能行为;钩子不全,你只能写死"全图乱飞",玩家看一眼就想把你无人机拆了。

事件钩子,是你游戏世界走向开放世界的唯一门票。

第4层:兼容协议,怎么让一堆Mod在同一张产线上不打架

前面三层都搞定了,最刺激的来了——Mod之间怎么相处。玩家装了三十个Mod,很可能其中两个都想给"煤矿"这个物品加一个新产物。一个Mod说"煤+水=油",另一个说"煤+空气=精炼煤"。这俩如果不商量,游戏启动时要么报错崩溃,要么只有一个生效,另一个白装了。

Mod兼容协议就是给Modder定的规矩,几条大部分时候管用的红线:

维度规则为什么这么定
命名空间所有新物品id必须带Mod前缀(如"mymod_steel_plate")防止两个Mod都叫"plate",户口本上重名
配方优先级同输入冲突时,可以声明覆盖别人配方,但必须显式declare让Modder知道自己在抢别人的配方,不是暗中作恶
物品定义一旦注册永不删除,只能弃用防止旧Mod的存档在更新后尸体都留不住
注册顺序加载顺序按Mod依赖声明排序模组B想用模组A的物品,就得先加载A

这四条是《城市天际线》的资产/Mod兼容性管理给我留下的创伤换来的。那个游戏Mod量大到爆炸,但经常因为两个资产撞了资源名字而直接紫屏。他们没做命名空间约定,全靠社区自觉,结果就是跨Mod兼容性成了天坑。反观《监狱建筑师》和《双点医院》,Mod社区规模小,但官方做了清晰的分区:建筑、房间、物品分开注册,冲突极少。

我自己的血泪史:当时我们在做环保主题的工厂游戏,有个Mod专注于"废水处理",加了一堆新配方;另一个Mod是"高品质回收"。结果两个Mod都需要"回收站"这个建筑,配方优先级又默认是最后一个加载的赢。玩家辛辛苦苦建了一百个回收站,一晚上全废了。我们后来在配方注册表里加了"冲突检测"——启动时扫描出两个Mod对同一输入有不同产出,直接在游戏里弹警告,让玩家去工坊评论区找Modder吵架。这招特别有用,因为玩家会自己把Modder拉到群里,逼着他们出兼容补丁。

模组兼容协议说白了,是你作为游戏设计师决定怎么当"居委会主任"——你可以完全放手随便打,但最后一定一地鸡毛;你也可以强制所有Mod必须通过你的审核再上线,但那等于没开放。最好的中间态是:规则透明,留给Modder协商空间,但你保留检测和警告的权力。

参数化设计:把Mod生态的旋钮交到你手里

上面三层都是机制,但光有机制你没有可调的东西。我做设计喜欢给团队一张表,把Mod支持的旋钮量化出来。你不是在"做功能",你是在"拧旋钮",调的是社区生态的底盘。

参数定义建议区间踩过的雷区
Mod加载顺序优先级同资源名冲突时,谁先注册默认按依赖声明升序,可被Modder手动覆盖优先级全靠文件名排序,会让人疯狂改名
配方专注匹配是否允许配方输入完全一致但产出不同的共存默认禁止,开放覆盖需显式声明共存时合成界面随机乱选,玩家崩溃
物品ID长度允许的id最大字符数32-64字符,要有前缀检查无上限会让数据表膨胀到卡顿
事件广播延迟钩子触发到通知Mod的时间窗口0-tick优先,1-tick可配置延迟过高会让Mod做出迟到的反馈
Mod冲突容忍度启动时对冲突的处理策略警告级优先,后期可升级为阻止加载一冲突就强退,玩家会去打差评

这几个参数彼此牵连。你拧"配方专注匹配=允许共存",那么"事件广播延迟"得跟着往下调,因为Mod需要在同一帧内做出反应,避免画面里两个结果同时出现。我见过一个项目,改了前者忘了后者,结果玩家按一次合成,界面上冒出两种产物图案来回跳——这种帧级Bug特别废口碑。

另一个容易被忽略的旋钮是"Mod加载面板"的复杂度。你给玩家展示多少个Mod冲突信息?一条警告弹窗就够了,你列三十条冲突清单,玩家看不懂,直接关游戏。我推荐保留"摘要+唯一冲突详情"的UI设计,兵不在多。

双路径对照:初级玩法快速上手 vs 进阶Mod研深

初级玩家视角——他装了个"更多矿石"Mod,进游戏发现山里多了个"暗钢矿"。这个玩家的需求很简单:这矿能采,采了能炼,炼了能做新工具,能感受到这是个新东西。你不用让初级玩家看配方文件,你只需要Mod做得好,他感知到的就是"变多了"。所以你的Mod加载机制得支持"即装即玩",最好连游戏都不用重启。做到这一点,新玩家对Mod的第一印象就是丝滑。

进阶Modder视角——他要在你的游戏里做一个跨Mod的综合工厂:用模组A的矿石,炼成模组B的合金,再供给模组C的终极科技。这位老兄需要的是:清晰的物品id文档、配方覆盖声明语法、事件钩子API示例。他不是在玩游戏,是在跟你的游戏结构对话。你的参数化设计工具,对他来说就是"和实体的约定"——只要id别变,配方声明的优先级系统稳定,他能玩出花。

你试想一下:如果初级玩家和进阶Modder都能找到舒适区,那你的Mod生态就是一个自生长的城市。初级玩家买材料,进阶Modder盖楼,你在中间只收一点"管理费"(配置规则的指引文档)。最怕的是你偏科——只做了一堆API但没有傻瓜安装包,或者只有一键安装但底层完全一团乱麻。

FAQ:Mod管线与配方扩展的五个热坑

Q1:Mod一多,游戏启动变慢,怎么办?

配方文本扫描是异步操作,但注册表加载是单线程的,拖慢是必然。解决方案是缓存——第一次启动时把扫描结果序列化,之后增量扫描,只读Mod文件夹的变化日志。但注意,这是每个Modder都会抱怨的点,你要在"加载进度"UI上给玩家吃定心丸,显示已加载的Mod数量,别让他觉得卡死了。

Q2:两个Mod想给对方配方增加副产品,兼容协议怎么管?

这是高阶玩法。让ModA声明自己的配方可以被ModB"附加产出",或者ModB可以监听"合成完成事件"额外生成物品。我的建议是:明确区分配方覆盖和事件叠加。覆盖必须显式,叠加靠事件钩子,不冲突的地方自由发挥,冲突的地方有警告。

Q3:我官方版本更新,会不会把Mod全搞废?

会,这是生态必然。唯一能减震的办法:版本升级时保留旧版物品id,新物品永远给新id,别删除,别复用。你给Modder留一条"弃用标记"而不是删除,他们至少能告诉玩家"这个Mod旧版已失效,新版换成了xx"。删户口本是灾难,弃用是温柔。

Q4:配方数据驱动做好了,但事件钩子做不来,行不行?

行是行,但这就等于你只给玩家一把改锥,却没给他工具箱。光有配方,Modder能加东西,但做不到"当X发生时触发Y"。上限会明显短一截。如果实在没工期做事件总线,至少把"启动时读配置"这个口子开了,剩下的让社区自己挂帧率焊。

Q5:我要不要自己做Mod例程,还是让社区自己摸索?

做。一个写满注释的"示例Mod"是你最好的文档,比一百页技术博客都强。Modder会直接复制你的示例去改。你剪裁一个能跑的骨架,比什么都珍贵。记住,Mod生产链的第一环是你喂出去的。

文章标签
自动化工厂策划Factorio-like流水线设计传送带吞吐物流网络寻路科研树节奏蓝图系统海量实体优化比例规划数学产能瓶颈削减理论优化即乐趣
更多专题全部专题
觉得有价值?点赞或收藏支持内容持续产出。
← 返回专题:自动化工厂流水线(Automation / Factory)游戏策划专题