05 Block Events
This article covers how Block Events (BE) work under the hood.
Basics
- What Block Events are and why they exist
- Block Event structure and related components
- A hands-on understanding of Block Event Delay (BED)
Advanced
- Block Event queuing and the breadth-first search mechanism
1 What are Block Events?
In Minecraft, to minimize network traffic between server and client, the game avoids syncing all the detailed data from every complex block every tick.
Instead, the server tells the client "a specific event happened here" and lets the client simulate those events locally.
Block Events were designed for this efficient "notify and simulate" pattern.
1.1 Block Event Structure
When a Block Event is created, it contains exactly four pieces of information:
- Position
pos: where the event occurs - Block type
block: which type of block is executing this event - Type
type: which specific event action (for pistons, represents extend or retract) - Data
data: necessary parameters attached when executing the event (for pistons, represents the direction of push)
2 Block Event Sources
Some redstone components produce Block Events for various purposes, including but not limited to:
...
3 Block Event Delay (BED)
When multiple blocks are activated at the same time and generate Block Events, do they execute simultaneously?
By Minecraft's design, nothing in the game is truly "simultaneous." Even within the same game tick, events must execute in a fixed order. This ordering effect is called Block Event Delay (BED).
Here's what Block Event Delay looks like in practice:
Flip the lever and you'll notice that moving the redstone block changes how many pistons extend nearby. When the redstone block sits closer to the pressure plate block, fewer pistons extend; when it moves farther away, more extend.
3.1 Depth and Queuing: A Mental Model
Think of Block Event execution like a ticket queue: first come, first served.
When a Block Event executes, it may trigger new events. These get appended to the end of the queue. To track which "generation" produced each event, we use depth: the initial event has depth 0, events it directly produces have depth 1, and so on, capturing the chain of cause and effect.
Below is an example of a 0t bottom retraction base in a tree farm, showing how Block Event depth works in practice:
0gt AT: Lever is pulled down
1gt BE depth 0: Sticky piston starts retracting
1gt BE depth 1: Sticky piston pulls back podzol, redstone dust changes direction
1gt BE depth 2: Bottom retraction piston receives an update, self-checks, sees it's activated, extends
1gt BE depth 3: Powered block is removed, updating the bottom retraction piston. It self-checks, sees it should retract, queues a retract Block Event, but notices it's still extending, triggering a 0t.
3gt TE: All blocks are in place.
4gt BE depth 0: Top and bottom regular pistons extend, dirt's sticky piston adds Block Event
4gt BE depth 1: Regular piston extends, updating the sticky piston. The pushback sticky piston extends, base activates piston self-check. Redstone block is removed.
4gt BE depth 2: Top and bottom regular pistons retract, sending updates. Dirt's sticky piston receives an update, self-checks, sees it shouldn't extend, queues a retract Block Event. Bottom sticky piston follows the same logic.
4gt BE depth 3: Redstone block sticky piston and podzol sticky piston trigger 0t, podzol snaps into place. Redstone block lands in position, sticky piston controlling the bottom retraction piston's powered block extends.
6gt TE: Redstone dust changes direction, powered block in place, base finishes resetting.
4 Block Event Queue and Breadth-First Search
Under the hood, Block Event "queuing" is essentially a breadth-first search mechanism.
In the game's main loop, Block Events sit in a first-in-first-out queue. When a source (like a central piston triggered by a lever) propagates updates to neighbors in NC update order, each neighboring piston pushes its Block Event to the end of the queue.
During execution, the game pulls an event from the head of the queue:
- Dequeue and execute the first node with depth
0 - If this update triggers new updates, the resulting Block Events (depth
1) get pushed to the tail of the queue in update order. - The game keeps executing depth
0nodes until they're all gone, then moves on to depth1events.
This is exactly equivalent to a breadth-first search.
Here's an example:
The long edge extends from +x toward -x.
Pulling the lever activates the central piston, which updates the three surrounding pistons in -x, +x, +z order, pushing them into the queue one by one. The game then executes the -x and +x pistons in sequence, followed by the next piston in the +x direction. That piston adds a Block Event to the queue, placing it after the +z piston. Next the +z piston executes, and finally the last +x piston runs.
We can abstract each piston as a node, treating depth-0 pistons as root nodes. Note that in practice, this graph may have multiple sources. We run multi-source BFS on this abstracted "piston graph," where child nodes join the queue in NC update order, determined by their direction relative to the parent. Children that have already been visited are not added again.





