Blocks and block behavior
Shared definitions
Section titled “Shared definitions”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.
Behavior lifecycle
Section titled “Behavior lifecycle”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 and placement
Section titled “State and placement”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.
Level APIs
Section titled “Level APIs”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.
Adding a block
Section titled “Adding a block”- Search
src/Voxel/Blocks/andBlockRegistryfor a related implementation and registration pattern. - Check whether the required state, shape, item, texture, and block-entity support already exists.
- Implement local behavior in a focused
Blocksubclass and wire registration through the existing registry. - Reuse atlas/assets and import settings; avoid copying reference assets outside the two retained title assets specified in
AGENTS.md. - Trace placement, neighbor updates, tick scheduling, drops, and save/load implications for the behavior you add.
Reference comparison
Section titled “Reference comparison”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.
Trace a block update
Section titled “Trace a block update”| 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.