Minecraft(我的世界)中文论坛

标题: 1.12 连锁命令方块(CCB)新机制研究 [打印本页]

作者: pca006132    时间: 2017-4-22 09:52
标题: 1.12 连锁命令方块(CCB)新机制研究
本帖最后由 pca006132 于 2017-4-26 22:32 编辑

个人认为2b的研究 http://mcbbs.tvt.im/thread-687926-1-1.html 有些未覆盖到的位置,故此发一些我的研究及猜测了

本研究会谈及CCB执行命令一瞬间的工作,新的gamerule maxCommandChainLength,以及一些CCB新的实用的功能

简写:
- ICB: 脉冲命令放
- CCB: 连锁命令方块
- RCB: 循环命令方块
- CB: 命令方块
- NTE: Next Tick Entry,就是放在一个列表里等待下一个gt(游戏刻)处理的意思
- gt: 游戏刻,game tick,游戏里最小可描述、测量时间单位
- 微观延迟: 在1gt里的先后次序,虽然有时间上的分别,然而只是先后次序的概念而不是一个时间单位

简介CCB新机制
chyx的CCB新特性简介 http://mcbbs.tvt.im/thread-687773-1-1.html已经很简单的概括了CCB在1.12的更新: 不再是NTE的东西了。
这代表什么呢?
以前,CCB是先放入NTE,然后下一个gt根据放进NTE的顺序来决定执行次序的,这代表了两个问题:我们没法在1gt内加入新的ccb并且执行命令;我们无法让后面的命令取消执行。我们只能做的是替换掉里面某些ccb(NTE不会记录它们的命令)来做到瞬间替换执行的命令。
现在,CCB是即时处理的了。也就是说是到该CCB执行命令的时候才传递信号给下一个执行命令的CCB,让后面的CCB执行命令。这分别是很大的,因为这代表了我们能够在那1gt里修改ccb朝向达至激活不同的链;清除ccb避免执行后方命令;在后方加上ccb执行更多的命令;修改UpdateLastExecution为0b以在同一cb执行多次命令。



CCB新机制研究
CCB默认1gt只能执行一次命令,除非设置了UpdateLastExecution为0b,这样就不会检查这gt有没有执行命令

CCB受到信号时,会先决定待会让哪个方位的CCB执行命令,然后自己执行命令,然后传信号到先前决定的方向的CCB执行
证明1: CCB会先决定待会让哪个方位的CCB执行命令,然后自己才执行命令。
先用CB搭建一个分支结构



设它们的号码为:
1
2 4
3

2的命令为把自己的朝向改为朝向4
3的命令为say 3
4的命令为say 4
然后激活ICB。

如果CCB是先执行命令,后决定待会让哪个方位的,执行命令的应该是4,聊天栏的输出应该是4。然而实验结果是3.
因此我们可以得知,CCB是先决定待会传信息给哪个方位的ccb的。


证明2: CCB先执行命令,后传信号到下一个ccb。
我想到的有两种证明方法: 分别为在后方加上ccb及移除自身。为了简单,这里会讲解后者。
先用CB搭建以下结构




第一个CCB的命令为 setblock ~ ~ ~ air
第二个CCB的命令为 say 1

如果CCB是先传递信号,后执行命令,那么应该会有第二个ccb的输出,也就是聊天栏会输出1。然而实验结果为无输出。
这证明了CCB是执行命令后传递信号的。



新的gamerule maxCommandChainLength
这个gamerule决定了CCB的信号能经过多少个ccb。默认65536。对icb及rcb无影响。

证明1:
先用CB搭建以下结构








从上而下命令为
say 1
say 2
say 3
...

预先设置gamerule: /gamerule maxCommandChainLength 4
然后启动icb。
输出为: 1-4。

证明2:
把以上结构第一个ccb调为auto:0(红石激活)。
把以上结构第二个ccb的命令清除掉。
把以上结构第三个ccb调为条件制约(conditional)
然后启动icb。
输出为4。

证明3:
你把那gamerule调成0然后开rcb及icb就行了。。。这里就不多说了。

这说明了该gamerule只对ccb有效,而且决定了CCB的信号能经过多少个ccb,而不是执行了多少命令。并且auto,条件制约等对其并无影响。



CCB实践
相信看完上面的证明,大家也知道了起码一个实践方法: 循环。方法就是弄个ccb的环,然后把里面的ccb改为UpdateLastExecution:0b

其次,我们也可以玩分支结构。
虽然从上面的证明中我们可以看到是没法转自己的,然而我们可以转下一个啊!
加上一些条件制约,我们就能开心的玩if之类的条件控制了,比较方便。

然后我们也能玩动态加载。虽然上面没写,然而大家应该也从2b及chyx那帖子那里看到动态加载的用法了。
其实就是在ccb后方加上更多的ccb而已。方法有两个,各有好处:
- clone,只需要一个cb。然而你需要绝对坐标。
- 结构方块: 不需要绝对坐标。然而你需要两个cb:(坐标、结构名称可以改变,总之就是在链后方先放置structure后放置红石块)
(我这个链的朝向是+x)
/setblock ~2 ~ ~ minecraft:structure_block 1 replace {posX:0,posY:0,posZ:0,name:test,mode:LOAD}
/setblock ~2 ~ ~ redstone_block
温馨提示: 动态加载建议复制时多复制个空气方块。这样就能与后面可能未能完全覆盖的ccb分开,避免执行了一些你不想执行的东西。

最后我们也能玩停止后面的命令执行...在原地setblock air就好

[groupid=546]Command Block Logic[/groupid]
作者: langyo_v3    时间: 2017-4-22 10:03
抢楼

我只想问一句,如果把gamerule的CCB最大执行量弄得很大/无限大,能否用它带动一些我们之前提出的不可能的无延迟机械?比如无延迟读写盔甲架变量与模拟无延迟红石电路?
作者: pca006132    时间: 2017-4-22 10:07
langyo_v3 发表于 2017-4-22 10:03
抢楼

我只想问一句,如果把gamerule的CCB最大执行量弄得很大/无限大,能否用它带动一些我们之前提出的不可能 ...

其实基本上65536也很够了。
很大的话分别只是在于gt而已。实际需要的运算时间还是很长的。
比如改到int32的上限...我觉得你真的需要那么大的限制的话,你可能要跑几个小时才跑完1gt。

所以那无延迟实际上会导致cpu不停运转,而且其他东西全停下来。实际上也算是延迟,只是你不能以mc内的时间测量而已。
作者: langyo_v3    时间: 2017-4-22 10:13
pca006132 发表于 2017-4-22 10:07
其实基本上65536也很够了。
很大的话分别只是在于gt而已。实际需要的运算时间还是很长的。
比如改到int32 ...

你能否测试一下,当CCB进入分支结构时,分支的执行顺序是怎样的?是否有额外条件能够调整顺序?(比如在分支第一个时把第二个即将要执行的分支用clone刷新,会不会直接跳票到第三个?)
以及,分支过后,是先把这个分支的后续命令执行完,还是继续下面的分支再分别执行支路?

期待你的研究
作者: pca006132    时间: 2017-4-22 10:16
langyo_v3 发表于 2017-4-22 10:13
你能否测试一下,当CCB进入分支结构时,分支的执行顺序是怎样的?是否有额外条件能够调整顺序?(比如在分支第 ...

我不是很明白你说的分支...
你是说1个信号到分岔路的时候还是啥?
信号一次只能传给一个ccb
作者: langyo_v3    时间: 2017-4-22 10:22
pca006132 发表于 2017-4-22 10:16
我不是很明白你说的分支...
你是说1个信号到分岔路的时候还是啥?
信号一次只能传给一个ccb ...
证明1: CCB会先决定待会让哪个方位的CCB执行命令,然后自己才执行命令。
先用CB搭建一个分支结构
设它们的号码为:
1
2 4
3
2的命令为把自己的朝向改为朝向4
3的命令为say 3
4的命令为say 4
然后激活ICB。
如果CCB是先执行命令,后决定待会让哪个方位的,执行命令的应该是4,聊天栏的输出应该是4。然而实验结果是3.
因此我们可以得知,CCB是先决定待会传信息给哪个方位的ccb的。
难道这不是么?
作者: chyx    时间: 2017-4-22 10:27
langyo_v3 发表于 2017-4-22 10:22
难道这不是么?

还是只执行了一个链啊
作者: ruhuasiyu    时间: 2017-4-22 10:27
我有一个问题,这种处理ccb的方式相比于原来的NTE方式,是不是可以大幅度减少卡顿?
作者: langyo_v3    时间: 2017-4-22 10:30
chyx 发表于 2017-4-22 10:27
还是只执行了一个链啊

那如何正确实现分支?
作者: pca006132    时间: 2017-4-22 10:33
ruhuasiyu 发表于 2017-4-22 10:27
我有一个问题,这种处理ccb的方式相比于原来的NTE方式,是不是可以大幅度减少卡顿? ...

其实我并不认为这和卡顿有太大关系...分别只是一个先把需要执行的放进个list里等待执行,一个是执行的时候决定下一个执行啥。这可能需要大量压测才知道
作者: ruhuasiyu    时间: 2017-4-22 10:35
pca006132 发表于 2017-4-22 10:33
其实我并不认为这和卡顿有太大关系...分别只是一个先把需要执行的放进个list里等待执行,一个是执行的时 ...

但是NTE不是会将整个链都记录下来吗?如果ccb链很长,这个列表就会很长吧?

不过好像每gt执行的cb数还是一样,好像是没太大差别




欢迎光临 Minecraft(我的世界)中文论坛 (https://www.mcbbs.net/) Powered by Discuz! X3.5