MCBE红石系统运行不完全分析(1)
前言
MCBE的红石系统已经出了五年了,在此之后出现了很多优秀的玩家和优秀作品,在众多玩家的努力之下也产生了一个十分完善的基于实践和经验的理论体系。但是遗憾的是纯理论的源码级的分析还几乎是空白。在这篇专栏(系列)中我尝试着填补空白,尽量完成这一工作,并随时弃坑。
有一说一,我自己连33门都不会做,所以这篇专栏几乎可以说出自云玩家之 手,请谨慎观看(
预备知识:
了解最基本的红石原件的基本功能
红石原件分类
在游戏内部,红石原件的分类是这样一个树形结构,这也是整个红石系统运行的基础,详细信息见表。
BaseCircuitComponent CSSC
BaseRailTransporter MCPR
ProducerComponent
CapacitorComponent CSCA
ComparatorCapacitor
PulseCapacitor
RedstoneTorchCapacitor
ConsumerComponent CSCC
PistonConsumer
PoweredBlockComponent CSPB
ProducerComponent CSPC
TransporterComponent CSTR
看不懂英语不用管,看下面的几条就行了:
producer就是自身发出信号的(比如红石块,拉杆等),下称生产者
capacitor就是比较器中继器火把和观察者
transporter就是红石线(传递信号)
cunsumer就是接受信号的,比如活塞,发射器等等,下面统称为消费者
铁轨?铁轨是啥
红石原件的信号源(Source)
信号源
这里先要给出一个概念叫做信号源,说白了就是给该原件提供红石能量的原件。我们来看个例子:

给比较器提供能量的是红石块和火把,所以它有两个信号源也就是右边的火把和红石线。
给中继器提供的能量的是比较器,所以它的源就是中间的比较器
同理红石灯和红石灯右边的红石线的信号源是中继器
注意
红石线不会作为信号源,因为它只能传递能量不产生能量
生产者本身就能提供能量,所以它没信号源
距离
游戏中每个原件都维护着它自己的所有信号源以及和该信号源的距离
红石信号强度的计算
这个算法其实非常简单:
首先计算每个信号源为自己提供的信号强度 strength =sourceStrength - distance
,说白了就是用信号源的信号强度减去信号源和自己的距离。然后从所有信号源提供的信号强度中选择最强的信号作为自己的信号(当然如果这个信号是负数就取0了)。来看个简单的例子:

绿色方块上方的红石线有两个信号源,它和左上方的红石块的距离是3,所以该红石块为它提供的信号强度就是12,而左下侧的红石块的距离是1,提供的信号强度是15 - 1 = 14.最后该红石线的信号强度就是max(12,14) = 14.
开胃小菜完成了后面就是稍微硬核的gt级别的微时序分分析了(
信号更新过程
红石刻
看图说话如下图是游戏的运行,一个方格是1gt,我们把红色的gt称之为红石刻,白色的暂时叫做普通刻。。在这样的gt是会更新红石信号的。两个红石刻之间的间隔也叫红石刻(redstone tick,rt),易得1rt = 2gt = 0.1s

信号的更新方式
原件有两种更新方式:
先根据当前电路状态计算出所有的信号值稍后再一起更新,暂时叫做缓存更新吧
立即更新,算出来值就马上更新了
capacitor(比较器,中继器,火把)和红石线是缓存更新的,其它的诸如生产者和消费者都是立即更新的。
1rt做了什么
在游戏内关于红石的1rt做的事情说多其实也不多,一共就下面三件事情(按照顺序):
根据当前电路状态(也就是上一个rt的电路)计算capacitor和红石线的信号,怎么计算也就是上面的算法(max(信号值 - 距离))。注意因为这几个是缓存更新的,因此算出来的新值其实是存起来了,原件的实际信号并没有进行更新。
计算和设置capacitor和和生产者的信号,到这一步才把capacitor的实际值进行更新(当前值 = 新值即可)。对于生产者没啥说的,是多少就多少,比如上1gt你拉了拉杆,到这时候就会把拉杆的值更新为15.
更新红石线和消费者的信号。对于红石线也是(当前值 = 新值),而对于消费者就是当前值设置为max(信号值 - 距离)。
为方便理解来举个例子:

拉下拉杆后拉杆的信号立即变为15(这个和红石系统无关):
然后等到下一个红石刻开始:
两根红石线和中继器的唯一信号源都是拉杆,然后他们就根据拉杆计算新值,这个值分别是14,15,14,但是这时候这三个器件的信号都还是0(因为新值缓存了没更新)
下一个行为拉杆信号还是15无事发生,这时候中继器新值和旧值同步了,它的信号变成了15(中继器虽然有延时,但是这个信号是立即更新的)
再到下一个行为,红石线同步自己的新旧值从0变到14和15;绿灯的唯一信号源是15,距离是1,因此它的信号从0变成15-1 = 14(注意这个值和与他连的红石线没啥关系),蓝灯的唯一信号源是中继器,它和中继器的距离为0,因此信号更新为15 - 0 = 15
然后这一rt结束了,等到下一个gt红石线和两个灯同时亮起(这个渲染细节和红石系统无关)。
???
你可能会疑惑为什么两个灯同时亮了,又或者你觉得中继器是有延时的,不会立即更新信号。但是事实就是如此。这个现象是由更新顺序和信号计算计算共同决定的。
再来做个简单练习,分析一下拉下拉杆后的所有原件的信号变化:
