05 方块事件
本篇讨论的是方块事件 (Block Event, BE) 的实现原理。
基础部分
- 方块事件的概念与存在意义
- 方块事件的信息结构与相关元件
- 方块事件延迟 (BED) 的通俗认识
进阶部分
- 方块事件队列与广度优先搜索机制
1 什么是方块事件?
在 Minecraft 游戏交互中,为了减少服务器与客户端之间的网络同步压力,游戏会避免把所有复杂方块的巨量数据都在每一刻同步给客户端。
相反,服务端会选择告诉客户端:“这里发生了一个特定的事件”,然后让客户端的方块自己把服务端发生的事情在本地模拟一遍。
方块事件 (Block Event) 就是为了这种高效的 “通知与模拟” 而生的。
1.1 方块事件的信息结构
当一个方块事件被创建时,它包含且仅包含以下四个核心信息:
- 位置
pos:事件在哪里发生 - 方块种类
block:是哪一种方块在执行这个事件 - 类型
type:是哪种具体的事件动作(对活塞而言,代表伸出或收回) - 数据
data:执行该事件时附带的必要参数(对活塞而言,代表推动的朝向)
2 产生方块事件的元件
一部分红石元件会产生方块事件,用途各不相同,包括但不限于以下方块:
...
3 方块事件延迟 (BED)
当多个方块在同一时间被激活并产生方块事件时,它们会同时执行吗?
Minecraft 的世界观告诉我们:游戏中不存在绝对的 “同时”。即使是在同一游戏刻内,事件的执行也必须有一个先后顺序。这种由执行顺序的时间差造成的现象,就称为方块事件延迟 (Block Event Delay, 简称 BED)
下面展示一下方块事件延迟是怎么在游戏中表现的:
开关拉杆,我们发现,当改变红石块的位置的时候,旁边活塞推出的数量发生了变化,当红石块靠近压线方块的时候,数量减少了,而当红石块远离压线方块的时候,数量增多了。
3.1 深度与队列的通俗理解
你可以把方块事件的执行想象成人们正在排队买票:先来的先执行,后来的后执行。
当一个方块事件执行时,它可能会触发后续的新事件。这些新事件会被追加到队列末尾。为了追踪这些事件是由 “哪一代” 产生的,我们引入深度概念:初始事件深度为 0,它直接产生的事件深度为 1,以此类推,用以刻画事件间的衍生因果链
下面是一个树场 0t 下吸底座的例子,用于展示方块事件深度是如何在实际设计中应用的:
0gt AT:拉杆被拉下
1gt BE 深度 0:粘性活塞开始收回
1gt BE 深度 1:粘性活塞将灰化土拉回,转向粉转向
1gt BE 深度 2:下吸活塞被更新,自检,发现自己被激活,伸出
1gt BE 深度 3:充能方块被移除,更新下吸活塞,自检,发现自己应该收回,添加收回的方块事件,发现自己正在伸出,0t 发生。
3gt TE:全部方块均到位。
4gt BE 深度 0:上下两个普通活塞伸出,泥土的粘性活塞添加方块事件
4gt BE 深度 1:普通活塞伸出,更新粘性活塞,回推粘性活塞伸出,底座激活活塞自检。红石块被移除。
4gt BE 深度 2:上下两个普通活塞收回,发出更新,更新泥土的粘性活塞,粘性活塞自检,发现自己不应该推出,添加收回的方块事件,下方粘性活塞同理
4gt BE 深度 3:红石块粘性活塞和灰化土粘性活塞的 0t 发生,灰化土瞬间到位。红石块到位,控制下吸活塞充能方块的粘性活塞伸出。
6gt TE:红石粉被转向,充能方块到位,底座完成重置。





