# Block Architecture & State System Blocks form the static and dynamic foundation of Minecraft worlds. In Pumpkin, block handling is cleanly bifurcated into two distinct layers: 1. **Static Data Layer ([`pumpkin-data`](https://github.com/Pumpkin-MC/Pumpkin/tree/master/crates/pumpkin-data))**: Compile-time generated metadata including numeric block IDs, block state IDs, hardness, blast resistance, light emission, opacity, collision shapes, and block state properties generated by [`pumpkin-codegen`](/developer/codegen). 2. **Dynamic Behavior Layer ([`pumpkin::block`](https://github.com/Pumpkin-MC/Pumpkin/tree/master/crates/pumpkin/src/block))**: Server-side behavioral hooks—such as opening containers, toggling redstone signals, growing crops, breaking triggers, and collision effects—handled via the `BlockBehaviour` trait. --- ## Static Blocks vs. Interactive Behaviors Because Minecraft contains thousands of block state combinations, Pumpkin avoids allocating runtime behavior structs for simple, non-interactive blocks: | Category | Description | Examples | Runtime Behavior Required? | | :--- | :--- | :--- | :--- | | **Static Blocks** | Rigid solid voxels without interactive logic or custom physics | `stone`, `dirt`, `cobblestone`, `bedrock`, `obsidian` | No — Placement, breaking times, and tool requirements are handled entirely by `pumpkin-data`. | | **Interactive Blocks** | Blocks triggered by right-clicks or tool actions | `door`, `trapdoor`, `lever`, `button`, `crafting_table` | Yes — Implements `BlockBehaviour::normal_use` or `use_with_item`. | | **Collision Blocks** | Blocks that modify entity movement or apply forces | `honey_block`, `slime_block`, `soul_sand`, `powder_snow` | Yes — Implements `on_entity_collision` or `on_landed_upon`. | | **Redstone Components** | Power sources, conductors, and logic gates | `redstone_wire`, `repeater`, `comparator`, `observer` | Yes — Implements `emits_redstone_power` and `on_neighbor_update`. | | **Block Entities** | Blocks with persistent, serialized custom states | `chest`, `furnace`, `sign`, `decorated_pot`, `spawner` | Yes — Implements `create_block_entity` and links a `BlockEntity`. | --- ## Block IDs, States, and Properties Minecraft distinguishes between a **Block** type and a specific **Block State**: ### 1. `BlockId` and `BlockStateId` - **`BlockId`**: An identifier representing a base block type (e.g., `minecraft:oak_door`). - **`BlockStateId`**: A 16-bit integer representing a unique combination of block properties (e.g., `minecraft:oak_door[facing=north,half=lower,hinge=left,open=false,powered=false]`). In Pumpkin, block data is looked up from precomputed lookup tables in `pumpkin-data`: ```rust use pumpkin_data::Block; use pumpkin_data::BlockStateId; // Access static properties directly from generated data let door_block = Block::OAK_DOOR; let default_state_id: BlockStateId = door_block.default_state_id; let hardness = door_block.hardness; let blast_resistance = door_block.blast_resistance; let is_air = door_block.is_air; ``` ### 2. Generated State Property Helpers Rather than parsing raw strings or bitmasks manually, [`pumpkin-codegen`](/developer/codegen) generates strongly typed property helpers in `pumpkin_data::block_properties`: ```rust use pumpkin_data::block_properties::{DoorLikeProperties, DoubleBlockHalf, Facing}; // Read typed properties from a numeric BlockStateId let is_open = DoorLikeProperties::open(state_id); let half = DoorLikeProperties::half(state_id); let facing = DoorLikeProperties::facing(state_id); // Generate a new BlockStateId with mutated properties let toggled_state_id = DoorLikeProperties::with_open(state_id, !is_open); ``` --- ## Physics, Bounding Boxes & Raycasting Pumpkin calculates collision and raycasting bounding boxes directly using pre-baked shapes in `pumpkin-data`: - **Solid Collisions**: During physics ticks, an entity's axis-aligned bounding box (AABB) is tested against surrounding block collision voxels. - **Raycasting**: When a player targets a block to place or break, client raycasts are validated against the server-side block outline shapes. - **Custom Movement Hooks**: Blocks like slime blocks or honey blocks override vertical rebound or horizontal velocity: - `bounce_entity_after_fall`: Dampens fall damage and multiplies rebound velocity. - `stop_vertical_movement_after_fall`: Zeros fall velocity upon contact. --- ## Block Entities (Tile Entities) When a block must store arbitrary dynamic data that cannot fit into standard block state bits (such as container inventories, custom sign text, brewing timers, or mob spawner delays), it uses a **Block Entity**: | Component | Responsibility | Implementation File | | :--- | :--- | :--- | | `BlockEntity` Trait | Defines NBT serialization (`to_nbt`, `from_nbt`) and tick execution | [`crates/pumpkin/src/block/entities/`](https://github.com/Pumpkin-MC/Pumpkin/tree/master/crates/pumpkin/src/block/entities) | | `create_block_entity` | Hook in `BlockBehaviour` called when placing the block | Attached to relevant block behaviors | | Chunk Entity Storage | Manages active block entities and coordinates within chunk sections | [`crates/pumpkin-world`](https://github.com/Pumpkin-MC/Pumpkin/tree/master/crates/pumpkin-world) | --- ## The Block Registry & Dispatch System Block interaction events are routed through the central `BlockRegistry` in [`crates/pumpkin/src/block/registry.rs`](https://github.com/Pumpkin-MC/Pumpkin/blob/master/crates/pumpkin/src/block/registry.rs): 1. **Registration**: At server initialization, all behavior structs are registered into the `BlockManager`. 2. **Mapping**: The manager maps numeric `BlockId` keys to thread-safe behavior instances (`Arc`). 3. **Dispatch**: When the network layer receives block action packets (such as `CUseItemOn` or block dig packets), the server looks up the behavior in $O(1)$ time and invokes the relevant hook. --- ## Next Steps To implement a new interactive block behavior, continue to the practical guide: - **[Adding a Block](/developer/blocks/adding-blocks)**: Complete walk-through of declaring attributes, implementing interaction hooks, creating block entities, and registering behaviors.