星期五报道#415-修复、改进、优化


3楼猫 发布时间:2024-06-22 00:25:02 作者:Wube Software Language

大家好 

虽然2.0开发中的许多时间花在了新功能和游戏质量上,但我们也在关注一些较小的细节和技术改进。

有确定性的多线程很难

最近一个同步异常错误被报告给了我们,涉及修改API以及多台玩家使用的Windows和Linux计算机。我的第一直觉是又有mod开发者干了什么好事,但这些年来我看到了足够多的错误报告,我知道在没有事先调查的情况下就下定论是个坏主意,也很容易挨回旋镖打脸。

我无法复现这个bug,但玩家们轻松的做到了。一开始我以为这是Windows与Linux之间的问题(我们已经遇到过很多这样的问题),但后来玩家能够在两台Linux系统的计算机上复现。接下来,我认为这是一个硬件问题,我们曾经看到过一些有故障的计算机,它们只是没有做它们应该做的事情。但即使在最好的情况下,说服某人他们的硬件坏了也要大费周章。

在几次尝试在我的一台电脑上复现这个问题失败后,Boskid使用他的多台电脑成功了。我想,成功在本地重现错误大约占了修复这个错误时间的90-95%。随着Boskid不断深究这个问题,他把问题出现的范围缩小到了不同计算机CPU内核数量不同这一问题。有了这些新发现的知识,他得以进行一项测试,可以在我的一台计算机上复现,通过人为让系统判定我电脑CPU内核比实际少来复现此bug。

这个问题的发生有四个条件,只有全部满足才会暴露出这个由多线程导致的问题,自2017年7月22日我把它放在那里以来,这个问题一直存在于游戏中。

1.一个需要监视区块生成的事件,并在某些事件发生时更改区块上的地块的mod。

2.一个请求生成几个地块mod。

3.一个立即强制生成所有请求的地块的mod。

4.游戏在两台CPU核数不同的计算机上运行。

“立刻”生成地块的逻辑会尝试使用所有可用的CPU内核,但这样做会导致,内核的数量——有变化时——会稍微改变地块生成结果。 

该修复程序实现起来并没有那么复杂,将在2.0中实现,但它表明多线程很难、有确定性的多线程更难。

多人游戏自动暂停

我们给专用服务器添加了这个功能,当最后一个玩家断开连接时,服务器会自动暂停。这非常有效,意味着你可以保留一个专用服务器,而不用担心当你离开时,虫子会吃掉你的基地。不过,有些边缘案例我们(直到现在)都没有时间处理。

情况1:当你加入自动暂停的服务器时,它会立即恢复运行——即使你还没有完全加载到游戏中。事实证明,这是一个非常简单的问题,只是因为一些原因,它多年来一直被忽略了。对于2.0,自动暂停的服务器将保持暂停状态,直到至少有一名玩家完全加载到游戏中。

案例2:加入游戏的玩家需要赶上正在进行的游戏进度。这对“正常”游戏非常有效,先加入服务器的玩家可以继续玩,不必等待新加入的玩家。但是,在玩家使用的地图较大或网速太慢时会遇到问题。如果服务器在他们没有加载完的情况下继续运行,加入的人可能需要1、2或几分钟的时间来下载、加载并完全赶上服务器的进度。对于2.0,我们添加了一个选项“当玩家加入时自动暂停”,它的作用和它的名字一样。

更快建造机器人的任务

感觉每隔一周就会有人问“为什么我的建筑机器人不工作?”在他们提供的屏幕截图中,有一个小警报显示“600个工作岗位缺少材料/机器人”。这个问题从机器人诞生之初就一直存在,直到今天我们还没有一个很好的解决方案。

问题是,给定建筑机器人需要完成的任务,游戏需要从物流网络中找到能够完成该任务的最佳机器人。检查“该物流网络是否在实体范围内”定义为O(Roboport数量,即后文N)。我们无法控制检查速度,因为玩家可以建造1个Roboport,或100000个,或他们的计算机所能承受的上限。因此,我们需要确保这种检查不会在运行时使游戏卡死。我们通过限制每帧处理建筑机器人的任务上限处理。

在1.1版本中,游戏每次刷新将检查3个建筑任务。如果找不到机器人就将会在这次刷新时停止寻找。而寻找机器人失败的警报持续10秒。因此,在一秒刷新60次,每个警报持续10秒的情况下,这意味着在第一个警报超时之前将创建了600个警报。这就是神奇的“600个工作岗位缺少材料/机器人”警报数量的来源。

自从我在Factorio上工作以来,它一直是这样工作的,并且可能会在一些基本层面上继续这样工作。我们不能简单增加每次刷新检查的任务数量,因为我们知道这会影响加载速度,玩家构建的roboport越多,加载就越慢。

今年早些时候,有人(论坛帖子)再次遇到了这个问题,但他们决定自己“解决”这个问题,通过做我们说不能做的事情:“每次更新检查任务”,从每次更新1个增加到374个。此外,他们还建造了36815个roboport。正如预测的那样,游戏加载会变慢。

星期五报道#415-修复、改进、优化-第0张

但这让我思考,如果我能加快判定速度呢?比如优化算法?当我想起我们在游戏中已经有了一套逻辑来处理roboport的物流和施工区域,并计算得到的矩形并集时,我受到了启发。简单地说,它所做的就是生成一组漂亮的消除重复的矩形,覆盖所有roboport的总面积。我们将其用于渲染,以避免roboport彼此靠近时出现大量过度渲染。

再加上对生成的矩形进行排序,这意味着我可以进行简单的二进制搜索,检查给定的任务是否在网络区域内。最后,检查范围从36815个机器人端口上的O(N),到900个矩形并集区域上的O(N),再到900个矩形并集区域的O(logN)。

检查“它在这个物流网络中吗”的时间大大缩短。有了这个加速,我就可以加快2.0版的机器人任务检查速度,并有望解决这个问题。



© 2022 3楼猫 下载APP 站点地图 广告合作:asmrly666@gmail.com