1/3
2/3
3/3
MCBE 折学(折跃门科学)研究
xiaoqch
2022年05月19日 22:05
收录于文集
共1篇

零、阅读前

⚠️本专栏过于硬核,在查看前请确保:

  1. 大脑已正确安装且处于正常运行状态

  2. 可以适当超频,但是请注意大脑状态,防止出现温度过高,血压不足等情况

  3. 如发现理解突然变慢甚至停止理解的情况,请暂停观看本专栏并进行充分休息,根据情况请考虑跳过部分内容

一、介绍

  • 前人研究:mcbe末地折跃门总结​

  • 本文研究方法:分析BDS反汇编伪代码、编写LiteLoaderBDS插件与实际测试

  • 适用范围:理论上 1.14.60.04 到最新版均适用,但目前只在1.18.32与1.17.10测试过,1.14.60更早的版本也可能适用

二、定义

  1. 零点门:传送点为(0,0,0)的折跃门

  2. 伪零点门:传送点为(0,1,0)的折跃门(因为容易被误认为零点门)

  3. 主岛门与外岛门:分别是位于主岛与外岛的门

  4. 量产门:通过人工控制的方法,大量生成的门

  5. 自传门:传送点位于外岛的外岛门(或者传送点位于内岛的内岛门)

  6. 互传门:传送点位于外岛的内岛门(或者传送点位于内岛的外岛门)

  7. 基准点:生成新折跃门中需要用到的点,与触发生成的折跃门和世界生成器(种子)相关

  8. 127(双层)屏蔽层:位于126和128的两层平台,后续介绍

  9. 折跃门特判:有效生成点查找算法中的特殊判断,后续介绍

  10. 欧氏距离:三维空间直线距离

  11. SolidBlckingMaterial:石制,木制等材料,具体看评论区

  12. SolidBlckingBlock:属于SolidBlckingMaterial中的完整方块?具体看评论区

三、关键算法介绍

  • 基准点寻找算法(EndGatewayBlockActor::findExitPortal)

  • ⚠️由于该算法存在浮点数转换产生的偏移,以及该返回值的重要性,此处仅用于理解,准确计算另外提供(具体看评论区)

    • 根据给定坐标,在水平方向上,找出由(0,0)到该方块坐标的(x,z)的射线上,与(0,0)欧氏距离1024的点,记为点①,如果给定坐标是(0,y,0),则基准点直接确定为(0,0,0)

    • 由点①开始向(0,0)进行0~16次移动(射线方向反方向),每次移动距离为欧氏距离16,直到该点所在区块没有末地外岛方块(注意此处判断特殊,具体看后面注释),如果移动次数达到16次,则停止移动,此时记该点为点②

    • 由点②开始远离(0,0)的方向移动,每次16距离,直到遇到有末地外岛方块(一样是特殊判断),如果移动次数达到16次,则停止移动,此时所在的点即为基准点(y=0)

      注:判断外岛方块特殊条件,不包括末地小岛屿(浮岛)的方块,而且是以世界刚生成时的状态判断,即使后期将该区块清空成虚空,也不会影响该判断

  • 向下查找最高固体方块算法(BlockSource::findNextTopSolidBlockUnder)

    此处命名中的固体方块不要太在意,仅命名

    • 根据给定坐标,向下寻找直到遇到空气方块

    • 继续向下寻找,如果遇到SolidBlckingMaterial类型方块,判断成功

    • 如果找不到,则判断失败

  • 判断某方块上是否允许玩家生成

    • 该方块上方两个方块均不是SolidBlckingBlock类型方块

  • 有效生成点查找算法(EndGatewayBlockActor::findValidSpawnAround)

    • 距离n参数控制范围,searchForEndStoneOnly 代表是否仅允许末地石方块

    1. 以给的坐标为中心,向水平四方向延申n个方块(即边长为2n+1的正方形)为查找范围

    2. 在查早范围内逐个取点,并从y=127(包含)开始开始使用向下查找最高固体方块算法, 如果寻找失败,忽略该点,如果成功继续判断

    3. 判断该方块类型

      1. 如果是基岩,则进行折跃门特判:判断该基岩向下第二个方块类型,如果不是折跃门方块,忽略该点,如果是折跃门,在这基础上继续使用向下查找最高固体方块算法,如果成功,判断找到的方块上是否允许玩家生成,如果是则该点为有效点,否则跳过改坐标判断

      2. 如果不是基岩,则根据是否仅末地石分别判断,如果仅允许末地石,则根据该方块是否为末地石来觉定该点是否为有效点,如果非仅允许末地石,则根据该点是否允许玩家生成决定该点是否为有效点

    4. 从所有有效点中找出与给定的点欧氏距离最近的点,该点即查找结果,如果没有有效点,结果为(0,0,0)点(请记住这个点)

  • 最高点查找算法

    • 距离n参数控制范围,allowBedrock参数控制是否允许基岩

    1. 以给的坐标为中心,向水平四方向延申n个方块(即边长为2n+1的正方形)为查找范围

    2. 范围内逐个取点,从y=ymax(末地默认为255)开始向下逐个方块进行判断,直到找到SolidBlckingBlock类型方块

    3. 如果找到的是基岩且不允许基岩,跳过该点,否则设置该点为有效点

    4. 从有效点中找出y值最大的点,如果范围内值最大的点不唯一,则从y值最大的点筛选出x值最小的点,如果筛选结果仍然不唯一,则继续筛选出z值最小的点

四、折跃门关键逻辑

因为B站专栏中间插入图片会有奇奇怪怪的问题就放这里系列

  1. 任务队列

    当触发折跃门生成或验证时会将生成或验证请求添加到任务队列,末地每tick均会从任务队列中尝试取出一个请求,并执行该请求,请求的坐标在添加请求时确定

  2. 生成逻辑

    1. 主动生成

      指的是由杀龙生成的主岛门或人工或命令方块放置的折跃门,这类生成的门的坐标不受地形影响,杀龙生成门的顺序与具体存档有关,但每个门的具体坐标都是固定的,

    2. 被动生成

      指的是杀龙时伴随主岛门而生产的外岛门或由于零点门加载数据时生成的折跃,这类生成均有主动触发生成新折跃门的门,由触发的门的坐标为基础,通过一定逻辑决定新生成的门的坐标,也是折学研究最主要的研究方向

      注:不同的折跃门数据上只有自身坐标与传送点坐标以及存在时间的区别,不同方式生成的门只有在生成过程中的有区别

    3. 被动生成逻辑:

      1. 根据触发被动生成的折跃门的坐标,执行基准点寻找算法,找出基准点

      2. 根据基准点执行有效生成点查找算法,仅末地石,n=16,

      3. 根据上一步得出的点,进行最高点查找算法,允许基岩,n=16,得出的点y值+10即为新生成的折跃门方块坐标,在此坐标创建新折跃门,(实际上如果为杀龙生成的折跃门,内岛门也会在此时创建)

      4. 根具新生成的折跃门的坐标,执行有效生成点查找算法,非仅末地石,n=16

      5. 根据上一步得出的坐标,执行最高点查找算法,不允许基岩,n=5,将得出结果向上移动一格(记住这情况),将该点设置为触发被动生成的折跃门的传送点

      6. 根据触发被动生成的折跃门的坐标,执行有效生成点查找算法,非仅末地石,n=48,将得出的坐标直接设置为新生成的折跃门的传送点

  3. 验证与校正逻辑

    分为主动验证和被动验证,验证逻辑与已有折跃门传送点是否稳定,以及如何更改已有折跃门的传送点,也是折学研究的重点,主动验证和被动验证总是同时出现的,同时出现的两个验证互不干扰,以下将触发主动验证的门称为主动门,被主动门触发验证的门称为被动门,

    1. 关于区域及其特性:

      源码中的BlockSource类型,源码中部分地方会将其为Region,本专栏将其称为区域,其他地方可能会其称为方块源。此处只需要直到区域的一个特性,如果利用该区域获取范围外的方块,即使该方块所在区块已加载进内存中,尝试获取结果总会是空气(无法获取区域外的方块,因此称其为区域),将通过主动门坐标获取的区域称为主动门区域,通过主动门传送点坐标获取的区域称为传送点区域

    2. 验证请求

      请求验证时,会将主动门坐标与主动门传送点数据记录到验证请求中

    3. 主动验证

      根据请求中的主动门传送点数据,如果该点以及该点向上一个方块均不是SolidBlockingBlock类型方块,且不是传送门,而且该点向下一格方块类型为SolidBlockingBlock类型方块,则停止验证,否则对主动门传送点进行校正

    4. 主动验证校正

      使用传送点区域,以主动门传送点为中心执行有效生成点查找算法,仅允许末地石,n=16,如果结果不是(0,0,0)则将执行结果设置为主动门传送点,否则,在主动门传送点位置生成末地小岛,并再次以相同条件执行有效生成点查找算法,将执行结果设置为主动门传送点

    5. 被动验证

      使用主动门坐标进行和主动门验证一样的验证逻辑(所以正常情况都是验证不通过),如果验证不通过,则进行被动验证校正

    6. 被动验证校正

      以主动门传送点为中心,向三个方向延申32格的立方体内,寻找与主动门传送点距离最近的折跃门(被动门),如果找不到,停止校正,否则,以主动门区域,被动门传送点为中心执行和主动验证类似的逻辑校正被动门的传送点

    7. 验证触发时机

      1. 折跃门方块数据加载时

      2. 其他暂不清楚的情况

是否会触发校正与校正后传送点是否发生变化举例

五、重要特性介绍

  • 零点门产生

  1. 有效点屏蔽:

    如果有效生成点查找算法范围内找不到有效点,并且生成末地小岛后仍然找不到有效点,则不管主动验证校正还是被动验证校正,均会使被校正的折跃门变成零点门

  2. 被动校正:

    条件需要主动门与被动门传送点距离超出区域的范围,由于使用主动门区域来寻找被动门传送点附近的有效生成点会失败,被动门会变成零点门,常见四种情况是

    1. 主岛门触发的外岛自传门的被动验证

    2. 外岛门触发的主岛自传门的被动验证

    3. 主岛门触发的主岛互传门的被动验证

    4. 外岛门触发的外岛互传门的被动验证

  3. 人工放置:

    人工通过折跃门物品放置的门均为零点门

  • 自传门产生

  1. 当外岛门触发被动生成时,由于被动生成逻辑的第6步,新生成的门很可能会是自传门,同时由于第4步,触发被动生成的外岛门也很可能会成为自传门

  2. 当(0,y,0)处的折跃门触发被动生成时,由于基准点寻找算法的特性,新生成的门必定是自传门(可能是主岛零点门,也是自传门的一种)

  • 零点门刷门

    零点门加载方块实体数据时,会发出被动生成请求。由于各种因素,可能需要下线再上线才能触发,触发条件暂时不清楚,如需模拟,可使用结构方块加载零点门的方式触发

  • 伪零点门产生

    被动生成第4步中,如果找不到有效点,会返回(0,0,0),第5步由于区域的范围性,会继续找不到有效点,维持(0,0,0),然后将该点坐标向上移动一格设置为触发被动生成的的折跃门的传送点,该门变成伪零点门

  • 127屏蔽层

    折学研究的重大成果之一,让工程中难以稳定零点门成为可能,让外岛折跃门堆门工程早期脱离主岛折跃门

    定义,根据生成逻辑中两次有效生成点查找算法的使用顺序,将仅允许末地石的有效生成点查找算法定义为正向查找,将非仅允许末地石的有效生成点查找算法定义为反向查找,y=127是有效生成点查找算法开始的高度,由于反向查找相比正向查找多了一步玩家空间判断,使得126~128层成为非常特殊的层,下面具体对各种屏蔽进行介绍

  1. 正向屏蔽

    反向查找会成功,正向查找会失败的屏蔽,简单的在126或以下放置非末地石的SolidBlckingMaterial类型的方块即可

  2. 反向屏蔽

    正向查找会成功,反向查找会失败的屏蔽,通过127层留空气,126层放置末地石,128层放置SolidBlckingBlock类型方块,正向查找时会找到126层的末地石,查找成功,反向查找时也会找到126层的末地石,但是由于128层的方块阻挡玩家生成,所以会查找失败

  3. 双向屏蔽

    正向查找与反向查找均会失败的屏蔽,通过127层留空,126层放置SolidBlckingMaterial类型的方块,128层放置SolidBlckingBlock类型方块,两种查找均会失败,

    另一种双向屏蔽,在126或以下放置基岩,并防止折跃门特判成功即可

    或者将方块全清空,

  • 忽略某位置方块向下查找

    此处略过是对于有效生成点查找算法来讲的,通过在该点堆任意方块到127层,由于向下查找最高固体方块算法特性,该点方块将会被忽略直到遇到空气

跳过基岩寻找到下方的末地石

  • 127屏蔽层下移

    由于有效生成点查找算法特性,如果127层不是空气,会首先向下查找到空气,再进行查找,因此只需下移屏蔽层并在其上方补充任意方块到127即可,(如果补充方块是最高点查找算法会忽略的方块会有额外用途,如水方块与流动水(待验证),铁砧)

127屏蔽层下移至124

  • 折跃门特判

    有效生成点查找算法中遇到折跃门结构时会继续往下进行判断,且会无视是否仅允许末地石参数寻找SolidBlockingMaterial类型方块

  • 有效零点

    通过特殊方法使得(0,0,0)点成为有效生成点查找算法能查找到的点,一个比较简单的方法末地祭坛向上堆任意方块至127高度(包含),坐标(0,0,0)处放置末地石,并保证坐标(0,0,0)到(0,127,0)之间只穿过一次连续空气方块

    注:此方法未进行详细测试,不保证此方法维持的零点门的稳定性

  • 命名物品人工门变自传门

    如果通过被命名的折跃门物品放置的折跃门,会在短时间内触发被动生成,然后再短时间内触发验证,导致放出来显示不是零点门的现象,简单验证,往自己身上放置折跃门,会瞬间被传送至零点,再次进入该折跃门,会被传送至附近的点,暂未详细研究

六、应用:通用双层屏蔽折跃门堆叠框架

框架示意图

控制点移动示例

原理简单示意

  1. 寻找一个外岛折跃门(最好位于外岛向内岛的边界附近,一般选用与主岛门一起生成的外岛门

  2. 寻找该门的基准点,以该点为基础搭建此框架

  3. 预先设置好反向屏蔽控制点与高点方块,

  4. 在(0,0)处做好维持零点门稳定的准备,如33*33单层屏蔽(不能位于或高于127)或有效零点方案

  5. 使外岛门转成零点门,如传送点坐标为中心33*33范围单层屏蔽,屏蔽层必须高于原传送点坐标,注意折跃门特判与侧向挤压

  6. 想办法让外岛零点门反复加载数据(如退出重进)

  7. 当一个位置堆叠至无法继续堆叠时,移动控制点,重复操作

七、其他补充

  • 基准点寻找

    • 根据使用和游戏一样的计算找出可能的基准点,然后人工判断

    • 先让外岛零点门生成一个新折跃门,在该门附近寻找合适的点一般可简单判断出来

    • 先让外岛零点门生成一个新折跃门,并以新折跃门为中心,在y<127的某高度上铺一层97*97的平面,再次触发折跃门生成,如果基准点坐标为(x,z),此时在(x,75,z)上生成小岛,并在基准点(x-16,z-16)的位置生成新折跃门

  • 基准点验证

    • 与寻找的第三种方法相似,只需要屏蔽基准点附近33*33范围即可,如不想验证时实际生成新折跃门,可在该范围内y=255位置放置末地石

  • 堆门过程中量产门的生成越来越慢

    由于每个折跃门加载时均会添加验证请求,零点门加载时会添加生成请求,是同一队列的,并且每tick只会执行一个任务,因此当折跃门越来越多是,生成请求排队的时间也会越来越长(后期可能会需要等待一分钟以上)解决方法,上线时玩家的加载范围内尽量避开量产门区域

  • 移动基准点来扩大折跃门的堆叠范围

    通过改变自传门坐标即可做到,但是由于框架外生成自传门相对麻烦,基准点和初始地形相关,以及已有区域可堆叠数量已经足够大等原因,一般不会这么做

  • 改变量产门生成初始高度

    参考屏蔽层下移

  • 传送目标高于127的传送门

    传送门被动生成的第5步,使用的是最高点查找算法确定的触发被动生成的传送门传送点,因此此时该门传送点最高可255,但是一般该点不稳定,主动验证会进行校正,维持该点稳定的方法,在传送点改变前,把该点方块往下移动一格,并防止该传送门的被动验证即可维持稳定

  • 关于本文内容适用范围

    通过对比BDS 1.14.60.04与BDS 1.18.32.02反汇编伪代码,相关内容均未发现变化,但不排除又未发现的或者从其他联系不大的地方影响的,以实际版本为主,另外服务器与客户端应该没区别太大

八、鸣谢

感谢 LiteLDev团队 提供LiteLoader插件加载器,与大量API极大方便了测试插件的开发,

感谢 和风LeftSoftwind、野生的无产诗人、凉辰Liang00Chen 的讨论和纠错

感谢 和风LeftSoftwind 对1.17.10版本进行测试

感谢 MCBE开发交流群 其他参与讨论的所有小可爱们

最后,如果发现本文内容有误,欢迎指出