方块更新(Block Update)是指方块发生一些变化时工作的一游戏机制。游戏受计算机的计算能力限制,不能随时处理所有方块,因此需要方块更新这样的机制。当一个方块因实体或计划刻等原因发生变化,它通知附近的方块它们应检查它们需不需要响应。
Java版[]
在Java版中,有两种主要的方块更新,即PP更新和NC更新。
PP更新[]
PP更新(Shape Update/Post-Placement Update[1])是游戏内最广泛的方块更新类型。它用于方块的放置、修改和移除等各种方块变化中,执行改变方块的形状与检查附着性等操作。
- 产生
PP更新必须由一次方块放置、修改或移除产生。当方块被放置、破坏,或方块状态产生变化时,系统会在这个方块修改之后依次向西、东、北、南、下、上的方块传播PP更新。
下列特殊的方块和行为产生的PP更新与正常情况下不同:
- 放置床时会以床两格方块为中心向周围10个方块传播PP更新。更新分为两次,第一次以床尾为中心传播,第二次以床头为中心传播,其更新顺序与正常PP更新相同。
- 潜影盒开始开合和结束开合(开合期间区块卸载的除外)时产生正常PP更新。
- 使用调试棒改变方块状态不产生PP更新。
- 下界传送门生成时其内部的下界传送门方块不产生PP更新。
除正常的PP更新外,还有一种特殊的、只有红石线会接收的PP更新,下文将称为间接PP更新。它基本上与PP更新产生的条件一致,在正常产生PP更新执行前和执行后各执行一次,在下文未说明的情况下,PP更新默认包含间接PP更新。
- 接收
当方块接收到PP更新时,方块会有如下行为:
- 附着性方块(各种铁轨除外)会检查是否可以正常附着在其他方块上,如果不能则尝试掉落为物品或对本身添加延迟为1游戏刻(0.05秒)的计划刻延迟破坏自身变为物品。
- 这种类型的检查只会检查更新传播而来的方向是否会影响方块的附着:如果方块正附着于北面的方块上,却收到了来自南面方块的PP更新,则不影响本方块的附着性,即使本方块不能附着在北面的方块上。
- 如果方块本身含水或方块本身为流体源,又或者方块为流体而PP更新源为流体源,接收到PP更新后会对自身添加流体计划刻。
- 含水栅栏先添加液体计划刻,后更新形状。
- 箱子、栅栏、绊线等可连接方块检查是否要连接到更新传播方向上的方块。
- 床、门等多方块组合的方块检查多方块结构是否完整,如果不完整则尝试掉落为物品。如果更新源不在多方块组合范围内,则不响应此PP更新。
- 珊瑚类方块检查周围是否有水,如果没有则添加延迟为60游戏刻(3秒)-99游戏刻(4.95秒)的计划刻。
- 气泡柱检查自身是否需要更新,如果需要更新则添加延迟为5游戏刻(0.25秒)的计划刻。
- 营火接收来自下方的PP更新检查是否成为信号火。
- 混凝土粉末尝试固化。
- 耕地和草径接收到来自上方的PP更新时检查是否会退化,如果会退化对自身添加1游戏刻(0.05秒)的计划刻用于延迟执行退化。
- 沙子、沙砾等受重力影响的方块检查自身是否可以被下方方块支撑,如果不能则对自身添加计划刻延迟变为下落的方块。
- 树叶对自身添加延迟为1游戏刻(0.05秒)的计划刻,执行时检查当前距离原木的距离,如果当前距离与方块状态中的距离不对应,则修改方块状态。
- 岩浆块和灵魂沙接收到来自上方的PP更新时,如果上方的方块为水,则对自身添加延迟为20游戏刻(1秒)的计划刻用于延迟生成气泡柱。
- 音符盒接收到来自上方或下方的PP更新时尝试改变乐器类型。
- 侦测器在非激活状态下接收到来自面对方向的PP更新时对自身添加延迟为2游戏刻(0.1秒)的计划刻用于产生红石信号。
- 红石中继器接收到来自侧方和上下方方块的PP更新时检查自身锁定状态。
- 脚手架接收到PP更新时对自身添加延迟为1游戏刻(0.05秒)的计划刻。
- 草方块和菌丝接收到来自上方的PP更新时检查是否应该变为积雪状态。
- 在间接PP更新时,如果红石线方块水平指向的方块不是红石线,则在这个方块上方和下方的红石线方块额外传播PP更新,用于更新斜上下方的红石线方块状态。
- 活塞头接收到来自其后方的PP更新时检查是否能找到自身对应的活塞,如果找不到对应的活塞会立刻被破坏。
NC更新[]
NC更新(Neighbor Changed Update)是最广为人知的方块更新,主要用于红石元件。
- 产生
与PP更新类似,NC更新也必须由一次方块放置、修改或移除产生,方块实体的变化也可能产生NC更新。
为了简化说明,在这里我们引入更新核和二阶更新核的概念:
- 如果一个方块为更新核,则它会依次向本方块的西、东、下、上、北、南方向上的方块传播NC更新。
- 如果一个方块为二阶更新核,则它本质上等价于本方块和周围6个方块都为更新核。在传播更新时,先执行本方块更新核的NC更新传播,再依次执行本方块下、上、北、南、西、东方向上的更新核进行NC更新传播。有些二阶更新核本方块不会产生NC更新,也有一些二阶更新核调用子更新核的顺序随机,在下文中这些特殊情况将特殊说明。
绝大多数的方块放置、破坏、更新方块状态和方块实体更新都会以自身方块为更新核传播NC更新,即按照西、东、下、上、北、南的顺序依次传播NC更新。
下列方块及行为不会产生NC更新:
- 使用调试棒改变方块状态。
- 铁砧的开裂。
- 大型垂滴叶叶片倾斜。
- 酿造台药水数量的变化。
- 气泡柱的生成和消失。
- 植物类方块生长、催熟和转变。
- 珊瑚类方块死亡。
- 发射器、投掷器和漏斗的激活状态变化。(包括放置时)
- 海绵转变为湿海绵。(包括放置时)
- 门、活板门和栅栏门打开、关闭、激活与取消激活。
- 龙蛋传送到位。
- 滴水石锥生长。
- 绵羊吃草方块和兔子吃胡萝卜作物。
- 末地传送门框架安放末影之眼和产生末地传送门。
- 耕地的湿润状态变化。
- 火和灵魂火方块状态
age
的变化。 - 霜冰融化状态的变化。
- 光源方块光照等级的变化。
- 蘑菇的传播。
- 红石灯的亮灭。
- 幽匿尖啸体的尖啸状态变化。
- 嗅探兽蛋开裂,海龟蛋数量变化。
- 结构方块模式变化。
- 草方块和菌丝转变为积雪状态。
- 产生下界传送门时下界传送门方块不产生NC更新。
- 大多数可连接方块与其他方块进行连接时不产生NC更新。
一些方块产生NC更新的行为与正常情况不同:
- 压力板、按钮、拉杆、避雷针和绊线钩在切换激活状态时或在激活时被破坏会以自身和附着的方块为更新核产生NC更新。
- 讲台、陷阱箱、幽匿感测体在激活状态发生变化或在被激活状态下被破坏时会以自身和下方方块为更新核产生NC更新。
- 红石火把在放置、破坏和状态变化时会以自身方块为二阶更新核发出NC更新。
- 侦测器在激活状态发生变化时,会向输出方向方块本身发出NC更新,并以输出方向方块为更新核产生NC更新(不包括更新源侦测器本身);如果在激活时被破坏,则以自身为更新核产生NC更新。
- 潜影盒在开合和结束开合(开合期间区块卸载的除外)时以自身方块为更新核产生NC更新。
- 铁轨类方块根据状态不同产生不同范围的NC更新[2]:
- 红石中继器和红石比较器在不同状态下也有不同的更新行为:
- 如果接收到NC更新,且中继器和比较器下方没有支撑,则以本方块为二阶更新核产生NC更新。
- 放置或破坏中继器和比较器时会以本方块和输出方向方块为更新核产生NC更新(不包括更新源中继器和比较器本身)。
- 比较器输出信号发生变化时会以输出方向方块为更新核产生NC更新(不包括更新源中继器和比较器本身)。
- 红石线在不同的状态下具有更复杂的更新行为,放置、破坏和切换点/十字形状的行为省略了其中正常NC更新的流程:
- 在放置时,如果当前红石信号和实际红石信号不对应,则先以自身方块为二阶更新核(子更新核顺序随机)产生NC更新。然后,无论红石线是什么状态,都以上下方块为更新核产生NC更新。接着,对水平方向(顺序为北、东、南、西)毗邻的红石线,以它们为二阶更新核产生NC更新。最后,对水平方向(顺序为北、东、南、西)的方块再进行一次遍历,如果方块是红石导体,尝试以红石导体上面的红石线为二阶更新核产生NC更新;如果方块不是红石导体,则尝试以此方块下方的红石线为二阶更新核产生NC更新。
- 在破坏时,先以自身方块为二阶更新核(自身方块不产生NC更新)产生NC更新。然后,计算如果此位置红石线存在时的红石信号,如果与破坏前状态不对应,则再以自身方块为二阶更新核(子更新核顺序随机)产生NC更新。接着,对水平方向(顺序为北、东、南、西)毗邻的红石线,以它们为二阶更新核产生NC更新。最后,对水平方向(顺序为北、东、南、西)的方块再进行一次遍历,如果方块是红石导体,尝试以红石导体上面的红石线为二阶更新核产生NC更新;如果方块不是红石导体,则尝试以此方块下方的红石线为二阶更新核产生NC更新。
- 在接收到NC更新且红石信号发生变化时,以自身方块为二阶更新核(子更新核顺序随机)产生NC更新。
- 当红石线进行点状与十字状形状变化时,以水平方向(顺序为北、东、南、西)的红石导体为更新核产生NC更新(不包括更新源红石线本身)。
- 如果放置后的方块本身可以发出模拟信号(包括炼药锅、蜂巢、蜂箱、蛋糕、命令方块、堆肥桶、末地传送门框架、讲台、重生锚、幽匿感测体和所有带有容器的方块),或带有容器的方块被破坏或容量产生变化,则在NC更新流程之外额外进行一次特殊的只在红石比较器上产生的NC更新。这类更新被称为比较器更新,在原理上与NC更新无异,在下文说明时接收NC更新包含比较器更新,在更新优先级中两者分开说明。
- 在上述方块结束NC更新后,对水平方向(顺序为北、东、南、西)的红石比较器和在红石导体之后的红石比较器传播NC更新。
*
|
||||
*
|
|||||
*
|
||||
*
|
||||
- 接收
方块在接收NC更新时,会有下列的行为:
- 铁轨类方块更新激活状态和检查附着。
- 流体方块在可传播情况下对自身添加流体计划刻进行流体传播。
- 命令方块更新状态,如果被激活则对自身添加延迟为1游戏刻(0.05秒)的计划刻用于执行命令。
- 结构方块执行对应的操作。
- 钟更新激活状态,如果被激活就发出声音。
- 音符盒更新激活状态,如果被激活就发出声音。
- 大型垂滴叶在有红石信号时重置倾斜程度。
- 门、活板门、栅栏门更新开闭状态。如果活板门含水接收这次更新后开闭状态被修改,则额外添加流体计划刻用于更新流体。
- 红石中继器和红石比较器检查附着并尝试更新输出信号。
- 投掷器和发射器切换激活状态,如果被激活则对自身添加延迟为4游戏刻(0.2秒)的计划刻用于进行投掷或发射行为。
- 红石灯不亮且存在红石信号时对自身添加延迟为4游戏刻(0.2秒)的计划刻用于点亮自身,如果红石灯亮且周围不存在红石信号则立刻熄灭。
- 红石火把在本游戏刻没有此方块的计划刻且输出状态与正常输出状态不一致,则对自身添加延迟为2游戏刻(0.1秒)的计划刻用于切换状态。
- 红石线更新红石信号并检查附着。
- 霜冰尝试融化。
- 漏斗尝试更新启用状态。
- 海绵尝试吸水。
- TNT在有红石信号时激活。
更新优先级[]
PP更新和NC更新的执行有先后顺序。在通常情况下,一个方块的放置、破坏或修改会按照下面的流程进行:
- 更改子区块内的方块状态。
- 更新高度图。
- 调用被替代方块状态的破坏行为。
- 调用替代方块状态的放置行为。
- 更新方块实体信息。
- 产生NC更新。
- 产生比较器更新。
- 产生PP更新。
绝大多数非正常NC更新行为的方块,其NC更新和PP更新的顺序与通常情况不同:
- 压力板、侦测器、红石火把在切换激活状态时先产生PP更新再产生NC更新;在破坏时在破坏行为中先执行非正常NC更新,接下来的流程与正常一致。
- 按钮、拉杆、讲台、避雷针、幽匿感测体、绊线钩在切换激活状态时在正常执行上方流程后再产生非正常的NC更新,即NC更新分为两次产生;在破坏时在破坏行为中先执行非正常NC更新,接下来的流程与正常一致。
- 铁轨类方块在切换激活状态时先执行原状态破坏时产生的非正常NC更新,随后正常执行上方流程,再产生非正常的NC更新。
- 红石线切换点/十字形状时在正常执行上方流程后再产生非正常的NC更新,即NC更新分为两次产生;在其他状况下,红石线先进行PP更新再进行NC更新。
- 红石中继器和红石比较器接收到NC更新,且中继器和比较器下方没有支撑时被破坏则在正常执行上方流程后再产生非正常的NC更新,即NC更新分为两次产生。
有些方块在调用破坏行为和放置行为时,内部又重新设置了自身方块的方块状态,这种更新叫做自更新。自更新内部调用的设置方块状态其更新流程与正常一致,而外部的更新流程会在产生NC更新前结束,即自更新的更新行为完全取决于内部设置方块状态引发的更新行为。如漏斗在被玩家放置时,如果周围有红石信号,则漏斗在调用方块状态放置行为时,自身修改激活状态,而此修改不会产生NC更新,外层的NC更新和PP更新也因为自更新影响而被忽略,所以最后的更新情况为只产生了PP更新,而没有产生NC更新。
更新传播[]
方块更新的传播基本遵循深度优先搜索算法:
- 当方块产生更新时,将方块产生的更新或更新核压入栈,并将更新数量加1。
- 循环执行以下步骤,直至栈为空或待更新列表为空:
- 如果待更新列表不为空,则按照添加时间从最晚到最早依次压入栈,之后清空待更新列表。
- 循环执行以下步骤,直到待更新列表不为空:
- 执行栈顶的更新或更新核。更新核只会按照方向顺序执行一个方向上的更新,所以更新核需要5或6次循环才能执行完毕。
- 在执行过程中可能产生新的更新或更新核,这些更新或更新核将添加到待更新列表中,并将更新数量增加。
- 当更新数量超过server.properties中的
max-chained-neighbor-updates
时就无法再添加更新或更新核,接下来添加的更新或更新核将被忽略,而已添加的更新或更新核仍然会被执行。
- 如果栈顶的更新或更新核已经执行完毕,将栈顶弹出,退出内层循环。
- 执行栈顶的更新或更新核。更新核只会按照方向顺序执行一个方向上的更新,所以更新核需要5或6次循环才能执行完毕。
- 更新计算完毕,重置存储更新的栈和待更新列表,重置更新数量为0。
如果最初产生更新的方块产生的是NC更新核,并且在更新过程中没有出现异常,即使更新数量超过max-chained-neighbor-updates
,更新核内包含的6个方块仍然会被更新。
基岩版[]
你可以帮助我们加入信息。
历史[]
此段落仍需完善。你可以帮助我们扩充关于该主题的更多信息。
Java版 | |||||
---|---|---|---|---|---|
1.5 | ? | 部分变化不再发出NC更新。 | |||
加入了比较器更新。 | |||||
1.11 | 16w41a | 侦测器不再更新指向的毗邻。 | |||
16w42a | 红石中继器和红石比较器不再更新指向的毗邻。 | ||||
16w43a | 侦测器、红石中继器和红石比较器仅在指向红石导体时更新指向的毗邻。 | ||||
16w44a | 撤销了前三个快照的更改。 | ||||
侦测器不再接受NC更新,改为检测方块和基础方块状态的更改。 | |||||
1.13 | 17w47a | 侦测器以外的方块开始响应方块状态的变化,即PP更新。 | |||
现在所有方块状态均在服务端存储,因此变化时均发出PP更新。 | |||||
音符盒的状态由方块实体改为方块状态,因此它们不再发送比较器更新,改为发送PP更新和NC更新。 | |||||
现在红石中继器改变延时、红石比较器从比较模式切换到减法模式不仅发出PP更新,也发出NC更新。 | |||||
加入了自更新。 | |||||
17w49a | 面对能被拉动(拉黏液块或蜂蜜块时不考虑黏动的方块,实际上可能拉不动)的方块的黏性活塞头不再在开始缩回时发出任何更新。 | ||||
18w30b | 常见的黏液块BUD失效了。 | ||||
18w31a | 撤销了上个快照的改动。 | ||||
侦测器开始自更新。 | |||||
pre7 | 液体开始接受PP更新。 | ||||
1.16 | 20w22a | 此前活塞一次移动的方块发出更新的位置和来源的配对顺序是反的。[3] | |||
1.17 | 20w45a | 箱子开合和比较模式的红石比较器后侧输入变化(不影响输出)不再发出NC更新。 | |||
1.19 | 22w11a | 现在NC更新引起的NC更新在其他更新之后处理。[4] | |||
22w12a | 上个快照对NC的更改被应用于PP更新,两种方块更新恢复22w11a以前的相对顺序,但现在含水活板门开闭时发出更新在计划流动之后。[5] | ||||
流动水不再接收四周水源或含水方块上下方红石线的间接PP更新。 | |||||
22w13a | 现在红石线对斜上斜下的PP更新仅发给其他红石线。此前这种更新发给侦测器以外所有接受来自四周的PP更新的方块。 | ||||
1.20.2 | 23w31a | 现在潜影盒在开合和结束开合时发出NC更新。 | |||
23w35a | 现在红石线、红石中继器和红石比较器收到来自下侧的PP更新时检查附着。 |
参考[]
版本 | |||||||
---|---|---|---|---|---|---|---|
开发周期 |
| ||||||
技术 |
| ||||||
多人游戏 | |||||||
游戏订制 |
版本 |
| ||||||
---|---|---|---|---|---|---|---|
开发 |
| ||||||
技术性 | |||||||
多人游戏 | |||||||
特色功能 |
语言