星际物流优化
 
      一直以来,星际物流都是整个《戴森球计划》中最为复杂的系统之一,不仅仅是代码层面的复杂,更是设计层面的复杂。很多工程师都曾经向我们提出过这样一个问题:“制作组,制作组,为什么我的运输船会去更远的xx星球而不是更近的xx星球上拿东西呢?”
 
        Good question! 今天这篇开发日志我们就将带大家大致了解一下星际物流系统的前世今生,粗略地向大家阐述一下我们对星际物流系统进行体验优化的迭代过程。
 
 
更新前的星际物流系统
      在此前的星际物流系统中,一个物品从物流站A运送到物流站B,是由一种名为供需配对的机制来运行的,每个供需配对包含了供应方、需求方以及运输物品的信息。每个物流站会在内部管理自己所有的供需配对,它需要对其他所有物流站进行遍历,看自己的供给和需求能否和其他物流站匹配上,并且把所有匹配上的供需配对储存起来。
 
        所有这些供需配对构成了一个纵横交错的物流网络,例如,如果宇宙中有10个星际物流运输站需求铁矿,有100个物流站供应铁矿,那么就有1000个关于铁矿的供需配对路线。
 
       在拿到所有信息后,物流站还需要每隔一定的时间进行更新。熟悉游戏的工程师都知道,星际物流运输站这个东西可是太好用了,从背包一拿,往地上一摆,设置好物品,源源不断的货物便“一支穿云箭,千军万马来相见”。所以,一般来说,整个宇宙中的星际物流运输站的数量都不会太少,相应地,每个星际物流运输站内部的配对信息就更是指数增长了。为了平衡整个供需关系(以及优化性能开销),每一次物流站在对配对信息进行取货判断时采取了“雨露均沾”的策略,也就是对所有的配对挨个遍历,并且在结束遍历后对上次的位置做个“标记”,下一次接着从这个位置进行遍历,以保证每个配对都有机会得到“宠幸”。
(壮阔的运输路线背后,是上千座物流站和数万条供需配对在每秒钟进行逻辑运算)
 
     是不是看到这里就已经开始大脑发晕了?更复杂的还在后面!为了不浪费工程师的运力资源,如果一个配对通过了各种逻辑检测(有没有货物,有没有电,有没有运输船等等),还需要考虑能不能顺手送一点东西过去,比如需求铁矿的塔内运输船在出发去拿货时,就要再进行一次判断,看看能不能顺手给对面的供应塔送点小礼物,角色互换一下;或者对面供应塔的船在抵达这边并卸完铁矿后,还要看看能不能顺点什么别的东西回去。
 
      我们的本意是好的,可是代码执行坏了。代码是一个死板的东西,它才不会管你的配对是不是更近还是更远,它只会根据你的规则来进行判断,现在这一帧检测到了这个配对,并且通过了所有的逻辑判断,那就盘它!
 
      这就苦了我们的工程师,尤其是在前期,运输船还比较龟速的时候,眼睁睁看着运输船放着几光年的矿区不去,一下子朝着几十光年的地方一去不回头。
 
 
开始优化
 
       一开始猪脑,哦不,主脑要求对星际物流系统的体验进行优化时,策划十分甚至九分不愿意。因为实在是太复杂了,以前的逻辑已经够复杂了,如果在这个上面还要进一步优化体验,只能朝着更复杂的情况去考虑。
 
       有句话说得好,设计的复杂度不会降低,只会转移。现在已经有了这么复杂的情况,造成了体验上的问题,那么就只有设计更复杂的规则去匹配这个复杂的需求。
 
       在经过策划和程序持续的battle之后,我们决定将“配对”这个机制扩展到多个维度,并且允许玩家在不同的维度上设置优先级,保证工程师们可以通过调整不同维度的配对进行优先级的设置,减少上述情况的发生,提升工程师对于整个宇宙工厂的掌控感。
(We can do it!)
 
新设计的供需配对一共有五个维度,分别是:
① 可指定单个物流站对单个物流站的点对点优先配对;
② 可设置星球对星球针对某种物品的“航路”,在航路里的塔优先配对;
③ 可设置行星系对行星系针对某种物品的“航路”,在航路里的塔优先配对;
④ 可设置物流站分组,同一分组号中的物流站优先配对;
⑤ 其他未设置优先的普通配对。
 
它们的优先级依次按顺序递减,也就是说,物流站会优先去看①点对点配对能不能运输,接着是②③④,最后再根据设置去看需不需要理会⑤这种最普通的配对。
 
(在设置了三号星对四号星的星球航路后,钛化玻璃会优先在这两个星球之之间运输)
 
      说干就干,在我们心情愉悦地开发一周之后发现出问题了,情况远比我们想象中的更复杂。在测试中我们发现,在特定的情况下,物流站在看①点对点配对的时候,因为翘曲器或者没能量等原因无法运输,但是在看⑤最普通配对的时候可以运输,这个时候就会去执行⑤最普通的配对(送或者取)。在普通配对拿完塔中货物后,轮到看①点对点配对时,发现已经没有货物了。或者在①无法运送时,另一些低优先级路线中的需求端会主动跑过来“偷塔”,因为它们并不知道①这边具体是因为何种原因被卡住了,缺能量还是缺翘曲器,这些情况的处理方式还不太一样,而且没能量还要分为接电和没接电两种情况,一些情况需要再等等高优先级,另一种又不能等(手动捂脸
 
        如果不处理这些情况,几乎一直会有低优先级配对抢高优先级配对的情况发生,优先级形同虚设。
(一种简化后的运输模型,箭头代表运输方向,双箭头代表高优先级配对)
 
      痛定思痛,我们修正了对优先级的理解。优先级并非完全决定谁先谁后,而且在高优先级无法运输的情况下,也不一定能轮到低优先级的配对,需要视具体情况而定。通过研究运输船的出发条件,我们发现在上图中对于每一个塔有9种情况需要讨论,供需端两个塔一共就是9x9=81种不同的情况需要讨论。
(81种情况的讨论,策划和程序表示看着这张表就掉头发)
 
 坏消息是平均每1000个物流站会增加~1ms的CPU开销。
 
(部分伪代码)
 
     为了实现这些机制,不仅要统一更新的时机(以前为了节省算力是分帧轮流更新),还需要引入一个“上锁”的机制,当一个配对互相运送时,会给彼此上一个锁。如果有优先级更低的配对想要去运输时,发现物流站上有高优先级的锁,就会“知难而退”;而优先级更高的配对想要去运输时,发现有低优先级的锁,就会直接无视这个锁。当然,这只是比较简单的情况,更加复杂的,比如说高优先级配对无法运输还有顺带送货的情况,就不在这里展开了。(但是可以在上面的讨论表中找到答案)
 
(“船”新的界面)
 
一些感谢的话
 
       在这次更新之后,船新的星际物流系统就要和各位工程师见面了。感谢大家在这段没有新特性的日子里耐心的等待,也感谢大家一直以来对《戴森球计划》的支持和喜爱。正如我们前面所说,设计的复杂度不会降低,只会转移。但只要是工程师的需求,我们都会认真考虑,不会因为设计复杂或者代码复杂就直接放弃。今后的日子里,我们也会持续对《戴森球计划》进行更新,谢谢大家!
 
2024-07-31
浏览702
主脑日志
登录后评论
评论
1