Modding:Block Attachment

From Vintage Story Wiki

Overview

Some blocks have an attachment requirement, which is a restriction on what kinds of blocks it can have as a neighbor. In this article, the terms attachment block (for example, a torch) and parent block (for example, cobblestone) are used.

Trying to place the attachment block starts the process of verifying attachment. The block the player was looking at is the proposed parent block. CanAttachBlockAt is called on the proposed parent block. The block argument to the function is the proposed attachment block. The parent block may either accept or reject the attachment by returning true or false. By default the block will accept the attachment if the attachment face of the parent block is solid. For example, a torch cannot be attached to a leaves block, because all of its sides are non-solid, but a torch can be attached to the branch leaves block, because it is solid.

If the parent block changes, then the attachment block will call CanAttachBlockAt again to verify it can remain attached. If not, then the attachment block will break itself.

Attachment Area

CanAttachBlockAt is also given an attachment area as a cuboid. It is the area of the parent block in voxel coordinates in which the child block is trying to connect. Logically, the parent block could return true if that entire area is non-empty in the parent block. However, most parent blocks ignore the attachment area, and of those that use it, none of them strictly implement that logic. These are the only two parent blocks that currently use the attachment area:

chiseled block (specifically BEMicroBlock)
Flattens the attachment area into a 2 rectangle, then checks that all of the voxels in that 2d rectangle are non-empty on the attachment face of the chiseled block.
slabs (specifically OmniRotatable in all faces mode)
For downward and upward facing slabs, it accepts the attachment if the attachment area is on the non-empty half of the block. Otherwise, it does not intercept the request.

Block Behaviors for Parent Block

CanAttach
Accepts the attachment if the face is listed in the sides property, otherwise delegates to the rest of the event chain.
HorizontalAttachable
As a parent block, it rejects all attachments.
OmniAttachable
As a parent block, it rejects all attachments.
OmniRotatable
If the block is in the down rotation (the lower half of the block is non-empty), then it verifies that the attachment area is in the lower half of the block. If the block is in the up rotation, then it verifies that the attachment area is in the upper half of the block. In all the modes or orientations, BehaviorOmniRotatable delegates to the rest of the event chain, which typically accepts the attachment if that face of the block is solid.

Block Behaviors for Attachment Block

FiniteSpreadingLiquid
Tries to spread if the parent block underneath accepts the attachment
HorizontalAttachable
Requires the block to be attached horizontally.
Ladder
Considers the ladder supported if the parent block accepts the attachment. The ladder tries both the lower and upper halves of the block as an attachment area, so that it can be attached to upward and downward slabs. Even if the parent block rejects the ladder, the ladder is still considered supported if finds another ladder block directly above or below.
OmniAttachable
Requires the block to be attached in any direction.
Unstable
Checks the neighbors of the attachment block in all allowed directions to see if any of them accept the attachment. The allowed directions can be configured through the attachedToFaces property.
UnstableFalling
Checks the neighbors of the attachment block in all allowed directions to see if any of them accept the attachment. The allowed directions can be configured through the attachableFaces property.
Decor
Attaches decors to the parent block in the decor layer.