2. 原版的WorldPawn:Tick和GC机制
其实上面的问题可以拓展成三个小问题。
先来说说第一个,这些临时的成员是否增加了运算?如果是,增加了多少?
原版把WorldPawn分成了三类,Live(活着的)、Mothballed(封存的)、Dead(死亡的)。
活着的WorldPawn的开销与地图上的基本一样,每一tick都会计算。
封存时,每15000tick进行一次计算,换言之,一天4次计算。计算的项目很少,只有年龄和记录。(封存的成员可能在后续的游戏中被使用;不直接删除它们的一部分原因是故事性,一部分原因是不用一直重复生成)
死亡的WorldPawn不会进行tick。
不难看出,活着的WorldPawn对游戏整体的性能影响最大且持续。当你有30个这样的成员,就相当于当前地图多养了30个人。
15000个封存的成员才相当于地图上1个人,所以这部分的影响并不大。
死亡的成员是不会tick的,所以它们没有持续的性能开销,清理不清理没太大影响。
死亡与存活很好理解,举个例子,一波袭击被打退后,逃跑的敌人进入存活WorldPawn列表,阵亡的敌人进入死亡列表。游戏中每过1/4天,会尝试将所有存活的WorldPawn封存(除非他们在远行队或者有健康状况禁止封存,后面细说)。
第二个问题,原版游戏会定时清理这些成员吗?
从上面的讨论,可以看到,如果一切正常,存活的WorldPawn都会在1/4天后被封存,而封存的成员性能影响并不大,看起来非常完美。
阵亡的成员虽然不参与tick,但因为其他原因,比如释放内存、减少存档容量等等,原版游戏也会每1/4天尝试清除它们。清除的逻辑和RuntimeGC是非常类似的,不过没那么激进,这部分可以不细说,毕竟——阵亡的成员并不影响我们游戏的速度。
第三个问题,如果游戏清除了这些成员,为什么我没有感觉到?
如果我们相信原版的GC机制正常运转,为什么使用RuntimeGC还能感受到大幅度的tps提升呢?
敏锐的人可能发现了,原版存活的成员要tick1/4天后才被封存,在这1/4天里,它们还是和地图上的人一样要正常的tick,而RuntimeGC可以提前清理掉这部分,我相信一部分性能提升确实来源于此。
但更重要的,是我们前面讨论到的封存问题,有些情况发生,使得存活的成员无法正确的被原版机制封存。
如果你有300个理应被封存的、但无法被封存的成员,就相当于你的地图上多养了300个人,boom。
RuntimeGC暴力地,将大部分这些封存的成员删了。