【MCJE】如何科学的设计“僵尸增援”铜锭农场
配合视频观看体验更佳;
如有错误,请指出;
目录
结构概览
设计特点
使用说明
农场原理
理论计算与实验
卡顿
参考资料

一、结构概览



二、设计特点
1. 减小卡顿

2. 溺尸转换
溺尸转换的部分如下图所示,僵尸的行进方向如箭头所示,僵尸在行进过程中,一共受到三重阻力。
其一是脚手架会初步减速;
其二是底部的粘液块会再次减速;
其三是头部的水会进一步减速。
经过三重阻力的影响,僵尸的速度降至最低。由于僵尸头部一值浸泡在水中,当僵尸走到尽头时,刚好能够转化为溺尸。

3. 快速增援
如下图所示,该铜锭农场设置有快速增援模式。开启该模式后,僵尸经过的路上会部分粘液块更换为岩浆块,当僵尸走过岩浆块时,会受到伤害,由于僵尸有仇恨在挂机者身上,僵尸会召唤增援。
经过测试,僵尸走过六块岩浆块刚好不会被烫死。当僵尸走到尽头时会转化为溺尸,转化后的溺尸的血量和增援能力会被重置,可以继续召唤增援,从而实现快速增援。
在开启快速增援模式后,大概挂机10分钟左右僵尸和溺尸的总量便可以达到目标值。快速增援模式主要用于启动阶段,在达到我们想要的水平后,需要关闭快速增援开关,否则僵尸数量会无限制的增长,另外下面讲的卡顿检测器在快速增援模式下是不起作用的。

4. 重复启动
该铜锭农场在启动一次之后,由于部分溺尸会持有掉落物,当玩家离开,区块卸载时,这些溺尸并不会被清除,它们可以用于下一次启动。
5. 卡顿检测器
下图便是卡顿检测器,在正常模式(非快速增援模式)下,当发生掉刻时,卡顿检测器通过控制粘液块和蜂蜜快来减小刷怪平台的大小,来减小增援速度,使TPS恢复至正常水平。


6. 循环计数器
下图便是循环计数器,和卡顿检测器一样,循环计数器通过控制粘液块和蜂蜜来控制初始刷怪平台的大小。

需要注意的是卡顿检测器使用到了强模信号[1],比较器在检测木桶容器部分会输出强度为30的强模信号,强模信号这里不过多赘述,具体请查看参考资料。

三、使用说明
1. 该铜锭农场设计用于末地,不需要做特别的遮光,如果做在主世界,需要进行遮光处理。
2. 挂机时,挂机的玩家可以持任意剑类武器,站在玻璃板上对盔甲架进行横扫即可,攻击间隔为13tick。剑类武器请勿附魔横扫之刃。在挂机时无法进行食物补给,建议使用生命恢复1的信标,生命恢复提供的血量能够抵消饥饿造成的伤害,从而实现长时间挂机。

3.上图所示的左右两个音符盒是控制平台大小的开关,如果在挂机铜锭农场同时需要做一些其他的小工程,可以将平台大小调值6挡,如下图所示即可,产量大概在6~7k/h左右。

4. 如果追求高产量,则建议将平台大小调至2挡,如下图所示,产量取决于你的电脑性能。

5. 该铜锭农场的收集使用了打包机[2],不需要的可以自行更换收集装置。
6. 在建设过程中,注意需要将玩家和转化后的溺尸放在同一区块内。如果溺尸转化的位置和玩家不再同一区块内,在溺尸转化时,溺尸会对玩家失去仇恨。


四、农场原理
1. 区域难度
在讲解农场原理之前,有必要了解一下区域难度[3],不仅仅是僵尸增援铜锭农场,其他一些基于刷怪的农场的效率都会受到区域难度的影响。区域难度对僵尸增援铜锭农场的效率影响也是比较显著的。

打开F3,如上图所示,在Local Difficulty所在行有两个数,双斜杠左侧为区域难度(Regional difficulty),简称RD,右侧为副区域难度(Clamped regional difficulty),简称CRD。两者的关系如下图所示。

区域难度主要受到三个时间影响,分别是游戏天数、月相和居住时间。区域难度随着游戏天数逐渐增加,月相的变化提供难度的波动,在一个区块居住的时间越长,其难度也就越高。
当游戏天数大于63天且玩家在某个区块的居住时间大于16.67h时,该区块的副区域难度会保持最大1,且此区块的难度不会再受到月相的影响。
在这里我们只需要知道,当区域难度大于4或者副区域难度为1时,僵尸增援的效率最高。后续的设计和测试均会在此区域难度大于4或者副区域难度为1的条件下进行。
2.溺尸的转化
当僵尸的头部浸润到水中600tick(即30s),僵尸开始转化为溺尸。转化一旦开始,不会停止,在300tick(即15s)后,僵尸会转化为溺尸,因此一个僵尸转化为溺尸的时间为45s[4]。转化为溺尸后,原有僵尸的属性均会重置,比如血量,是否为僵尸首领,僵尸增援的能力等等,我们可以认为是在原来僵尸的位置重新生成一个溺尸,并将原来的僵尸从世界中删除。利用这个特性,我们可以通过击杀僵尸转化的溺尸,来获得铜锭。值得注意的是,转换后的溺尸是会保留原来僵尸身上的装备。
3. 僵尸增援
僵尸增援中的僵尸,泛指僵尸和继承僵尸类的生物实体,比如溺尸,僵尸村民,尸壳等,这些生物均能进行僵尸增援。僵尸增援的生物均为僵尸,并不会生成继承僵尸类的生物。僵尸增援的来源主要来自两个部分,其一是僵尸首领所增援的僵尸,其二是非僵尸首领的僵尸所增援的僵尸。这里我们统一一下说法,对于非僵尸首领的僵尸,下面会一律称为普通僵尸。在次,我们需要了解一下僵尸首领[5]。
1) 僵尸首领
僵尸和继承僵尸类的生物均有僵尸首领,包括小僵尸也有可能成为僵尸首领。
僵尸首领与普通僵尸最大区别就是最大血量值和僵尸增援的能力。僵尸首领的最大血量是一般是普通僵尸的1-4倍,如果看到最大血量大于20的僵尸,其一定是僵尸首领。尽管僵尸首领最大血量很大,但是其生成时的血量仍和普通僵尸相同,即20血。
僵尸有一个属性zombie.spawn_reinforcements,是用于控制僵尸增援的能力,下面用概率Psr表示。我们可以认为,增援能力是仅在困难难度下,僵尸在受到伤害时,召唤僵尸的概率,且每只僵尸每次受伤最多召唤一个僵尸。我们可以通过下面这条指令查看离我们最近的僵尸的增援能力。
/attribute @e[type=minecraft:zombie,limit=1,sort=nearest] minecraft:zombie.spawn_reinforcements get
在困难难度下,普通僵尸的初始增援能力Psr是介于0~0.1的任意一个值,即0<Psr<0.1。僵尸首领在生成时,其初始增援能力会在普通僵尸的基础之上增加,
是介于0.5~0.75之间的任意值,因此僵尸首领的增援能力为
,即0.5<Psr'<0.75。
僵尸首领的生成概率Pzl与副区域难度CRD有关,Pzl=CRD*0.05。对于因此当CRD最大时(CRD=1),有着最大的僵尸首领生成概率
2) 惩罚机制
当僵尸受到伤害并成功召唤一只增援僵尸时,召唤增援的僵尸和被增援的僵尸的增援能力均会有5%的衰减,以防止游戏难度过高。很显然,这个惩罚机制增加了溺尸农场的设计难度。值得注意的是,当僵尸转化为溺尸后,溺尸的增援能力会重新初始化。
考虑惩罚机制,每只普通僵尸(0<Psr<0.1)最多会增援两只僵尸;每只僵尸首领(0.5<Psr'<0.75)最多能够增援17只僵尸。
3) 增援区域
接着是僵尸增援的区域,对于僵尸的位置,我们可以认为是僵尸脚所在的方块就是僵尸的位置。僵尸增援的区域共有27个。分别是1个点区域、6条线区域、12个面区域和8个体区域,如下所示。

假设召唤增援的僵尸坐标为(x0, y0 ,z0),则增援僵尸的位置为(x1, y1 ,z1)可以用下列代码[6]计算:
int x1 = x0 + Mth.nextInt(this.random, 7, 40) * Mth.nextInt(this.random, -1, 1);
int y1 = y0 + Mth.nextInt(this.random, 7, 40) * Mth.nextInt(this.random, -1, 1);
int z1 = z0 + Mth.nextInt(this.random, 7, 40) * Mth.nextInt(this.random, -1, 1);
Mth.nextInt(this.random, 7, 40)表示在7-40之间随机取一个整数,包含7和40,Mth.nextInt(this.random, -1, 1)表示在-1、0和1之间任取一个数。
因此可以用于增援僵尸的位置一共有328509个方块,请问选中这328509个方块中任意一块的概率是否相同,可以思考一下。
……
答案是不同的。刚才提到僵尸增援的生成区域共有27个,每个区域被选中的概率是相同的,均为1/27。但是不同区域所包含的方块数量是不同的,很显现点区域仅包含1个方块,那么这个区域被选中的概率就是1/27,体区域所包含的方块最多,其中一个方块被选中的概率最小,仅有,可以看到相差甚远。
因此我们可以得到选中每个区域的方块的概率:
点区域:
线区域:
面区域:
体区域:
如果僵尸确定需要生成增援僵尸,则游戏会在上述区域内随机选择方块 并判断是否符合僵尸生成条件,如果不符合,继续选择其他位置,此过程最多进行50次,超过50次就生成增援失败,这种生成失败并不会触发惩罚机制。
值得注意的是,尽管点区域的方块被选中的概率最高,但是大部分情况下,此方块通常会与召唤增援的僵尸有碰撞冲突,因此大概率不会满足僵尸的生成条件,但也并非绝对,因此我们可以忽略点区域。
而你们常见到的僵尸增援铜锭农场通常就是使用的线区域进行刷怪,其实线区域已经足够产生链式反应了,但是我设计的农场采用的是面区域进行刷怪,主要就是为了减小卡顿。

五、假设与实验
1. 假设
我们在设计铜锭农场时,做出下列假设:
1. 假设可以生成增援的方块数量为Aa,由于采用的是面区域进行刷怪,因此平台的大小限制生成增援的比率如下,下面将其简称平台使用率 ;
2. 假设每秒攻击β下,即攻速为β/s,则就是间隔攻击的tick数。显然,攻速β越快,单位时间的产量就越高,单位时间杀死和需要生成的溺尸数量也就越多,所堆积的僵尸和溺尸的数量也就越少。对于剑来说,剑的最大攻速为β=1.6次/s,最小攻击间隔为
,因此我们可以选择13tick作为攻击间隔,此时的
。
玩家在不使用抢夺附魔的工具击杀溺尸时,掉落一个铜锭的概率为11%,每级抢夺魔咒会增加2%的掉落概率,因此使用抢夺三的剑击杀溺尸掉落铜锭的概率为。
为了保证溺尸有足够的次数进行僵尸增援,显然每次攻击的伤害越少越好。使用不含横扫之刃魔咒的剑对护甲值为0的生物进行横扫时,不管是木剑还是下届合金剑,其对于没有护甲的生物的横扫伤害均为1点伤害,并且横扫能够使在横扫范围内的所有生物都会受到横扫伤害,这就保证了伤害的持续和稳定。
但是僵尸在不穿带任何防具时是有2点基础护甲值,其中有些僵尸会生成防具,并且部分僵尸会捡起其他僵尸掉落的防具,这就降低横扫产生的伤害,使得横扫产生的伤害具有了不确定性,并且这种不确定性是无法进行计算的。因此我们需要设计实验进行测试。
2. 实验
1)实验1 - 1 存在僵尸的平均数量与僵尸的生成速度关系测定
a. 实验环境
实验环境如下图所示:

僵尸会生成在盔甲架的下方,假人通过横扫盔甲架来对僵尸造成伤害,当僵尸的生成速度一定时,僵尸的数量会维持在一定的水平。
为了保证测试结果的准确性,测试采用的是僵尸而非溺尸,因为在实际击杀的是有僵尸转换的溺尸,由僵尸转化的溺尸会保留原有的护甲,而自然生成的溺尸是不会生成护甲的;
僵尸会生成在脚手架中,生物实体在脚手架、梯子和藤曼等可以攀爬的方块中时,会取消不同生物之间的碰撞计算的,也就可以认为不同的生物之间不会发生冲突;
由于小僵尸很难在僵尸增援中起到作用,因此需要排除小僵尸;
实验中,假人会以13tick为攻击间隔对盔甲架进行攻击,即攻速
;
待数据稳定后,每14tick采集一次数据,每组数据采集100次。
b. 实验原理
通过命令方块控制每秒生成僵尸的数量Sps,当目标位置的僵尸数量稳定后,记录目标位置的僵尸数量。在保证其他地方的防刷怪后,可以使用地毯模组的 /log mobcaps 指令,开启怪物数量显示,按下Tab键,第一个值就是当前的怪物数量,我们需要记录每秒生成僵尸的数量Sps和当前存在僵尸的数量
。
c. 实验内容
我需要分别测定并记录当每秒生成僵尸的数量Sps=1、2、3 ... 20个/s时,对应的僵尸数量。显然这是一个重复的体力活,作为一个懒人,当然不会亲自测定,而电脑就能轻松完成这个工作。
Python正好可以用于测定,使用pyautogui模块进行自动化控制,采用ocr文字识别来识别当前的怪物数量,代码也是非常的简单,就是ocr文字是被有时会将8误判为“日”字,需要单独做一下修正,其他的识别错误直接忽略。
d. 实验结果
实验结果如下所示,由于生成僵尸时会有5%的概率生成小僵尸,因此需要剔除小僵尸的部分

做出曲线如下所示:

可以看到,实验图像趋于一条直线,我们使用最小二乘法计算其回归曲线为:
转换为与的关系为:
当Sps(或Sps)较大时,可以认为每次攻击到的僵尸(溺尸)数量与僵尸的生成速度Sps(或Spa)成正比。
2) 实验1 - 2 僵尸受到的平均横扫伤害的测定
a. 实验原理
在脚手架处的僵尸数量稳定后,每秒生成僵尸的数量Sps×僵尸基础血量20 就是每秒横扫产生的总伤害(即20Sps)。将总伤害分摊到每个僵尸身上就是僵尸平均每秒受到的横扫伤害,即
平均每次横扫产生的伤害为
因此我们只需要对实验1-1进行简单的处理,即可得到实验结果。
b. 实验结果

做出僵尸在不同生成速度下受到的平均横扫伤害图像,如下所示。

计算出其方差、均值
、平均偏差
和相对平均偏差
分别为
可以看到测试出的方差较小,相对平均偏差小于5%,属于可接受范围内。因此我们可以认为僵尸受到的平均横扫伤害与僵尸的生成速度无关。转换为每只僵尸(溺尸)每次攻击的伤害如下:
3) 实验2 模拟平台使用率与平均每次横扫每只僵尸增援数量的关系
由于游戏存在僵尸增援的惩罚机制,僵尸的增援能力随着增援的次数而衰减,这就很难从理论上计算每只僵尸能够增援僵尸的数量。因此,我们可以通过计算机模拟结果。
a. 实验原理
实验平台采用java平台。注意,虽然游戏中使用的伪随机算法与世界种子相关联,但是从概率上讲,当样品数量足够大时,游戏的随机结果与使用java自带的随机算法获得的随机结果可以认为相同。
模拟实验可分成三层循环嵌套

最外层循环用于改变平台使用率
和计算对应的平均增援数量
;
中间层循环用于根据概率选择生成普通僵尸和僵尸首领;
最内层循环计算每个僵尸能够召唤的增援数量。
根据实验1-2的结论公式5-10,可以计算出每只僵尸平均需要横扫次数为。A就是内层循环的循环次数,同时也用于计算平均每次横扫每只僵尸增援数量。
b. 实验结果

c. 不发散的刷怪平台大小计算
根据上述图像,当我们知道每只僵尸(溺尸)每次增援的数量时,就能够选择出对应的平台使用率。接下来计算一下每只溺尸每次增援的数量
:
根据和每次攻击到的僵尸数量
计算出每次攻击生成僵尸的数量
,将实验1-1的回归方程5-2,代入得到:
整理得到:
当时,可以近似计算
根据查实验2的图像可以得到平台使用率为
根据公式4-6,对应面区域的刷怪面积为
根据实验结果计算出我们需要使用到的面区域刷怪大小为1340格,这个可以认为是僵尸数量不发散时的刷怪面积。我们应该明白,实验结果总会出现误差,实验计算结果为我们限定了平台的大小,为了保证僵尸数量不发散,我们需要在
的基础之上,改变小范围平台的大小进行测试,这边大大减小了测试的工作量。
3. 测试与验证
经过测试,当时,僵尸总数会发散,但是发散的速度相对缓慢,适当降到
时,不再发散。在
的条件下,通过4h的测试,测试结果如下图:

图中横坐标表示时间,纵坐标表示测试过程中对应时间的僵尸和溺尸总量。
的大小可以直接反应出铜锭的产量,我们可以看到,初始
为500左右,但经过4h的挂机后,会稳定至1200-1400的范围内。
查实验2表格得,当时,对应的每只溺尸每次增援的数量
,则绝对误差
在误差允许范围内。
如果你的电脑性能足够好,僵尸和溺尸数量稳定后电脑的性能并不会被榨干,你可以在使用假人挂机的时候,进行一下其他的小工程。但是对于电脑性能不足或者追求更高的效率的玩家来说,仅仅依靠平台大小来控制僵尸和溺尸的数量就有些力不从心了。别急,后面会提供解决方案。

六、卡顿
1. 卡顿的来源
首先要提高溺尸塔的产量,就必须增加僵尸转化为溺尸的速率,即必须得堆积足够多的僵尸。因此卡顿的主要来源就是僵尸和溺尸的实体数量和它们之间的碰撞计算。
2. 卡顿的缓解
1)减少实体数量
缓解卡顿的第一个办法是减小实体数量,溺尸群体每秒受到的总伤害可以直接反应出溺尸的死亡速率,进而决定铜的产量。在铜产量固定的情况下,总秒伤是不变的,因此攻速越高,所需的溺尸数量就越少。
游戏中,剑在不丢失伤害时的最大攻速为,即间隔13tick进行横扫攻击。此时溺尸和僵尸的数量最小。
2)减少碰撞计算
我们可以看一下下面这组对比实验,当1000个实体挤在100个的区域内,游戏已经出现掉刻:

当1000个实体之间没有碰撞,游戏卡顿明显减少:

因此第二个缓解卡顿的方法是避免碰撞计算,当生物的脚部处于可以攀爬的方块,如脚手架、梯子、藤曼等,是不会进行碰撞计算的,也不会因为实体数量过多导致窒息死亡。虽然使用线区域进行刷怪的效率很高,但是线区域很难让僵尸快速的进入可攀爬的方块,来减少实体碰撞,而面区域进行刷怪就很容易进入脚手架。这就是选择面区域刷怪的原因之一。另外,在面区域运动的僵尸可以认为它们之间是没有碰撞的。
3. 卡顿检测器
卡顿检测器[7,8,9]对于提高铜锭农场效率,榨干电脑性能是非常有必要的。
1)原理
具有寻路AI的生物,在选定目的地后,会有两种重新计算路径的情况,分别是PP更新和路径超时检测。
当生物周围有PP更新时,生物会重新计算路径。
当生物超时未到达目的地时,生物也会重新计算路径。在超时检测中,所使用的时间是以毫秒为单位进行比较的,与游戏刻无关。当超时时间固定时,在没有发生掉刻的情况下走过的游戏刻和发生掉刻的情况下走过的游戏刻是不同的,通过检测这种变化,便可知道是否发生了掉刻。
超时时间与生物的移动速度和生物离节点目的地的距离有关,并非固定值。但我们可以通过控制初始条件相同来保证每次的超时时间相同。
2)卡顿检测器
通过上面原理便可以设计出下面的卡顿检测器,通过调低tps来模拟掉刻,当出现掉刻时该卡顿检测器会输出信号,使红石灯亮起。

在设计过程中,如果仅仅使用超时检测,僵尸的超时时间很容易受到周围环境的影响,造成超时时间不稳定。经过测试,当僵尸在更换路径后,通过下图指针指向的活塞,立刻在其周围进行一次PP更新,会使其超时时间相对稳定,测试出的超时时间能够稳定在11.88s。

此外,当发生掉刻时,僵尸有一定的概率会发生抽风,在两个重质压力板之间反复走动,造成输出不稳定,因此增加了一个检测抽风的装置,当僵尸发生抽风后,左上方的粘性活塞会推出,阻止僵尸移动,使机器恢复正常。
在添加了卡顿检测器后,通过3个小时的测试,测试出僵尸和溺尸的实体总量随时间变化的结果如下:

可以看到,在挂机2h后,僵尸和溺尸的总量随时间呈锯齿形变化,在这个过程中,游戏会在正常和掉刻之间反复横跳。本人的电脑CPU为i5-9300H,GPU为GTX1650。测试得到极限僵尸和溺尸的总量在1600左右浮动,铜锭产量在1w+/h。

七、参考资料
[1]: [mc红模]什么是红石强模?如何跨线传输强模信号? (bilibili.com)
https://www.bilibili.com/video/BV1yN4y1G76K/
[2]: mc 最小完美无t触静音六倍速分类打包机 1.13+_哔哩哔哩bilibili
https://www.bilibili.com/video/BV1HG4y1h7Lp/
[3]: 难度 - Minecraft Wiki
https://minecraft.fandom.com/zh/wiki/%E9%9A%BE%E5%BA%A6
[4]:溺尸 - Minecraft Wiki
https://minecraft.fandom.com/zh/wiki/%E6%BA%BA%E5%B0%B8
[5]: 僵尸 - Minecraft Wiki
https://minecraft.fandom.com/zh/wiki/%E5%83%B5%E5%B0%B8
[6]: Minecraft1.19源码获取来源 GitHub - Hexeption/MCP-Reborn
https://github.com/Hexeption/MCP-Reborn
[7]: 【懒穷简】实装优化的极限效率铜锭反应堆_我的世界 (bilibili.com)
https://www.bilibili.com/video/BV1BB4y1y7qN
[8]: 【MC】生存可用的卡顿检测器【2No2Name】_哔哩哔哩_bilibili
https://www.bilibili.com/video/BV19z4y1y7UQ
[9]:[mc] 便宜又好用-生存可用的卡顿检测器_哔哩哔哩bilibili_我的世界
https://www.bilibili.com/video/BV1cb4y1p7es