【mcbe】【全物品】浅谈全物品 ep.2 卡顿

写在前头(感谢)
这篇文章是面向对全物品有一定理解,打算动手做却还没有开始设计的人的,并非是面向零基础的人的
对于全物品大量应用的双漏斗分类的原理,这里推荐 @smart_cuber 的视频。视频中展示的大部分分类单元在be都可以使用

本文参考了 @flag易 于2016年在百度帖吧发表的帖子《全物品自动分类机的设计》(链接:https://tieba.baidu.com/p/4920562733)感谢 @flag易 的这篇帖子,给刚入生电的我极大的启蒙
因为现在有较多的物品的设计资料(包括je的和be的),以及前人留下来的全物品单片设计。所以本文的侧重点是从卡顿这一点来说的
在这里感谢 @_hhhxiao 开发的 trapdoor 插件,可以精确地测量出服务器内的卡顿

本文是由我和同为天火服务器成员 @Maple_枫槭 共同撰写的。由我负责主要内容,@Maple_枫槭 负责技术指导
(这里打一波广告,天火服务器交流群:1029028772)
本文大体分为四部分,从“绪论”、“卡顿”、“全物品的组成”、“水道的设计”来系统地阐述全物品的设计方向。由于专栏的表现能力有限,这里只讨论设计方向。具体的设计之后会以视频的方式放出

目录(在全文放出后会统一整理)
2、卡顿
2.1、全物品有多卡
2.2、静态卡顿与动态卡顿
2.3、方块实体
2.3.1、什么是方块实体以及它为什么卡
2.3.2、哪些方块实体卡以及如何避免
(1)漏斗
(2)投掷器
(3)活塞
(4)箱子
(5)物品展示框
2.4、实体
2.5、其他卡顿
2.5.1、空置域
2.5.2、生物

2、第一章 卡顿
--------------------------
2.1、全物品有多卡
这里先抛出mspt这个概念
“MSPT,全称Millisecond Per Tick,毫秒/刻,表示一刻平均需要多长时间执行”——知乎答主MineCommander
所以你电脑算得越快,运算每一刻需要的时间就越少,mspt就越低。相应的,需要计算的东西越多,运算每一刻需要的时间就越高,mspt就越高,相应表征出来的就是游戏越卡
这里列出几个mspt让大家感受一下
虚空地图: 1.2ms
正常的世界: 1.4ms
全物品: 14ms
但mspt仅仅能表现出来cpu对游戏的运算,真正游戏的时候内存的占用、显卡的运算都会大幅度影响你的游戏体验
所以说全物品的卡顿不容小觑。同时降低全物品的卡顿必将成为设计中至关重要的一环
------------------------------
2.2、静态卡顿与动态卡顿
这里我先提出两个概念,静态卡顿和动态卡顿。静态卡顿就是全物品不工作时带来的卡顿,而动态卡顿是全物品正在分类物品时的卡顿
作为一个设置了常加载的大型生电设施,服务器会时刻背负着全物品的静态卡顿来为服务器成员提供游戏体验。显而易见的,全物品静态时长会远高于动态时长。且受限于输入速度,一般能够同时工作的分类单元不会超过四个,对于全物品共计600~800个分类单元来说,实在是有点少。所以在进行分类单元设计时,静态卡顿的优先级远高于动态卡顿的优先级
下面我将从静态卡顿和动态卡顿来分析各个位置可能产生的卡顿
------------------------------
2.3、方块实体的卡顿
2.3.1、什么是方块实体以及它为什么卡
“方块实体(Block Entity)是与各类方块关联的附加数据,作为方块的各种状态有限组合的补充”——Minecraft Wiki
mc有些方块可以与玩家交互或有特殊功能,如箱子、漏斗等有ui的方块和其他没有ui的方块,如篝火、蜂窝等。大部分这种方块不仅要经过一次方块渲染,还会经历一次方块实体的特殊渲染。这种特殊渲染会大幅增加卡顿(和其他普通方块比)。而全物品中每一个物品分类单元都会用到漏斗和箱子,算下来将会有数量庞大的方块实体。这也是全物品静态卡顿的主要来源
所以少用这些方块,或者用低卡顿的方法来使用这些方块则成为了降低全物品卡顿的重点之一
2.3.2、哪些方块实体卡以及如何避免
(1)漏斗
漏斗每gt会寻找漏斗上方的掉落物并吸取、尝试向指向的方向寻找容器并向容器输送物品。如果漏斗内有物品,则会尝试遍历一次漏斗内所有物品进行运输尝试。如果指向了容器,则会遍历容器内部所有可以储存物品的地方进行运输尝试。所以尽量减少漏斗内的物品,以及降低漏斗指向容器的储量是非常有必要的
同时锁住漏斗可以极大地减少上述卡顿。所以在静态时尽可能地锁住更多的漏斗可以有效降低静态卡顿
(2)投掷器
空投掷器的卡顿远低于空漏斗(约为空漏斗的24%),且满投掷器的卡顿略低于锁住的满漏斗(约为满漏斗的85%)(这里及本文以下的满漏斗都指64 1 1 1 1装填)。所以在静态下投掷器的卡顿要低于漏斗
但同时需要注意,因为投掷器投出物品的不确定性,常见的投掷器分类单元必须将投掷器装填满,而大部分漏斗分类单元都不用将第二个漏斗装填满。所以只有在难以布线或难以安排水道的情况下才需要考虑投掷器分类单元
在考虑满投掷器的8gt铁轨—侦测器时钟的情况下,投掷器分类单元的卡顿和横向双漏斗分类单元(即第二个漏斗为满漏斗的情况下)的卡顿基本持平(约为满漏斗的98%)
(3)活塞
“显存占用对于电脑基本上可以忽略不计,所以学姐叫所有移动端玩家,爬”——Maple_枫槭
毫无疑问,推容为基岩版的全物品单片布线带来巨大的便利,但活塞每gt自检带来的mspt、移动的方块以及活塞臂(包括收回的活塞臂和伸出的活塞臂)按方块实体渲染给显卡带来的负担都会造成较大的卡顿。同时因为活塞臂按照方块实体渲染,对显卡要求较高,对于手机端玩家并不友好
但横向对比(以下仅从mspt这一点上对比),未激活的活塞+空漏斗的卡顿低于锁住的满漏斗(静态)(约为满漏斗的78%),激活的活塞+空漏斗的卡顿基本等于解锁的满漏斗(动态)(约为满漏斗的100%)。适当地运用推容来代替横向双漏斗分类显然是一种有效的减少静态卡顿的方式
(4)箱子
大箱子为全物品带来了足够的储量,也同时为全物品带来了巨大的卡顿
箱子本身按照方块实体渲染,同时大箱子的大储量增加了漏斗的遍历次数,最后箱子内的物品数据会大量占用服务端(常加载全物品)和客户端(玩家渲染全物品)的内存,造成卡顿。对于内存的卡顿占用无法在mspt上体现。但打开箱子时,由于游戏会尝试读取大量数据,会大量占用mspt,造成mspt的波动
所以对于小储量的全物品,使用木桶会是一个相当不错的选择,可以有效降低渲染压力以及漏斗遍历次数。但木桶全物品单片的布线困难程度远高于箱子全物品,所以目前箱子全物品为主流的设计
特别说明,箱盒物品由于叠加了一层套娃,导致箱子内的数据指数级上升,其卡顿程度远超上述几种方块实体的卡顿。所以本人极不建议为全物品配套大宗物品分类
(5)物品展示框
物品展示框采用方块实体渲染,其中的物品以实体方式渲染。因为其静态、坐标相对确定的特性,对于mspt的占用并不高。但其渲染方式决定了对显卡的依赖程度较高,对手机端玩家并不友好
所以如果可以的话,尽量采用方块进行物品展示(关爱移动端玩家,从我做起)
------------------------------
2.4、实体的卡顿
“实体(Entity)包括在Minecraft中所有动态的、移动中的对象”——Minecraft Wiki
实体是类似于怪物、盔甲架等可以移动,且不必按照方块具有严格位置。具有朝向、速度、生命值、特殊行为等一系列数据
全物品这里的实体卡顿的主要来源是掉落物
由于漏斗的恶性bug(即不同种物品聚集在一起经过分类漏斗时,分类漏斗无法正常工作,具体可以参考 @今日木木的林昕 的《基岩版最恶心的bug 一直在恶化从未被修复》)

基岩版的全物品需要将掉落物以零散的方式输送进水道,直接导致了水道内掉落物实体数量巨大,同时也限制了输入倍速。原因很简单,较高的倍速会导致更高的物品密度,同时投掷器喷出物品的方向与速度具有较高的随机性,极易使掉落物聚在一堆,降低分类成功率
由于实体的数据较大,带来了更高的mspt。同时渲染方式注定了对显卡压力较大。一般来说实体造成的卡顿会远高于方块实体。所以降低全物品同时存在的实体数成为了降低全物品动态卡顿的最重要的一环
对于实体的优化方案,我会在“全物品的组成”和“水道的设计”两章给出
--------------------------
2.5、其他卡顿
2.5.1、空置域
“全物品挖空置域我也吐槽过不止一回了,为了挖而挖”——_hhhxiao
空置域可以有效地减少卡顿,但是嘛……
根据实测,空置域仅能减少0.3~0.4 ms的mspt。对于动辄达到十几mspt的全物品属实有点不够看
2.5.2、生物
防刷怪是必须的。实测大量怪物寻路会占用5~6 ms的mspt。所以需要将全物品做在远离地面的高空来阻止地面刷怪,同时全物品本身需要足够的照明来防刷怪,并且对于地狱门刷出的猪人也需要一定的清理措施

写在最后(作者的碎碎念)
卡顿是本文的核心一章,接下来的两章(全物品的组成、水道的设计)将从全物品的实现层来考虑如何减少卡顿。具体落到实处时需要将问题细化再细化,才能找到具体的、可实现的目标
虽然对于全物品来说空置域实在用处不大,但是mspt能少一点是一点
毕竟服里全物品空置域都炸了一半了,也不能填回去是不是
实测宿管不会刷在空置域上,所以这也算空置域的一个好处?_(:з」∠)_
(封面来源:天火创造服全物品框架)