自动化工厂流水线(Automation / Factory)游戏策划专题高级tech10 / 21 已发布

多人联机的世界同步与地质

客户端权威 · 地图分块同步 · 冲突仲裁 · 断线重连

· 15 分钟阅读
多人联机世界同步与地质:客户端权威、地图分块与断线重连的工程叙狱 Online World Sync & Terrain Chunking — 自动化工厂流水线(Automation / Factory)游戏策划专题

多人联机世界同步与地质:客户端权威、地图分块与断线重连的工程叙狱 Online World Sync & Terrain Chunking

为什么世界同步是多人工厂的第一块基石

说个惨痛教训。我参加过一个小型工厂游戏的内测,当时我们四人联机,服务器是对方租的廉价款。游戏本身挺好,有传送带、有分拣器、有自动化矩阵——但玩到第40分钟,神奇的事情发生了:我正兴冲冲往熔炉里塞铁矿,下一秒我人就站在了出生点,背包里原来那堆铜块全没了。群里炸了锅:联网就是为了这种"灵异传送"?然后开发者发来一条消息:"你们都看到同一块矿,但为什么消失的只有你一个人?"——好家伙,这是把我们当成了测试服务器。

这事让我意识到,多人联机同步里最坑的不是延迟,不是丢包,而是"命运的分岔"。玩家要的是"我搬的砖头,变成了你墙上那个洞",而不是"我搬的砖头,在某个时刻同时从我们俩手里消失"。要达成这种幻觉,你得先想清楚:世界到底听谁的?是那个能踢人的房主?是创建存档的机器?还是每个人脑子里都有一份世界副本,但大家投票决定哪个是真实?

这篇是系列的第09篇,紧接在蓝图系统(可复制与解耦)之后——蓝图是把"我的设计"抽象成可共享的东西,二是本篇的世界同步,是把"我们的设计"凝成同一个可交互的地质。你造出来的蓝图,如果换个玩家加载就能用,那才是多人。如果队友进来还得先等五分钟同步区块,那蓝图根本不存在。反之,如果没有地质层的稳定同步,蓝图就是一张不能落地的纸。为什么这个话题是第一块基石?因为单机是你一个人对着地质层施法,多人是两个人都对着同一条断层施法,而施法的法杖,就是同步架构。

第一层:客户端权威 vs 服务器权威——谁说了算

在多人工厂(类Minecraft)架构里,第一个要在白板上画的决策是:世界状态由谁持有。服务器权威(Server Authority),就是机房那台机器说了算。你按W前进,服务器算完你的新位置再广播给所有人。优点:安全、防作弊、一个版本统天下。代价:一秒tick如果只有20次,你按键盘到看见自己移位的反馈延迟就有50毫秒,体感就是"踩了油门但车还在想"。客户端权威(Client Authority),就是你的机器让你自己说了算。你在客户端上把人物坐标改成地图另一端,服务器会收到你的宣言并广播给别人,但它不验证合法性。

对工厂游戏来说,危险的不是跑酷作弊,而是跑位穿越和物品复制。如果每个客户端都对背包有权威,那A断线重连前把Bukkit复制给B,再回档自己那份,这就是能刷出无限铜线的"贤者之石"。所以权威分配不能一刀切——移动可能可以客户端权威(为了手感好),但背包、地块变动、流体流动这些核心经济系统,必须走服务器权威。

资源类型权威归属理由
玩家位置/视角客户端权威+服务器校验移动反馈要零延迟,但防瞬移
背包/库存服务器权威物品是经济根基,防复制全靠它
地块地质变动服务器权威挖方/填方影响全局导航和流体模拟
建筑物放置服务器权威(允许客户端预测)预测放置要能被撤销,幽灵放置是预反馈

自己开过服务器都懂,工业类游戏最怕的是"一个挂壁用移速MOD跑遍全图把你家铁采空"。所以即便你倾向客户端权威,至少在矿物节点、箱子这类公共资源上,必须一刀切进服务器校验。有个折中叫"预测+服务器仲裁":你在本地立刻看到采矿动画和物品入包(客户端预测),但服务器在后台验证后如果发现冲突(比如这格矿刚才被人采了),就回滚你的动作并广播修正。可能带来"你采集了,但物品又消失"的瞬间,但如果校验延迟控制在100ms内,玩家基本感知不到。

以《异星工厂》(Factorio)为标杆,它用的是服务器权威加一种叫"活动同步(Active Sync)"的策略——其实质是:地图分块后,每个区块的数据由服务器掌管,但客户端在区块内本地操作时是预测的。你拆一个矿机,立刻看到它消失并收到碎片,但服务器真正决定它确实消失后才广播给别人。它的tick率在单机是60,在服务器多人时往往降到30或更低,因为每个区块变化都要序列化成数据包。设计目的是保住"手快有手慢无"的采矿快感,但代价是服务器开太多区块时卡成PPT。玩家社群里最经典的repo就是"服务器把视野拉远,全图刷矿,帧率直接跳水"——其实不是矿在闪,是区块同步在烧CPU。

第二层:地图分块同步——地质层是区块的骨肉

聊到地图同步,程序员会很自然地想到"分块(Chunk)"——把世界切成16x16或32x32的格子,各自同步。但策划视角问的问题是:分块边界放哪里,才能让玩家在边界上不觉得"世界断了"?如果你把边界切在矿脉中心,那挖矿的玩家会发现矿脉一半有矿一半没矿,站在边界还能穿模看到另一半的地质数据没加载。

地质(Terrain)是工厂游戏的隐形指挥家。铁矿、铜矿、煤炭的分布,决定了第一圈传送带怎么绕;水体和高度差,决定了地基规划。多人时,地质层的同步优先级应该高于实体(比如一个怪物),因为实体好歹能瞬移,地质要是数据缺失,玩家会直接掉进虚空。

我设计里建议一张地图划分为若干"地块",每个地块32x32格,并给每种资源赋一个"地质指纹"——大部分底层数据其实从生成时就固定了(比如这格矿有4000单位,再生率为0)。这些"静态基础层"根本不需要同步,服务器只需在玩家首次加载区块时发送一次"地质描述",之后只同步那些真正被改变过的区块元数据。这样一来,带宽被压到一个让人睡不着觉的水平——真正吃带宽的永远是那几条传送带上的物品流和玩家的位置广播。

数据类别生成时是否确定同步策略网络开销
地质基础层(矿脉、高度、水)是首次加载发送,后续不更新低
区块变体(挖过的坑、建的墙)否定只在变更时广播增量中期
实体(飞行中的机器人、流体)否定每个tick插值广播高
玩家视野内细节否按需订阅中等

《幸福工厂》(Satisfactory)在这个问题上做出了很好的折衷。它的地图是手动设计过的(每条矿脉、每处瀑布都有讲究),所以"地质指纹"天然是静态的——服务器只需把整块地图的"骨架"在一开始发给客户端,几百KB搞定。之后的同步重点是玩家留下的印记:提取器、传送带、静置在室内的核废料桶。它的分块大小大概是300米见方,而它的同步频率不是每tick,而是有"数据陈旧度"机制——如果一个区域在半小时内没被任何人改过,服务器就懒得再广播它的快照。代价是:如果你在小伙伴不在线时用炸药轰平了一座山,他下次登录时可能得站在原地等几秒,让那块地的地质数据慢慢补进缓存——玩家把它叫"等着大地回忆起来"。

第三层:冲突仲裁——当两条传送带想穿过同一个十字路口

双人联机最容易爆发的不是拆迁纠纷,而是"时间的错误"。我见过一个真实案例:A玩家把铜矿石从甲点运往冶炼厂,B玩家同时把那条传送带拆了,改建一条更宽的。当服务器的tick迟到200毫秒,A客户端还是会看到自己的铜矿石在半空中向前滑行,而B那边已经在"老传送带已拆除"的状态。解决方案叫"先到先得"?还是"版本戳"?

在实际工程里,最简单有效的手段是给每笔地块变更、每个建筑的放置和拆除加一个单调递增的"操作序号"。如果发生在同一个区块内,服务器按序号顺序执行,后到的操作发现该地块已是"非预期状态"则拒绝。但你真想让玩家感受到"你的挖掘鼠标赢了对方挖掘鼠标"这种屁事吗?不,你要的是让冲突解决发生在服务器后台,而不是弹一个"冲突警告"给玩家。

具体做法是"善意合并":如果两个玩家同时往同一个方向扩展传送带,服务器允许双方都成功,甚至自动把两条线段连成一条;只有出现不可调和的矛盾(比如同一格被同时放置了采矿机和水泵)时,服务端才裁决并广播一个"军令状"修正。这听起来玄学,但落到机制上就是:每个操作带一个"优先级",建筑放置 > 拆除 > 移动物品。矿山开采优先于地基铺路?不,恰恰相反,铺路一旦落实就属于"地质变更",优先级最高——因为你不能等一个矿机开采完再去铺路。

冲突类型仲裁策略玩家感知
同时放置两建筑于同一格各自占领相邻空格,新增一个提醒稍显凌乱但不打断节奏
同时拆除又放置同一建筑放置优先,拆除回滚隐式,无弹窗
流体与固体互相占用固体优先可能流体回流,可接受
两个玩家移动一台装备后到的操作转移位置可能有点怪,但无数据损坏

《戴森球计划》作为一个本地单机但支持“宇宙”(运载火箭带来的卫星视角)类同步的先例,它处理冲突的方式很容易被误读——其实它用的是“重建式同步”:每个客户端都持有全部建筑的完整副本,服务器只同步“变更日志”(比如新增了一个分拣器)。如果冲突,服务器合并日志。但《戴森球》本质是“异步工厂”,冲突发生概率低,因为玩家之间很少在同一星球同一时刻碰撞。所以它尽管用简单的日志合并,却很少露馅。反例是《异星工厂》的多人服务器,冲突频发时它选择强一致:操作序号与服务器tick绑定,后到的冲突操作直接报错回滚。玩家见的最多的是“某某某于位置(3,5)尝试无法完成的操作”,看起来像系统在抱怨,其实在护着你们的世界不被撕裂。

我对这类冲突仲裁的建议是:别做“失败”界面,做“回滚的优雅”。如果服务器裁决后,A玩家看到的矿石回到了包子前的位置,不如立刻播一个小动画:矿车倒了,矿石滚回去了,配上“哎”的音效。把技术回滚包装成物理玩笑,玩家不是愤怒而是会心一笑——这就是策划给网络代码上的美妆。

第四层:断线重连——死亡简化中玩家意志的延续

多人游戏里有两个“贱人”:一个是“掉了的人”,一个是“看着掉的人”。掉线重连机制若写不好,比任何怪物都扫兴。尤其工厂游戏,你走开几分钟去泡面,回来发现暂停键根本不属于你,队友已经把传送带改成火车线,你的矿机孤零零漂在空中。断线时,那块你刚开出来的飞地,会不会被别人顺手拆了?

稳妥的机制是“代理接管”。玩家网络断开瞬间,服务器不立刻把他的角色踢下线,而是把控制权交给一个AI托管,持续N秒(建议90-120秒,足够让人跑回来)。这段托管期,AI执行“安全策略”:不新建建筑、不拆除已有、能继续收矿但默认入箱不运输,避免它跟活人抢比特。超过时限才彻底踢出,把角色连带库存冻结在副本里,等待重连。好处是:队友看到“小明托管中”不会太担心,而小明重连后发现自己没被世界遗忘。

重连本身也要讲“地质体验”。当你重新载入时,客户端不该闪烁“加载区块”的加载条把玩家扔回上次位置——而应该从“角色所在视角”平滑过渡:服务器把你上次持有的区块状态打包,先静默加载地形,再加载建筑,最后才是NPC和动物。这样你回到世界的感觉是“这个世界一直等我”,而不是“我重新进入了一个陌生副本”。

断线处理阶段玩家体验目标时长参考
1. 意外断线立刻托管,队友看到AI操作0-2秒
2. 托管期避免资源生产停止,AI安全操作90-120秒
3. 掉线限制角色冻结,库存保护再+60秒后踢出
4. 重连静默加载,视角连续3-10秒

讲一个让我难忘的玩家故事。《异星工厂》的一个服务器上,有个叫“索菲”的老哥在半夜四点,在一条巨型传送带的正中央没电了。他的角色掉线被托管,AI坚持把传送带上的铜板不停往一个箱子里续。队友们发现这条传送带居然开始结块,有人提议拆掉箱子,但“索菲”重连后第一句话是:“别拆!我那儿囤了一批级品,等我建个火车站过来取。”——托管期不仅让世界没坏,还帮队友看到了一道可能产生瓶颈的“瘀血”,而重连后玩家把瘀血变成了规划支线。这就是断线重连作为“设计”的好案例:它不是补丁,而是给玩家提供“残局”乐趣的契机。如果你设置断线即消失,这种火花就不会发生。

附录:给你的同步系统留一张配置表

下面这张表是我每次做多人系统设计时先填的“底表”,你也可以照着抄,再改成自己的参数。重点是:每个数字都有体感目标,不是拍脑袋。同步频率不是越高越好,带宽不是越低越好——要看玩法是散兵游勇还是基地经营。

参数项建议区间体感目标备注
区块大小16x16 ~ 32x32格边界上资源不“撕裂”地质资源跨度应小于区块边长的一半
服务器tick率20 ~ 30 Hz(工厂类)建筑放置延迟<80ms30Hz以上带宽激增但体感几乎无提升
实体广播频率4 ~ 10 Hz运动不“闪现”但可接受传送带上的物品流可降低到4Hz插值
冲突回滚容忍度500ms窗口内回滚玩家感知“意外”但合理超过1秒会让人恼羞
断线托管窗口90秒 ~ 120秒足够接杯水,但不过度延宕配合断线保护库存开启
重连最大加载时间3秒内完全交互不显得“卡”,无缝用静态地质层预加载跳过

有一个我自己翻车过的数值:我曾把区块大小设成64x64,想着减少分块数量、降低管理开销。结果矿区跨区块出现前后不同步,A玩家看见矿机还在,B玩家已把它挖成空洞,视野里出现“悬浮矿机”。修了三周客户端预测才勉强掩盖掉。教训是:区块边界是地质层的断层线,你想减少网络负载,不如去压缩实体数据,别动区块尺寸。

常遇问题与常见坑

问题1:玩家数量多少才需要分块同步?
初级团队可先尝试“全地图同步”,就是一张地图所有状态都由服务器广播,任何变化即时推给所有人,数据量可控时(比如小于8人)也能跑。但一旦建筑数破千,带宽就会崩。建议在项目原型验证段就上分块,哪怕简单点。

问题2:客户端权威是不是对玩家更友好?
是也不是。我见过有朋友做的游戏用客户端权威,移动手感确实一流,但工业类游戏的“掠夺”行为(把别人家箱子拆了拿走)一旦被延迟掩盖,就会变成仇恨工具。底线是:吃进背包的物品必须过服务器。

问题3:回滚会不会让玩家觉得世界是假的?
会。但你可以用“堆叠修正”缓解:不是把物品白回滚出去,是产生一个“幽灵物品”让玩家主动移动它归位。这也是为什么我很推荐“善意合并”冲突策略—尽可能在合并里假装无事发生。

问题4:地图形大(无限生成)时怎么分块?
别放无限。工厂游戏的核心是改变,不是探险。设一个合理的世界边界(比如2km x 2km),在边界做一道可以翻越的自然断崖。这样STC基础层就能成为恒定数据,同步负担降到最低。

一些小坑

坑1:觉得服务器权威就是安全之选。其实如果服务器代码一团糟,权威一样会被反编译客户端伪造数据。权威是管理优势,不是安全保险。你需要加一层校验签名或哈希。

坑2:把同步频率直接等于tick率。tick是游戏逻辑心跳,同步是网络心跳,二者解耦。用平滑插值算法在两次同步之间补运动,这样即使sync只有8Hz,画面也像30fps。

坑3:忽略“演出层”的回滚包装。上面说的“矿石滚回去”的笑果是真实案例,能大幅降低冲突回滚的挫败感。别把回滚做成生硬的“无效操作”弹窗。

FAQ

Q1:如果不做分块同步,能撑起几个朋友联机?
经验值:全地图同步+服务器权威,上限大约4~6人,且不能大搞基建。超过这个规模,推荐分块,纯带宽收益就能有十倍差距。

Q2:断线托管会不会被恶意利用?
可能,但你可以设置“托管中不能拆除”和“保护库存”,再让托管AI不参与战斗。如果你有PvE环境,这些足够堵住绝大漏洞。

Q3:服务器权威下,玩家放置建筑延迟高怎么优化?
引入“客户端预测+服务器裁决”。本地立刻放出一个幽灵预览并允许微调,确认后服务器再提交,失败则回滚并提示。业界的《异星工厂》和《幸福工厂》都是这么干的。

Q4:分块边界上的矿脉被挖了,但相邻区块没同步,会出现什么?
会出现“矿脉边界的幽灵矿”。解决方案:让矿脉生成时不要跨区块,或者强制跨区块矿脉拥有统一的“地质ID”,那个ID由服务器管理,修改时所有相碰的区块一起锁动。

Q5:多人联机时,二玩家能否看到同一个动画(比如传送带上的物品)?
如果同步频率低于10Hz,物品闪现是会发生的。一般做法是物品位置由服务器发送“关键帧”,客户端插值。但如果你追求完美同步(连物品抖动都要一致),那建议提升同步频率到30Hz并备好高带宽,或者降低玩家数量上限。

最后留个引子:地质同步做完之后,你要面对的不再是工程师的难题,而是玩家的朋友了。一个能让一群朋友深夜还排着队在传送带前等“矿石回滚”的世界,才是真的活世界。

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