本篇教程由作者设定未经允许禁止转载。
模块化机械:社区版 从入门到入土 —— Part.4.1 并行配方处理
本篇教程皆在展示模块化机械:社区版的特殊功能。
本教程主要使用的模组为模块化机械:社区版 - 1.11.1-r55、CraftTweaker。
教程目录:
Part.4.1 并行配方处理(当前)
Part.4.2 工厂系统(未完成)
Part.4.3 工厂事件系统(未完成)
Part.4.4 智能数据接口(未完成)
Part.4.5 单方块 / 多方块机械升级(未完成)
Part.4.6 自定义 GUI 信息(未完成)
Part.5 配置文件解析(未完成)
环境准备
本教程强烈推荐使用 Visual Studio Code(以下简称 VSCode),可以大大减少你的魔改工作量。
使用 VSCode,你可以利用它的强大的功能来更快的完成复杂的操作,同时拥有代码提示,大大减少代码阅读难度和出错率,同时可以安装插件来扩展功能,使其更加强大。
此外推荐安装 VSC 插件 ZenScript Intelisense 与配套模组 ProbeZS,可以极大程度的增强你的 ZS 脚本编写体验。
阅读本教程即代表你已熟悉 ZenScript 的大部分高级运用,并且已经了解基本的机械创建与配方创建。
介绍
从 MMCE 版本 R23 起,机械开始支持类 GT 的并行配方处理,允许一次运行能够处理多个相同的配方。
注意:与工厂系统没有关系,两者相互独立。
本教程皆在为魔改作者提供部分并行内容的相关 ZS API,并介绍部分运作原理。
并行控制器
默认情况下,MMCE 自带 5 种并行控制器,当这些控制器位于机械的结构中时,机器就可以自动对配方进行并行化。
这是为提供并行化的最基本的方式。
5 种并行控制器分别名为“并行控制器”、“强化并行控制器”、“精英并行控制器”、“超级并行控制器”、“终极并行控制器”。
其默认的并行数从左到右为 4,16,64,256,512。
提示:你可以在 modularmachinery.cfg 配置文件中的 parallel-controller 类别中调整这些并行控制器的最大并行数。
右击并行控制器可以打开 GUI,允许玩家调整每个并行控制器提供的并行数。
最低可以设置为 0,最高为并行控制器的的最大并行数。
最大并行数代表该并行控制器最多可以给控制器提供的并行数量。
当前并行数代表该并行控制器目前为控制器提供的并行数量。
6 个按钮可以点击来调整相关的并行数。
输入框中可以输入精确的数值来调整并行控制器的并行数量。
如果安装了 TheOneProbe,还可以在 TOP 窗口中显示信息。
并行条件 / 原理解释
在尝试并行一个配方时,控制器会按照以下顺序判断配方的并行数:
并行化判断 ->并行数计算 -> 额外并行数计算 -> 配方并行数计算 -> 检查配方执行状态 -> 开始配方
不同颜色代表并行计算中不同的大阶段,每个阶段都必须通过检查才能够前往下一个阶段,接下来我们会一一介绍每个计算的小阶段。
并行化判断
在这个阶段,控制器会判断自身机械是否启用了并行,随后判断目标配方是否启用了并行,如果两者有一个未满足,则终止并行计算,并按照普通配方处理。
并行数计算
在通过了并行化判断后,控制器会检查自身结构中所有有效的并行控制器(即并行数 >= 1 的并行控制器),并将其并行数相加获得最大并行数。
此外最终值还会再加上自身机械的内置并行,最后获得到我们的配方最大并行数(不会超过机械定义的最大并行数)。
额外并行数计算
如果配方的最终运行时间小于 1 Tick(也叫 1 Tick 墙),则控制器会额外进行一次计算。
设当前并行数为 P,运行时间为 T,最终并行数为 FP,则计算方式如下:
FP = P x (1 / T)
FP 就是我们新的配方最大并行数。
配方并行数计算
在并行数计算完毕后,会对配方的每个需求(也可叫输入/输出)进行一次并行计算,获取每个需求允许的最大并行数,最大值不超过我们先前所计算的配方最大并行数。
随后配方的并行数会取这些需求的最小值,至此,我们配方的并行数已经尘埃落定了。
检查配方执行状态
如果配方的并行数小于 0,则代表该配方中的部分需求缺失,此时并行计算终止,并按照普通配方的方式计算失败部分,并输出错误信息至控制器状态。
开始配方
如果以上阶段全部满足,则控制器开始运行配方,并在控制器显示当前并行数与最大并行数。
如果安装了 TheOneProbe,还会在 TOP 窗口显示当前控制器的并行数与最大并行数。
ZenScript API
并行系统的大部分高级操作均提供了 ZenScript API,下方将一一展示相关方法。
启用/禁用机械并行
// 注意:需要模块化机械版本 R56。
// machineName 为机械注册名,parallelizable 为启用 / 禁用并行,true 启用,false 禁用。
MachineModifier.setParallelizable(String machineName, boolean parallelizable);
MachineModifier.setParallelizable("test_machine", false); // 将注册名为 "test_machine" 的机械设置为禁用并行化。
// 将名为 "test_machine" 的机械设置为启用并行化。
MachineBuilder.getBuilder("test_machine").setParallelizable(true);
启用/禁用配方并行
RecipeBuilder.newBuilder(...).setParallelized(false) // 将此配方设置为不可并行化。
RecipeBuilder.newBuilder(...).setParallelized(true) // 将此配方设置为并行化。
机械最大并行
// machineName 为机械注册名,parallelism 即为最大并行数。
MachineModifier.setMaxParallelism(String machineName, int parallelism);
MachineModifier.setMaxParallelism("test_machine", 128); // 将注册名为 "test_machine" 的机械设置最大并行数为 128。
// 将名为 "test_machine" 的机械设置为设置最大并行数为 128。
MachineBuilder.getBuilder("test_machine").setMaxParallelism(128);
机械内置并行
内置并行是除了并行控制器之外另外一个为控制器提供并行数的方式,缺点是它目前不可配置。
// machineName 为机械注册名,parallelism 即为内置并行数。
MachineModifier.setInternalParallelism(String machineName, int parallelism);
MachineModifier.setInternalParallelism("test_machine", 64); // 将注册名为 "test_machine" 的机械设置内置并行数为 64。
// 将名为 "test_machine" 的机械设置为设置内置并行数为 64。
MachineBuilder.getBuilder("test_machine").setInternalParallelism(64);
催化剂?编程电路?
假设我们创建了一个可以用于加速的物品输入,例如催化剂,又或是类似编程电路般的存在,由于默认情况下,并行计算会计算所有的输入输出的最大值,这时我们就需要为其设置为“不受并行影响”(格温不受影响)。
RecipeBuilder.newBuilder(...)
.addInput(<minecraft:diamond> * 1).setParallelizeUnaffected(true) // 将其设置为不受并行影响。
配置文件解析
parallel-controller {
# Whether the machine parallel recipe processing is enabled by default. [default: true]
# 是否默认为所有机械启用并行化?true 为启用,false 为禁用。
B:machine-parallelize-enabled-bydefault=true
# The default max number of parallelism for a machine. [range: 1 ~ 2147483647, default: 2048]
# 默认情况下,每个机械的最大并行数,默认为 2048,也可通过 ZenScript 为每个机械设置并行数。
I:max-machine-parallelism=2048
# Whether parallel recipe processing is enabled by default. [default: true]
# 是否默认为所有配方启用并行化?true 为启用,false 为禁用。
B:recipe-parallelize-enabled-bydefault=true
normal {
# Defines the max parallelism for the parallel controller. [range: 1 ~ 2147483647, default: 4]
# 并行控制器的最大并行数,默认为 4。
I:max-parallelism=4
}
reinforced {
# Defines the max parallelism for the parallel controller. [range: 1 ~ 2147483647, default: 16]
# 强化并行控制器的最大并行数,默认为 16。
I:max-parallelism=16
}
elite {
# Defines the max parallelism for the parallel controller. [range: 1 ~ 2147483647, default: 64]
# 精英并行控制器的最大并行数,默认为 64。
I:max-parallelism=64
}
super {
# Defines the max parallelism for the parallel controller. [range: 1 ~ 2147483647, default: 256]
# 超级并行控制器的最大并行数,默认为 256。
I:max-parallelism=256
}
ultimate {
# Defines the max parallelism for the parallel controller. [range: 1 ~ 2147483647, default: 512]
# 终极并行控制器的最大并行数,默认为 512。
I:max-parallelism=512
}
}