pub trait BlockBehavior: Send + Sync {
Show 66 methods
// Required method
fn get_state_for_placement(
&self,
context: &BlockPlaceContext<'_>,
) -> Option<BlockStateId>;
// Provided methods
fn type_name(&self) -> &'static str { ... }
fn pickup_block(
&self,
world: &Arc<World>,
pos: BlockPos,
state: BlockStateId,
player: Option<&Player>,
) -> Option<PickupResult> { ... }
fn update_shape(
&self,
state: BlockStateId,
_world: &dyn ScheduledTickAccess,
_pos: BlockPos,
_direction: Direction,
_neighbor_pos: BlockPos,
_neighbor_state: BlockStateId,
) -> BlockStateId { ... }
fn update_indirect_neighbour_shapes(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
flags: UpdateFlags,
update_limit: i32,
) { ... }
fn can_survive(
&self,
_state: BlockStateId,
_world: &dyn LevelReader,
_pos: BlockPos,
) -> bool { ... }
fn can_be_replaced(
&self,
state: BlockStateId,
context: &BlockPlaceContext<'_>,
) -> bool { ... }
fn on_place(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
old_state: BlockStateId,
moved_by_piston: bool,
) { ... }
fn set_placed_by(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
source: &PlacementSource<'_>,
) { ... }
fn attack(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
player: &Player,
) { ... }
fn player_destroy(
&self,
world: &Arc<World>,
player: &Player,
pos: BlockPos,
state: BlockStateId,
block_entity: Option<&SharedBlockEntity>,
tool: &ItemStack,
) { ... }
fn player_will_destroy(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
player: &Player,
) -> BlockStateId { ... }
fn destroy(&self, state: BlockStateId, world: &Arc<World>, pos: BlockPos) { ... }
fn get_drops(
&self,
state: BlockStateId,
context: &BlockLootContext<'_>,
) -> Option<Vec<ItemStack>> { ... }
fn spawn_after_break(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
tool: &ItemStack,
drop_experience: bool,
) { ... }
fn affect_neighbors_after_removal(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
moved_by_piston: bool,
) { ... }
fn use_item_on(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
player: &Player,
hand: InteractionHand,
hit_result: &BlockHitResult,
inv: &mut InventoryAccess,
) -> InteractionResult { ... }
fn use_without_item(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
player: &Player,
hit_result: &BlockHitResult,
inv: &mut InventoryAccess,
) -> InteractionResult { ... }
fn handle_neighbor_changed(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
source_block: BlockRef,
moved_by_piston: bool,
) { ... }
fn is_signal_source(
&self,
_state: BlockStateId,
_context: SignalQueryContext,
) -> bool { ... }
fn is_diode(&self) -> bool { ... }
fn is_trapdoor(&self) -> bool { ... }
fn is_rail(&self) -> bool { ... }
fn is_piston_base(&self) -> bool { ... }
fn get_own_signal(
&self,
_state: BlockStateId,
_world: &dyn LevelReader,
_pos: BlockPos,
_context: SignalQueryContext,
) -> i32 { ... }
fn get_signal(
&self,
state: BlockStateId,
world: &dyn LevelReader,
pos: BlockPos,
_direction: Direction,
context: SignalQueryContext,
) -> i32 { ... }
fn get_direct_signal(
&self,
_state: BlockStateId,
_world: &dyn LevelReader,
_pos: BlockPos,
_direction: Direction,
_context: SignalQueryContext,
) -> i32 { ... }
fn is_redstone_conductor(
&self,
state: BlockStateId,
_world: &dyn LevelReader,
_pos: BlockPos,
) -> bool { ... }
fn trigger_event(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
param_a: i32,
param_b: i32,
) -> bool { ... }
fn get_clone_item_stack(
&self,
block: BlockRef,
state: BlockStateId,
include_data: bool,
) -> Option<ItemStack> { ... }
fn is_pathfindable(
&self,
state: BlockStateId,
computation_type: PathComputationType,
) -> bool { ... }
fn is_wooden_door(&self, state: BlockStateId) -> bool { ... }
fn set_door_open(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
source_entity: Option<&dyn Entity>,
open: bool,
) -> bool { ... }
fn default_get_collision_shape(
&self,
state: BlockStateId,
world: &dyn LevelReader,
pos: BlockPos,
context: BlockCollisionContext,
) -> VoxelShape { ... }
fn get_collision_shape(
&self,
state: BlockStateId,
world: &dyn LevelReader,
pos: BlockPos,
context: BlockCollisionContext,
) -> VoxelShape { ... }
fn get_collision_shape_offset(
&self,
state: BlockStateId,
world: &dyn LevelReader,
pos: BlockPos,
context: BlockCollisionContext,
) -> DVec3 { ... }
fn get_collision_boxes(
&self,
state: BlockStateId,
world: &dyn LevelReader,
pos: BlockPos,
context: BlockCollisionContext,
) -> BlockCollisionBoxes { ... }
fn get_block_support_boxes(
&self,
state: BlockStateId,
world: &dyn LevelReader,
pos: BlockPos,
) -> BlockCollisionBoxes { ... }
fn is_face_sturdy(
&self,
state: BlockStateId,
world: &dyn LevelReader,
pos: BlockPos,
direction: Direction,
support_type: SupportType,
) -> bool { ... }
fn default_get_entity_inside_collision_shape(
&self,
state: BlockStateId,
world: &dyn LevelReader,
pos: BlockPos,
entity: &dyn Entity,
) -> VoxelShape { ... }
fn get_entity_inside_collision_shape(
&self,
state: BlockStateId,
world: &dyn LevelReader,
pos: BlockPos,
entity: &dyn Entity,
) -> VoxelShape { ... }
fn random_tick(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
) { ... }
fn tick(&self, state: BlockStateId, world: &Arc<World>, pos: BlockPos) { ... }
fn on_projectile_hit(
&self,
_state: BlockStateId,
_world: &Arc<World>,
_hit: &ClipHitResult,
_projectile: &dyn Projectile,
) { ... }
fn default_entity_inside(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
entity: &dyn Entity,
effect_collector: &mut InsideBlockEffectCollector,
is_precise: bool,
) { ... }
fn entity_inside(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
entity: &dyn Entity,
effect_collector: &mut InsideBlockEffectCollector,
is_precise: bool,
) { ... }
fn default_fall_on(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
context: EntityFallOnContext<'_>,
) -> Option<EntityFallDamage> { ... }
fn fall_on(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
context: EntityFallOnContext<'_>,
) -> Option<EntityFallDamage> { ... }
fn after_fall_on_damage(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
entity: &dyn Entity,
fall_damage: &EntityFallDamage,
damage_applied: bool,
) { ... }
fn default_update_entity_movement_after_fall_on(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
context: EntityLandingContext,
) -> DVec3 { ... }
fn update_entity_movement_after_fall_on(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
context: EntityLandingContext,
) -> DVec3 { ... }
fn default_step_on(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
entity: &dyn Entity,
) { ... }
fn step_on(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
entity: &dyn Entity,
) { ... }
fn new_block_entity(
&self,
level: Weak<World>,
pos: BlockPos,
state: BlockStateId,
) -> BlockEntityCreation { ... }
fn get_block_entity_ticker(
&self,
world: &Arc<World>,
state: BlockStateId,
block_entity_type: BlockEntityTypeRef,
) -> Option<BlockEntityTicker> { ... }
fn get_game_event_listener(
&self,
world: &Arc<World>,
block_entity: &dyn BlockEntity,
) -> Option<SharedGameEventListener> { ... }
fn should_keep_block_entity(
&self,
old_state: BlockStateId,
new_state: BlockStateId,
) -> bool { ... }
fn has_analog_output_signal(&self, state: BlockStateId) -> bool { ... }
fn get_analog_output_signal(
&self,
state: BlockStateId,
world: &dyn LevelReader,
pos: BlockPos,
direction: Direction,
) -> i32 { ... }
fn is_liquid_container(&self, state: BlockStateId) -> bool { ... }
fn can_place_liquid(&self, state: BlockStateId, fluid: FluidRef) -> bool { ... }
fn can_place_liquid_with_player(
&self,
state: BlockStateId,
fluid: FluidRef,
_player: Option<&Player>,
) -> bool { ... }
fn can_be_replaced_by_fluid(
&self,
state: BlockStateId,
_fluid_block: BlockRef,
) -> bool { ... }
fn place_liquid(
&self,
level: &dyn LevelAccessor,
pos: BlockPos,
state: BlockStateId,
fluid_state: FluidState,
) -> bool { ... }
fn as_bonemealable(&self) -> Option<&dyn Bonemealable> { ... }
fn as_rail(&self) -> Option<&dyn RailBehavior> { ... }
}Expand description
Trait defining the behavior of a block.
This trait handles all dynamic/functional aspects of blocks:
- Placement logic
- Neighbor updates
- Player interactions
- State changes
Required Methods§
Sourcefn get_state_for_placement(
&self,
context: &BlockPlaceContext<'_>,
) -> Option<BlockStateId>
fn get_state_for_placement( &self, context: &BlockPlaceContext<'_>, ) -> Option<BlockStateId>
Returns the block state to use when placing this block.
Provided Methods§
Sourcefn type_name(&self) -> &'static str
fn type_name(&self) -> &'static str
Returns the Rust type name of the concrete behavior implementation.
Sourcefn pickup_block(
&self,
world: &Arc<World>,
pos: BlockPos,
state: BlockStateId,
player: Option<&Player>,
) -> Option<PickupResult>
fn pickup_block( &self, world: &Arc<World>, pos: BlockPos, state: BlockStateId, player: Option<&Player>, ) -> Option<PickupResult>
Called when a player uses an empty bucket on this block.
Should:
- Remove or modify the block
- Return the filled bucket stack to give
Return None if pickup failed.
Sourcefn update_shape(
&self,
state: BlockStateId,
_world: &dyn ScheduledTickAccess,
_pos: BlockPos,
_direction: Direction,
_neighbor_pos: BlockPos,
_neighbor_state: BlockStateId,
) -> BlockStateId
fn update_shape( &self, state: BlockStateId, _world: &dyn ScheduledTickAccess, _pos: BlockPos, _direction: Direction, _neighbor_pos: BlockPos, _neighbor_state: BlockStateId, ) -> BlockStateId
Called when a neighboring block changes shape.
Returns the new state for this block after considering the neighbor change.
Implementations also own any block or fluid ticks that Vanilla schedules
from updateShape; the world dispatcher does not infer them from the result.
Sourcefn update_indirect_neighbour_shapes(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
flags: UpdateFlags,
update_limit: i32,
)
fn update_indirect_neighbour_shapes( &self, state: BlockStateId, world: &Arc<World>, pos: BlockPos, flags: UpdateFlags, update_limit: i32, )
Queues indirect neighbor-shape updates after this state changes.
Vanilla’s default is a no-op. Redstone wire overrides this for vertical corner connections.
Sourcefn can_survive(
&self,
_state: BlockStateId,
_world: &dyn LevelReader,
_pos: BlockPos,
) -> bool
fn can_survive( &self, _state: BlockStateId, _world: &dyn LevelReader, _pos: BlockPos, ) -> bool
Returns whether this block can survive at the given position.
Vanilla parity: BlockBehavior.canSurvive(BlockState, LevelReader, BlockPos).
Used during placement validation, shape updates (to break unsupported
blocks), and when removing water from waterlogged blocks. The default
returns true; override for blocks that require physical support
(torches, buttons, candles, cactus, etc.).
Sourcefn can_be_replaced(
&self,
state: BlockStateId,
context: &BlockPlaceContext<'_>,
) -> bool
fn can_be_replaced( &self, state: BlockStateId, context: &BlockPlaceContext<'_>, ) -> bool
Returns whether this block can be replaced by the held item during placement.
Vanilla parity: BlockState.canBeReplaced(BlockPlaceContext).
Default behavior mirrors BlockBehaviour.canBeReplaced.
Sourcefn on_place(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
old_state: BlockStateId,
moved_by_piston: bool,
)
fn on_place( &self, state: BlockStateId, world: &Arc<World>, pos: BlockPos, old_state: BlockStateId, moved_by_piston: bool, )
Called when this block is placed in the world.
§Arguments
state- The new block state that was placedworld- The world the block was placed inpos- The position where the block was placedold_state- The previous block state at this positionmoved_by_piston- Whether the block was moved by a piston
Sourcefn set_placed_by(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
source: &PlacementSource<'_>,
)
fn set_placed_by( &self, state: BlockStateId, world: &Arc<World>, pos: BlockPos, source: &PlacementSource<'_>, )
Called by block items after this block has been placed by an entity.
Vanilla parity: Block.setPlacedBy(Level, BlockPos, BlockState, LivingEntity, ItemStack).
Steel passes the placement source instead of a borrowed stack so the
caller does not hold the inventory lock while dispatching block behavior
and synthetic placements can retain a directly supplied stack.
This is intentionally separate from [on_place], which fires for any
world block mutation.
Sourcefn attack(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
player: &Player,
)
fn attack( &self, state: BlockStateId, world: &Arc<World>, pos: BlockPos, player: &Player, )
Called when a player starts attacking this block.
Vanilla parity: Block.attack(BlockState, Level, BlockPos, Player).
Sourcefn player_destroy(
&self,
world: &Arc<World>,
player: &Player,
pos: BlockPos,
state: BlockStateId,
block_entity: Option<&SharedBlockEntity>,
tool: &ItemStack,
)
fn player_destroy( &self, world: &Arc<World>, player: &Player, pos: BlockPos, state: BlockStateId, block_entity: Option<&SharedBlockEntity>, tool: &ItemStack, )
Called after a player destroys this block and drops/effects are processed.
Vanilla parity: Block.playerDestroy(Level, Player, BlockPos, BlockState, BlockEntity, ItemStack).
Sourcefn player_will_destroy(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
player: &Player,
) -> BlockStateId
fn player_will_destroy( &self, state: BlockStateId, world: &Arc<World>, pos: BlockPos, player: &Player, ) -> BlockStateId
Called before a player removes this block.
Vanilla parity: Block.playerWillDestroy(Level, BlockPos, BlockState, Player).
The returned state is the state used for tool damage and loot after the
block is removed.
Sourcefn destroy(&self, state: BlockStateId, world: &Arc<World>, pos: BlockPos)
fn destroy(&self, state: BlockStateId, world: &Arc<World>, pos: BlockPos)
Called after a player successfully removes this block.
Mirrors vanilla Block.destroy(LevelAccessor, BlockPos, BlockState).
Sourcefn get_drops(
&self,
state: BlockStateId,
context: &BlockLootContext<'_>,
) -> Option<Vec<ItemStack>>
fn get_drops( &self, state: BlockStateId, context: &BlockLootContext<'_>, ) -> Option<Vec<ItemStack>>
Overrides the loot generated for this block state.
Returning None evaluates the state’s normal loot table. Returning
Some uses the provided items, including an empty list. This mirrors
vanilla’s per-block getDrops override point.
Sourcefn spawn_after_break(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
tool: &ItemStack,
drop_experience: bool,
)
fn spawn_after_break( &self, state: BlockStateId, world: &Arc<World>, pos: BlockPos, tool: &ItemStack, drop_experience: bool, )
Called for post-break effects such as experience drops.
Vanilla parity: Block.spawnAfterBreak(BlockState, ServerLevel, BlockPos, ItemStack, boolean). Normal block destruction invokes this after loot;
other destruction paths retain their Vanilla-specific ordering. Ore
experience and similar non-item drops belong here rather than in the
loot-table override.
Sourcefn affect_neighbors_after_removal(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
moved_by_piston: bool,
)
fn affect_neighbors_after_removal( &self, state: BlockStateId, world: &Arc<World>, pos: BlockPos, moved_by_piston: bool, )
Called after this block is removed from the world, to affect neighbors.
This is used for things like rails notifying neighbors when removed.
§Arguments
state- The block state that was removedworld- The world the block was removed frompos- The position where the block was removedmoved_by_piston- Whether the block was moved by a piston
Sourcefn use_item_on(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
player: &Player,
hand: InteractionHand,
hit_result: &BlockHitResult,
inv: &mut InventoryAccess,
) -> InteractionResult
fn use_item_on( &self, state: BlockStateId, world: &Arc<World>, pos: BlockPos, player: &Player, hand: InteractionHand, hit_result: &BlockHitResult, inv: &mut InventoryAccess, ) -> InteractionResult
Called when a player uses an item on this block.
Returns TryEmptyHandInteraction by default to fall through to item use.
Override this to handle block-specific interactions (e.g., opening chests,
using buttons, etc.).
Sourcefn use_without_item(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
player: &Player,
hit_result: &BlockHitResult,
inv: &mut InventoryAccess,
) -> InteractionResult
fn use_without_item( &self, state: BlockStateId, world: &Arc<World>, pos: BlockPos, player: &Player, hit_result: &BlockHitResult, inv: &mut InventoryAccess, ) -> InteractionResult
Called when a player uses this block without an item (or as a fallback
when use_item_on returns TryEmptyHandInteraction).
Returns Pass by default. Override this for blocks that have interactions
without needing an item (e.g., buttons, levers, repeaters).
Sourcefn handle_neighbor_changed(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
source_block: BlockRef,
moved_by_piston: bool,
)
fn handle_neighbor_changed( &self, state: BlockStateId, world: &Arc<World>, pos: BlockPos, source_block: BlockRef, moved_by_piston: bool, )
Called when a neighboring block changes (not shape-related).
This is the Rust equivalent of vanilla’s BlockState.handleNeighborChanged().
Used by redstone components, doors, and other blocks that react to neighbor changes.
§Arguments
state- The current block stateworld- The worldpos- Position of this blocksource_block- The block type that changedmoved_by_piston- Whether the change was caused by a piston
Sourcefn is_signal_source(
&self,
_state: BlockStateId,
_context: SignalQueryContext,
) -> bool
fn is_signal_source( &self, _state: BlockStateId, _context: SignalQueryContext, ) -> bool
Returns whether this state is a redstone signal source.
Sourcefn is_diode(&self) -> bool
fn is_diode(&self) -> bool
Returns whether this behavior is a vanilla diode block.
Vanilla uses its DiodeBlock class hierarchy for side-input filtering.
Sourcefn is_trapdoor(&self) -> bool
fn is_trapdoor(&self) -> bool
Returns whether this behavior implements vanilla TrapDoorBlock semantics.
Redstone wire uses this class-hierarchy check when deciding whether it can climb onto a neighboring block.
Sourcefn is_rail(&self) -> bool
fn is_rail(&self) -> bool
Returns whether this behavior implements vanilla BaseRailBlock semantics.
Sourcefn is_piston_base(&self) -> bool
fn is_piston_base(&self) -> bool
Returns whether this behavior implements vanilla PistonBaseBlock semantics.
Sourcefn get_own_signal(
&self,
_state: BlockStateId,
_world: &dyn LevelReader,
_pos: BlockPos,
_context: SignalQueryContext,
) -> i32
fn get_own_signal( &self, _state: BlockStateId, _world: &dyn LevelReader, _pos: BlockPos, _context: SignalQueryContext, ) -> i32
Returns this state’s direction-independent redstone signal strength.
Sourcefn get_signal(
&self,
state: BlockStateId,
world: &dyn LevelReader,
pos: BlockPos,
_direction: Direction,
context: SignalQueryContext,
) -> i32
fn get_signal( &self, state: BlockStateId, world: &dyn LevelReader, pos: BlockPos, _direction: Direction, context: SignalQueryContext, ) -> i32
Returns the weak redstone signal emitted toward direction.
Sourcefn get_direct_signal(
&self,
_state: BlockStateId,
_world: &dyn LevelReader,
_pos: BlockPos,
_direction: Direction,
_context: SignalQueryContext,
) -> i32
fn get_direct_signal( &self, _state: BlockStateId, _world: &dyn LevelReader, _pos: BlockPos, _direction: Direction, _context: SignalQueryContext, ) -> i32
Returns the direct redstone signal emitted toward direction.
Sourcefn is_redstone_conductor(
&self,
state: BlockStateId,
_world: &dyn LevelReader,
_pos: BlockPos,
) -> bool
fn is_redstone_conductor( &self, state: BlockStateId, _world: &dyn LevelReader, _pos: BlockPos, ) -> bool
Returns whether this state conducts direct redstone power through itself.
Most blocks use extracted state data. Dynamic blocks can override this with a live level/position query, matching vanilla’s state predicate surface.
Sourcefn trigger_event(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
param_a: i32,
param_b: i32,
) -> bool
fn trigger_event( &self, state: BlockStateId, world: &Arc<World>, pos: BlockPos, param_a: i32, param_b: i32, ) -> bool
Handles a queued server block event.
Mirrors Vanilla BlockBehaviour.triggerEvent. Returning true publishes
the corresponding event packet to nearby clients.
Sourcefn get_clone_item_stack(
&self,
block: BlockRef,
state: BlockStateId,
include_data: bool,
) -> Option<ItemStack>
fn get_clone_item_stack( &self, block: BlockRef, state: BlockStateId, include_data: bool, ) -> Option<ItemStack>
Returns the item stack to give when a player picks this block (middle click).
The default implementation looks up an item with the same key as the block. Override this for blocks where the pick item differs from the block key (e.g., crops → seeds, redstone wire → redstone dust, wall torch → torch).
§Arguments
block- The block being picked_state- The block state (some blocks vary pick item based on state)_include_data- Whether to include block entity data (creative + Ctrl)
Sourcefn is_pathfindable(
&self,
state: BlockStateId,
computation_type: PathComputationType,
) -> bool
fn is_pathfindable( &self, state: BlockStateId, computation_type: PathComputationType, ) -> bool
Returns whether this block state is pathfindable for the supplied vanilla path computation.
Vanilla baseline for BlockBehaviour.isPathfindable.
Sourcefn is_wooden_door(&self, state: BlockStateId) -> bool
fn is_wooden_door(&self, state: BlockStateId) -> bool
Mirrors vanilla DoorBlock.isWoodenDoor.
Despite the vanilla name, this returns true for any door block type that can be opened by hand.
Sourcefn set_door_open(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
source_entity: Option<&dyn Entity>,
open: bool,
) -> bool
fn set_door_open( &self, state: BlockStateId, world: &Arc<World>, pos: BlockPos, source_entity: Option<&dyn Entity>, open: bool, ) -> bool
Mirrors vanilla DoorBlock.setOpen for AI door goals.
Sourcefn default_get_collision_shape(
&self,
state: BlockStateId,
world: &dyn LevelReader,
pos: BlockPos,
context: BlockCollisionContext,
) -> VoxelShape
fn default_get_collision_shape( &self, state: BlockStateId, world: &dyn LevelReader, pos: BlockPos, context: BlockCollisionContext, ) -> VoxelShape
Returns this block state’s collision shape for the supplied collision context.
Vanilla baseline for BlockState.getCollisionShape(BlockGetter, BlockPos, CollisionContext).
Sourcefn get_collision_shape(
&self,
state: BlockStateId,
world: &dyn LevelReader,
pos: BlockPos,
context: BlockCollisionContext,
) -> VoxelShape
fn get_collision_shape( &self, state: BlockStateId, world: &dyn LevelReader, pos: BlockPos, context: BlockCollisionContext, ) -> VoxelShape
Returns this block state’s collision shape for the supplied collision context.
Overrides that mirror vanilla super.getCollisionShape(...) should call
Self::default_get_collision_shape.
Sourcefn get_collision_shape_offset(
&self,
state: BlockStateId,
world: &dyn LevelReader,
pos: BlockPos,
context: BlockCollisionContext,
) -> DVec3
fn get_collision_shape_offset( &self, state: BlockStateId, world: &dyn LevelReader, pos: BlockPos, context: BlockCollisionContext, ) -> DVec3
Returns a block-local translation for this block state’s collision shape.
Vanilla baseline for BlockState.getOffset(BlockPos) where
getCollisionShape delegates to the offset outline shape.
Sourcefn get_collision_boxes(
&self,
state: BlockStateId,
world: &dyn LevelReader,
pos: BlockPos,
context: BlockCollisionContext,
) -> BlockCollisionBoxes
fn get_collision_boxes( &self, state: BlockStateId, world: &dyn LevelReader, pos: BlockPos, context: BlockCollisionContext, ) -> BlockCollisionBoxes
Resolves this block state’s collision shape to owned block-local boxes.
Vanilla dynamic-shape blocks may override this directly. Static blocks inherit the collision shape and positional offset hooks above.
Sourcefn get_block_support_boxes(
&self,
state: BlockStateId,
world: &dyn LevelReader,
pos: BlockPos,
) -> BlockCollisionBoxes
fn get_block_support_boxes( &self, state: BlockStateId, world: &dyn LevelReader, pos: BlockPos, ) -> BlockCollisionBoxes
Resolves vanilla BlockState.getBlockSupportShape to owned block-local boxes.
Most states use extracted support shapes. Dynamic blocks can override this
hook to consult live world data, as vanilla does when its state cache is
disabled by dynamicShape().
Sourcefn is_face_sturdy(
&self,
state: BlockStateId,
world: &dyn LevelReader,
pos: BlockPos,
direction: Direction,
support_type: SupportType,
) -> bool
fn is_face_sturdy( &self, state: BlockStateId, world: &dyn LevelReader, pos: BlockPos, direction: Direction, support_type: SupportType, ) -> bool
Mirrors vanilla BlockState.isFaceSturdy(level, pos, direction, supportType).
Static states retain their registry fast path. Dynamic states evaluate the live support boxes so block entities and other world-dependent shapes remain observable to attachment logic.
Sourcefn default_get_entity_inside_collision_shape(
&self,
state: BlockStateId,
world: &dyn LevelReader,
pos: BlockPos,
entity: &dyn Entity,
) -> VoxelShape
fn default_get_entity_inside_collision_shape( &self, state: BlockStateId, world: &dyn LevelReader, pos: BlockPos, entity: &dyn Entity, ) -> VoxelShape
Returns this block state’s shape used by vanilla entity-inside effects.
Vanilla baseline for
BlockState.getEntityInsideCollisionShape(BlockGetter, BlockPos, Entity).
Sourcefn get_entity_inside_collision_shape(
&self,
state: BlockStateId,
world: &dyn LevelReader,
pos: BlockPos,
entity: &dyn Entity,
) -> VoxelShape
fn get_entity_inside_collision_shape( &self, state: BlockStateId, world: &dyn LevelReader, pos: BlockPos, entity: &dyn Entity, ) -> VoxelShape
Returns this block state’s shape used by vanilla entity-inside effects.
Sourcefn random_tick(&self, state: BlockStateId, world: &Arc<World>, pos: BlockPos)
fn random_tick(&self, state: BlockStateId, world: &Arc<World>, pos: BlockPos)
Called on random tick for blocks that support random ticking.
This is only called when the block state’s extracted metadata marks it as randomly ticking. Used for crop growth, grass spread, ice melting, fire behavior, etc.
§Arguments
state- The current block stateworld- The world the block is inpos- The position of the block
Sourcefn tick(&self, state: BlockStateId, world: &Arc<World>, pos: BlockPos)
fn tick(&self, state: BlockStateId, world: &Arc<World>, pos: BlockPos)
Called when a scheduled tick fires for this block.
Unlike random_tick, scheduled ticks are deterministic — they fire after
a precise delay set by World::schedule_block_tick. Used for buttons
unpressing, repeaters firing, fluids flowing, etc.
§Arguments
state- The current block stateworld- The world the block is inpos- The position of the block
Sourcefn on_projectile_hit(
&self,
_state: BlockStateId,
_world: &Arc<World>,
_hit: &ClipHitResult,
_projectile: &dyn Projectile,
)
fn on_projectile_hit( &self, _state: BlockStateId, _world: &Arc<World>, _hit: &ClipHitResult, _projectile: &dyn Projectile, )
Called when a projectile hits this block.
Vanilla parity: BlockState.onProjectileHit(Level, BlockState, BlockHitResult, Projectile).
Sourcefn default_entity_inside(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
entity: &dyn Entity,
effect_collector: &mut InsideBlockEffectCollector,
is_precise: bool,
)
fn default_entity_inside( &self, state: BlockStateId, world: &Arc<World>, pos: BlockPos, entity: &dyn Entity, effect_collector: &mut InsideBlockEffectCollector, is_precise: bool, )
Default entity-inside hook.
Overrides that mirror vanilla super.entityInside(...) should call
Self::default_entity_inside.
Sourcefn entity_inside(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
entity: &dyn Entity,
effect_collector: &mut InsideBlockEffectCollector,
is_precise: bool,
)
fn entity_inside( &self, state: BlockStateId, world: &Arc<World>, pos: BlockPos, entity: &dyn Entity, effect_collector: &mut InsideBlockEffectCollector, is_precise: bool, )
Called when an entity is inside this block’s collision area.
Used by cactus (damage), fire (ignite), sweet berry bush (slow + damage), etc.
§Arguments
state- The current block stateworld- The worldpos- The position of the blockentity- The entity inside the block
Sourcefn default_fall_on(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
context: EntityFallOnContext<'_>,
) -> Option<EntityFallDamage>
fn default_fall_on( &self, state: BlockStateId, world: &Arc<World>, pos: BlockPos, context: EntityFallOnContext<'_>, ) -> Option<EntityFallDamage>
Default fall-on hook.
Overrides that mirror vanilla super.fallOn(...) should call
Self::default_fall_on.
Sourcefn fall_on(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
context: EntityFallOnContext<'_>,
) -> Option<EntityFallDamage>
fn fall_on( &self, state: BlockStateId, world: &Arc<World>, pos: BlockPos, context: EntityFallOnContext<'_>, ) -> Option<EntityFallDamage>
Called when an entity lands on this block.
Vanilla parity: Block.fallOn(Level, BlockState, BlockPos, Entity, double).
Sourcefn after_fall_on_damage(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
entity: &dyn Entity,
fall_damage: &EntityFallDamage,
damage_applied: bool,
)
fn after_fall_on_damage( &self, state: BlockStateId, world: &Arc<World>, pos: BlockPos, entity: &dyn Entity, fall_damage: &EntityFallDamage, damage_applied: bool, )
Called after fall damage requested by BlockBehavior::fall_on is applied.
Vanilla parity hook for block-specific fall side effects that depend on
whether Entity.causeFallDamage returned true.
Sourcefn default_update_entity_movement_after_fall_on(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
context: EntityLandingContext,
) -> DVec3
fn default_update_entity_movement_after_fall_on( &self, state: BlockStateId, world: &Arc<World>, pos: BlockPos, context: EntityLandingContext, ) -> DVec3
Default post-fall movement hook.
Overrides that mirror vanilla super.updateEntityMovementAfterFallOn(...)
should call Self::default_update_entity_movement_after_fall_on.
Sourcefn update_entity_movement_after_fall_on(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
context: EntityLandingContext,
) -> DVec3
fn update_entity_movement_after_fall_on( &self, state: BlockStateId, world: &Arc<World>, pos: BlockPos, context: EntityLandingContext, ) -> DVec3
Updates entity velocity after a vertical movement collision with this block.
Vanilla mutates the entity in Block.updateEntityMovementAfterFallOn.
Steel returns the velocity to apply so movement resolution keeps entity
state changes centralized in Entity::move_entity.
Sourcefn default_step_on(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
entity: &dyn Entity,
)
fn default_step_on( &self, state: BlockStateId, world: &Arc<World>, pos: BlockPos, entity: &dyn Entity, )
Default step-on hook.
Overrides that mirror vanilla super.stepOn(...) should call
Self::default_step_on.
Sourcefn step_on(
&self,
state: BlockStateId,
world: &Arc<World>,
pos: BlockPos,
entity: &dyn Entity,
)
fn step_on( &self, state: BlockStateId, world: &Arc<World>, pos: BlockPos, entity: &dyn Entity, )
Called when an entity steps on this block while on ground.
Vanilla parity: Block.stepOn(Level, BlockPos, BlockState, Entity).
Sourcefn new_block_entity(
&self,
level: Weak<World>,
pos: BlockPos,
state: BlockStateId,
) -> BlockEntityCreation
fn new_block_entity( &self, level: Weak<World>, pos: BlockPos, state: BlockStateId, ) -> BlockEntityCreation
Creates a new block entity for this block.
Structural block-entity presence comes from the extracted block-entity type registry. The result distinguishes a missing Steel implementation from a Vanilla factory that intentionally returns no entity.
§Arguments
level- Weak reference to the worldpos- The position where the block entity will be placedstate- The block state for this block entity
Sourcefn get_block_entity_ticker(
&self,
world: &Arc<World>,
state: BlockStateId,
block_entity_type: BlockEntityTypeRef,
) -> Option<BlockEntityTicker>
fn get_block_entity_ticker( &self, world: &Arc<World>, state: BlockStateId, block_entity_type: BlockEntityTypeRef, ) -> Option<BlockEntityTicker>
Returns the server ticker selected by this live block state and entity type.
Mirrors Vanilla EntityBlock.getTicker. Selection runs without chunk,
section, or block-entity storage locks.
Sourcefn get_game_event_listener(
&self,
world: &Arc<World>,
block_entity: &dyn BlockEntity,
) -> Option<SharedGameEventListener>
fn get_game_event_listener( &self, world: &Arc<World>, block_entity: &dyn BlockEntity, ) -> Option<SharedGameEventListener>
Returns the game-event listener exposed by this block entity.
Mirrors Vanilla EntityBlock.getListener. Block implementations may override the
provider result; the default delegates to the block entity’s listener capability.
Sourcefn should_keep_block_entity(
&self,
old_state: BlockStateId,
new_state: BlockStateId,
) -> bool
fn should_keep_block_entity( &self, old_state: BlockStateId, new_state: BlockStateId, ) -> bool
Returns whether this new block should keep the old state’s block entity.
Vanilla defaults to false; copper chests and copper golem statues explicitly
keep their entity across transformations within their respective block family.
Steel checks those two extracted tags here until those block classes have their
own complete behaviors, rather than registering partial block implementations.
Non-Vanilla behaviors must opt in explicitly even if a plugin extends either tag.
§Arguments
old_state- The previous block statenew_state- The requested replacement state
Sourcefn has_analog_output_signal(&self, state: BlockStateId) -> bool
fn has_analog_output_signal(&self, state: BlockStateId) -> bool
Returns whether this block can provide an analog output signal to comparators.
Override to return true for containers (chests, barrels, hoppers, etc.)
and other blocks that comparators can read (composters, beehives, etc.).
Sourcefn get_analog_output_signal(
&self,
state: BlockStateId,
world: &dyn LevelReader,
pos: BlockPos,
direction: Direction,
) -> i32
fn get_analog_output_signal( &self, state: BlockStateId, world: &dyn LevelReader, pos: BlockPos, direction: Direction, ) -> i32
Returns the analog output signal strength (0-15) for comparators.
Only called if has_analog_output_signal() returns true.
For containers, this is typically based on how full they are.
§Arguments
state- The current block stateworld- The worldpos- The position of the blockdirection- The face from which the comparator reads the block
Sourcefn is_liquid_container(&self, state: BlockStateId) -> bool
fn is_liquid_container(&self, state: BlockStateId) -> bool
Vanilla parity: whether this block implements LiquidBlockContainer.
This is a block behavior capability, not just a state property. Most
simple waterlogged blocks expose it through WATERLOGGED, but vanilla
also has liquid containers without that property, such as kelp and
seagrass.
Sourcefn can_place_liquid(&self, state: BlockStateId, fluid: FluidRef) -> bool
fn can_place_liquid(&self, state: BlockStateId, fluid: FluidRef) -> bool
Vanilla parity: LiquidBlockContainer.canPlaceLiquid().
Returns true if the given fluid type may be placed into this block at the
given state. Called by the fluid-spread logic; there is no player context
here (fluid spreading has no associated player).
Default (SimpleWaterloggedBlock): accepts source water for blocks with
a WATERLOGGED property. Override for blocks that need different
restrictions (e.g. double-slabs, barriers).
Vanilla signature: canPlaceLiquid(@Nullable LivingEntity, BlockGetter, BlockPos, BlockState, Fluid)
— the Fluid parameter is a type, not a state.
Sourcefn can_place_liquid_with_player(
&self,
state: BlockStateId,
fluid: FluidRef,
_player: Option<&Player>,
) -> bool
fn can_place_liquid_with_player( &self, state: BlockStateId, fluid: FluidRef, _player: Option<&Player>, ) -> bool
Vanilla parity: LiquidBlockContainer.canPlaceLiquid() with a user.
Runtime bucket placement supplies the acting player; fluid spread and
other no-user callers should use can_place_liquid.
Sourcefn can_be_replaced_by_fluid(
&self,
state: BlockStateId,
_fluid_block: BlockRef,
) -> bool
fn can_be_replaced_by_fluid( &self, state: BlockStateId, _fluid_block: BlockRef, ) -> bool
Vanilla parity: BlockBehaviour.BlockStateBase.canBeReplaced(Fluid).
This is a behavior hook because vanilla block subclasses can override the
base replacement rule. The default mirrors Block.canBeReplaced(Fluid).
Sourcefn place_liquid(
&self,
level: &dyn LevelAccessor,
pos: BlockPos,
state: BlockStateId,
fluid_state: FluidState,
) -> bool
fn place_liquid( &self, level: &dyn LevelAccessor, pos: BlockPos, state: BlockStateId, fluid_state: FluidState, ) -> bool
Vanilla parity: LiquidBlockContainer.placeLiquid().
Attempts to place fluid_state into this block. Returns true on success,
false if placement was rejected.
Default (SimpleWaterloggedBlock): sets WATERLOGGED = true and schedules
a fluid tick. Vanilla’s default placeLiquid directly accepts source
water and does not delegate to canPlaceLiquid.
Sourcefn as_bonemealable(&self) -> Option<&dyn Bonemealable>
fn as_bonemealable(&self) -> Option<&dyn Bonemealable>
Returns the trait object for Blocks that have the Bonemealable trait implemented.
Sourcefn as_rail(&self) -> Option<&dyn RailBehavior>
fn as_rail(&self) -> Option<&dyn RailBehavior>
Returns the shared vanilla rail capability implemented by this block.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".