Skip to content

Blocks and block behavior

Block definitions derive from Block and are registered as shared instances by BlockRegistry. BlockProperties describes common properties, while subclasses own behavior that is specific to their domain. Texture selection and atlas indices belong with the relevant block data and existing atlas conventions.

Block behavior is invoked by gameplay or world lifecycle events: placement, removal, neighbor changes, scheduled ticks, random ticks, interaction, collision/step events, and redstone signal queries. Follow the corresponding virtual method on Block and its callers before changing a rule. Keep behavior polymorphic; avoid adding a growing BlockType switch in WorldManager.

State is stored per cell, but the current BlockStateData is intentionally compact and cannot encode all vanilla block properties. When adding behavior that depends on facing, open/powered flags, or support, first verify that the required state can be represented and that placement and update paths preserve it. A missing state capability is a foundation gap, not a reason to hide parallel state in an unrelated system.

Block hooks use the level interfaces under src/World/ to request world reads, writes, ticks, and signals. Prefer the narrowest interface a hook needs. WorldManager implements the runtime coordination behind those interfaces; a block should not depend on scene-tree details where a level operation expresses the intent.

  1. Search src/Voxel/Blocks/ and BlockRegistry for a related implementation and registration pattern.
  2. Check whether the required state, shape, item, texture, and block-entity support already exists.
  3. Implement local behavior in a focused Block subclass and wire registration through the existing registry.
  4. Reuse atlas/assets and import settings; avoid copying reference assets outside the two retained title assets specified in AGENTS.md.
  5. Trace placement, neighbor updates, tick scheduling, drops, and save/load implications for the behavior you add.

Minecraft’s meaningful boundary is BlockBehaviour/Block plus state definitions and level APIs. Use the supplied 26.3 reference to establish the behavior, then adapt it to GDCraft’s existing owner and data model. Do not copy broad source trees.

Step Owner Question to answer
Player intent BlockInteraction Was this a use, attack, or placement action, and what did the ray hit?
World mutation ILevelWriter / WorldManager Which position changes, and what happens to an attached block entity?
Neighbor response Block subclasses via level updates Which adjacent positions are notified, and in what order?
Deferred behavior scheduled tick access Did the block request a later update?
Derived data lighting and section mesh owners Which sections need relighting or remeshing?

The block hook owns the local decision; the level coordinator owns global consequences. Trace both when a change looks correct in storage but leaves stale neighbors, lighting, or geometry.

Before adding state-dependent behavior, check the per-cell encoding and every transition that writes it. Placement, rotation, neighbor updates, serializer round trips, and mesh texture selection must agree on the same state representation.