Modding:Adding Block Behavior

From Vintage Story Wiki


Basic Behavior

Let's create a behavior which makes a block move on right click.

Setting up

A development workspace is required. Additionally you will need the assets (blocktype, texture and lang file). You can either create your one owns or use those pre-made ones: Moving - No CS File.zip

Creating the behavior

So first of all we need to create the behavior itself, which is a class extending BlockBehavior

class Moving : BlockBehavior
{
    public Moving(Block block) : base(block)
    {
        
    } 
}

This class provides several methods we can override. You can find a full list of a methods by hovering with the mouse of "BlockBehavior" and pressing "F12".


The method bool OnPlayerInteract(IWorldAccessor world, IPlayer byPlayer, BlockSelection blockSel, ref EnumHandling handling) looks to be ideal for our purpose.

What should it do?

  1. Calculate the new position of the block depending on the face the player is looking at
  2. Check if the block can be placed at this position
  3. Remove the original block
  4. Place the new block using the previous calculate position
    public override bool OnPlayerInteract(IWorldAccessor world, IPlayer byPlayer, BlockSelection blockSel, ref EnumHandling handling)
    {
        BlockPos pos = blockSel.Position.AddCopy(blockSel.Face.GetOpposite());
        if (world.BlockAccessor.GetBlock(pos).IsReplacableBy(block))
        {
            world.BlockAccessor.SetBlock(0, blockSel.Position);
            world.BlockAccessor.SetBlock(block.BlockId, pos);
        }
        handling = EnumHandling.PreventDefault;
        return true;
    }

handling = EnumHandling.PreventDefault;

This is used to prevent all further actions. For example if you hold a block in hand it will no longer place it.

Register

In order the register the BlockBehavior we need to create a mod class, override Start(ICoreAPI) and register it with the given name:

    public class MovingBlocks : ModBase
    {

        public override void Start(ICoreAPI api)
        {
            base.Start(api);
            api.RegisterBlockBehavior("Moving", typeof(Moving));
        }

    }

Now all you need to do is to put the *.cs file in the zip file as well and you are ready to test/ distribute your mod.

You can download the example mod here.

Testing

Advanced Behavior

Our behavior is still rather simple, but there are a lot more possibilities. A behavior can have special properties, which can be defined by the blocktype itself.

Example

The behavior liquid supports some special properties as shown in this example of the water blocktype:

	behaviors: [
		{
			name: "FiniteSpreadingLiquid", 
			properties:
			{
				spreadDelay: 150, 
				liquidCollisionSound: "hotmetal", 
				sourceReplacementCode: "obsidian", 
				flowingReplacementCode: "basalt"
			}
		}
	],

Parsing properties

In order to take care of special properties there is a method called Initialize(JsonObject). Each blocktype creates a new instance of the behavior, so the method can be used to parse the properties.

So what kind of properties could we add?

  • push distance
  • pull block if player is sneaking

First of all, we need to override the method in our block behavior class ...

        public override void Initialize(JsonObject properties)
        {
            base.Initialize(properties);
        }

Additionally we need to add two fields, one for the distance and another one if the player should pull the block while sneaking ...

        public int distance = 1;
        public bool pull = false;

Now we can parse the two properties like so:

        distance = properties["distance"].AsInt(1);
        pull = properties["pull"].AsBool(false);

Adding another block

Testing