我的世界SFM超级工厂进阶教程:状态机
深渊兽你不要过来啊
2026年03月09日 21:56
我的世界?我的世界启动!

超级工厂没有提供变量存储的方式,使得编程十分受限。为了解决数字存储的问题,我们可以使用一个外部存储去存储变量。利用”has”句式去返回bool变量(只包含真假两种值的变量)来判断变量的大小与数值。

 

64内无符号整型小数字变量快速赋值

为了存储变量,我们需要三个箱子。第一个箱子是变量对应的物品(变量来源),第二个箱子是存储变量的位置(变量存储)寄存器,第三个箱子是多余物品的去向(垃圾桶)。

这是一段c++代码:

unsigned int a =0;

a=32;

这是等效的SFM代码:

input item:: from 变量存储 slot 0

output item:: to 垃圾桶

forget

input 32 item:: from 变量来源

output 32 item:: to 变量存储 slot 0

forget

都是对某个变量初始化后,为那个变量赋一个32的值。利用这个手段,我们可以将一些数值存储在某个箱子中。对于一个普通的原版箱子,我们可以存储27个非负数的整数变量(无符号整型),与传统编程不同的是,每个变量最大值仅为64。

当然,我们可以使用模组存储或者不限定插槽来存储更大的变量。不过要小心,模组物品可能会导致意外的问题。如无必要,还是建议使用原版存储方式(木桶)。

复习:函数”has”的使用方式

由于作者只引入了”If”判断一个使用bool变量的方式,”has”在本mod中必须绑定”if”使用。

如下,是一段has在if判断中使用的例子

if barrel top side slot 0 has = 32 item:: then

else  ----can delete else(if dont need this)

end

 

状态机引入

为了描述物体或行为的不同状态,我们引入状态机这个概念。

简单来说,状态机就是一个变量,它用不同的取值来代表系统当前处于哪种状态。如果这个变量的值和之前某个时刻一样,那就说明系统又回到了和当时相同的状态。

有了状态机,我们就可以条理清晰地针对每一种状态分别编写逻辑——也就是“按状态分别处理”。这样一来,程序结构更清晰,复杂度更容易掌控,代码的可读性也大大提升。(掉光的头发回来了)

在大多数编程规范中,状态机的变量名通常会包含“state”这个词,方便快速辨认。在SFM框架中,我们借助 “has” 关键字来编写状态机逻辑。

如下,是一段未加入行为的状态机代码,表达了0→1→2→0三种状态循环。

every 20 tick do

 if state top side slot 0 has = 0 item:: then

   input 1 item:: from 变量来源

   output 1 item:: to state top side slot 0

  forget

 end

 if state top side slot 0 has = 1 item:: then

    input 1 item:: from 变量来源

    output 1 item:: to state top side slot 0

   forget

 end

 if state top side slot 0 has = 2 item:: then

    input 2 item:: from state top side slot 0

    output 2 item:: to 垃圾桶

   forget

 end

end

为这个循环加入行为后,可以变成这样(熔炉):

every 20 tick do

 if state top side slot 0 has = 0 item:: then  -----empty furnace

   input 1 minecraft:coal from chest

   output 1 minecraft:coal to furnace north side

  forget

   input 1 item:: from 变量来源      -----empty furnace

   output 1 item:: to state top side slot 0   -----furnace with fuel

  forget

 end

 if state top side slot 0 has = 1 item:: then  -----furnace with fuel

    input 8 minecraft:raw_iron from chest

    output 8 minecraft:raw_iron to furnace top side

   forget

    input 1 item:: from 变量来源     -----furnace with fuel

    output 1 item:: to state top side slot 0  -----working furnace

   forget

 end

 if state top side slot 0 has = 2 item:: then  -----working furnace

  if furnace bottom side slot 0 has = 8 item:: then

    input 8 minecraft:iron_ingot from furnace bottom side

    output 8 minecraft:iron_ingot to chest

   forget

    input 2 item:: from state top side slot 0  -----working furnace

    output 2 item:: to 垃圾桶       -----empty furnace

   forget

  end

 end

end

#当然,实际使用中我们不会用状态机控制如此简易的状态循环。状态机的对手是多状态满足一定条件后的状态间互相跳变。

#良好的编程习惯:由于SFM没有提供定义与引用函数块的方式,建议在注释中写清楚各种状态的含义。对于巨量的状态(真的存在于MINECRAFT中吗),建议专门留出几行注释空间将状态的含义写在一起。

 状态机使用样例

状态机使用样例1:大部分单主材多合一产线(主材第一个输入)

name “fusion”

every 20 tick do

 if state slot 0 has = 1 item: then    -----empty fusion

 if not source has = 0 item:: then

   input item:: from source slot 1-26

   output item:: to each assistant

  forget

   if source has = 1 item:: then

    input 2 item:: from 变量来源  -----empty fusion

    output 2 item:: to state slot 0  -----ready except the main item

   forget

   else

    input 1 item:: from 变量来源  -----empty fusion

    output 1 item:: to state slot 0  -----stacked main item and assistant

   forget

   end

end

 end

 if state slot 0 has = 1 item: then    -----stacked main item and assistant

  input 1 item:: from source

  output 1 item:: to empty slot in each assistant each side

  forget

   if source has = 1 item:: then

    input 1 item:: from变量来源   -----stacked main item and assistant

    output 1 item:: to state slot 0   -----ready except the main item

   forget

   end

 end

 if state slot 0 has = 2 item:: then    -----ready except the main item

  input item:: from source

  output item:: to core

 forget

   if core has = 1 item:: then

    input 1 item:: from 变量来源   -----ready except the main item

    output 1 item:: to state slot 0   -----start fusion

   forget

   end

 end

 if state slot 0 has = 3 item:: then    -----start fusion

   if each assistant has = 0 item:: then

   if product has = 1 item:: then

    input 1 item:: from 变量来源   -----start fusion

    output 1 item:: to state slot 0   -----end fusion

   forget

   end

   end

 end

 if state slot 0 has = 4 item:: then    -----end fusion

   if not product has = 0 item:: then

    input item:: from product

    output item:: to storage

   forget

   else

    input item:: from state slot 0   -----end fusion

    output item:: to 变量来源    -----all products stored, empty fusion

   forget

   end

 end

end

状态机使用样例2:机械动力精密构件(利用状态机控制复杂程序的运行,节省占用)

name “create:precision_mechanism”

every 220 tick do

 input  minecraft:iron_nugget from me_1

 output item:: to hand_3 each side

 forget

 input  create:cogwheel from me_1

 output item:: to hand_1 each side

 forget

 input  create:large_cogwheel from me_1

 output item:: to hand_2 each side

 forget

 if state slot 1 has = 0 item:: then         -----empty factory

   if not source has = 0 item:: then

      input 1 item:: from 变量来源      -----empty factory

      output 1 item:: to state slot 1      -----running factory

      forget

   end

 end

 if state slot 1 has = 1 item:: then         -----running factory

   input 1 item:: from depot_3

   output 1 item:: to temp

   forget

   input 1 item:: from depot_2

   output 1 item:: to depot_3

   forget

   input 1 item:: from depot_1

   output 1 item:: to depot_2

   forget

   input create:precision_mechanism from temp -----try output product

   output 1 item:: to storage

   forget

   if temp has = 0 item:: then         -----if output successfully

        input 1 item:: from source

        output 1 item:: to depot_1

        forget

   else

        input 1 item:: from temp

        output 1 item:: to depot_1

        forget

   end

   if overall depot_* has = 0 item:: then

      input 1 item:: from state slot 1     -----running factory

      output 1 item:: to 变量来源      -----empty factory

   end

  end

end

●若需转载请联系作者