User Tools

Site Tools


Sidebar

← Go back to the homepage

Fabric Tutorials

Setup

These pages will help you setup a productive development environment and semi-automated releases.

Basics

These pages are essential must-reads when modding with Fabric, and modding Minecraft in general, if you are new to modding, it is recommended you read the following.

Items

Blocks and Block Entities

Data Generation

World Generation

Commands

These pages will guide you through Mojang's Brigadier library which allows you to create commands with complex arguments and actions.

Events

These pages will guide you through using the many events included in Fabric API, and how to create your own events for you or other mods to use.

Entities

Fluids

Mixins & ASM

These pages will guide you through the usage of SpongePowered's Mixin library, which is a highly complex topic. We recommend you read these pages thoroughly.

Miscellaneous

Yarn

Contribute to Fabric

tutorial:waterloggable

Make a Block Waterloggable

To make blocks waterloggable, implement Waterloggable interface and override some methods.

public class VerticalSlabBlock extends HorizontalFacingBlock implements Waterloggable {
    [...]
}

In this case, we store the Properties.WATERLOGGED as a static field in this class, and you can use WATERLOGGED to access the field. (Unnecessary as it looks, most vanilla Minecraft block classes do that, so we do as well. Of course you can refuse to do that, and use Properties.WATERLOGGED every time to access it, or just directly import the static field.) We have to manually make the block recognize the property, as it is not done for you by Waterloggable interface.

    // Note the ''Properties'' is net.minecraft.state.property.Properties. Don't import the wrong one.
    public static final BooleanProperty WATERLOGGED = Properties.WATERLOGGED;
 
    // Let default value of the WATERLOGGED property become ``false``
    public VerticalSlabBlock(Settings settings) {
        super(settings);
        setDefaultState(this.stateManager.getDefaultState()
            .with(Properties.HORIZONTAL_FACING, Direction.NORTH)
            .with(WATERLOGGED, false);
    }
 
    // Make the block recognize the property, otherwise setting the property will through exceptions.
    @Override
    protected void appendProperties(StateManager.Builder<Block, BlockState> stateManager) {
        stateManager.add(Properties.HORIZONTAL_FACING, WATERLOGGED);
    }

We also have to override getPlacementState, so that the block placed in water is initially waterlogged.

    @Override
    public BlockState getPlacementState(ItemPlacementContext ctx) {
        return (BlockState)this.getDefaultState()
            .with(Properties.HORIZONTAL_FACING, ctx.getPlayerFacing().getOpposite())
            .with(WATERLOGGED, ctx.getWorld().getFluidState(ctx.getBlockPos()).getFluid() == Fluids.WATER);
    }

Override getFluidState so that when it is waterlogged the block displays water.

    @Override
    public FluidState getFluidState(BlockState state) {
        return state.get(WATERLOGGED) ? Fluids.WATER.getStill(false) : super.getFluidState(state);
    }

Override getStateForNeighborUpdate so that it correctly handles the flowing of water.

    @Override
    public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState neighborState, WorldAccess world, BlockPos pos, BlockPos neighborPos) {
        if (state.get(WATERLOGGED)) {
            // This is for 1.17 and below: world.getFluidTickScheduler().schedule(pos, Fluids.WATER, Fluids.WATER.getTickRate(world));
            world.createAndScheduleFluidTick(pos, Fluids.WATER, Fluids.WATER.getTickRate(world));
        }
 
        return super.getStateForNeighborUpdate(state, direction, neighborState, world, pos, neighborPos);
    }

Now the block becomes waterloggable, and works correctly with water.

tutorial/waterloggable.txt · Last modified: 2022/03/20 13:39 by solidblock