Skip to main content

Overview

Entity resolvers handle the conversion of entity data between Minecraft’s Java and Bedrock editions and Chunker’s intermediate format. These resolvers manage entity properties, NBT data, and format-specific entity types.

Base Resolver

EntityResolver

Abstract base class that can turn format-specific data into Chunker entities. The resolver uses a hierarchy-based system, calling handlers from base to child type.
EntityResolver<R, D>
abstract class
Located at: com.hivemc.chunker.conversion.encoding.base.resolver.entity.EntityResolver
R
type parameter
The resolvers used by this format (e.g., JavaResolvers, BedrockResolvers)
D
type parameter
The data class holding the encoded entity (e.g., CompoundTag for NBT)
The resolver calls handlers from base to child type, using the child type to construct the object. This allows logic to be shared - base entity properties don’t need to be handled every time.

Constructor

public EntityResolver(
    Version version,
    R resolvers,
    boolean preserveUnknownEntities
)
version
Version
The format version
resolvers
R
The resolvers used by this format
preserveUnknownEntities
boolean
Whether unknown entities should be read/written as UnknownEntity

Core Methods

to()
Converts format-specific entity data to a Chunker entity.
public Optional<Entity> to(D input)
public Optional<Entity> to(Class<? extends Entity> type, D input)
input
D
The input entity data (e.g., NBT CompoundTag)
type
Class<? extends Entity>
Optional specific entity class to convert to
returns
Optional<Entity>
The converted Chunker entity, or empty if not supported
from()
Converts a Chunker entity to format-specific data.
public Optional<D> from(Entity input)
input
Entity
The Chunker entity
returns
Optional<D>
The format-specific entity data, or empty if not supported

Entity Lifecycle Methods

These methods handle entity transformations during world processing:
shouldRemoveBeforeProcess()
Determines if an entity should be removed before column processing.
public <T extends Entity> boolean shouldRemoveBeforeProcess(
    ChunkerColumn column,
    T entity
)
shouldRemoveBeforeWrite()
Determines if an entity should be removed before column writing.
public <T extends Entity> boolean shouldRemoveBeforeWrite(
    ChunkerColumn column,
    T entity
)
updateBeforeProcess()
Updates an entity before column processing.
public <T extends Entity> T updateBeforeProcess(
    ChunkerColumn column,
    T entity
)
returns
T
The updated entity (may be same instance or new)
updateBeforeWrite()
Updates an entity before column writing.
public <T extends Entity> T updateBeforeWrite(
    ChunkerColumn column,
    T entity
)
generateBeforeProcessEntities()
Generates entities from blocks before chunk processing.
public void generateBeforeProcessEntities(
    ChunkerColumn column,
    ChunkerChunk chunk
)
This method scans the chunk palette for blocks that need to generate entities (e.g., signs, chests).
generateBeforeWriteEntities()
Generates entities from blocks before chunk writing.
public void generateBeforeWriteEntities(
    ChunkerColumn column,
    ChunkerChunk chunk
)

Handler Management

getInterfaceHandlers()
Retrieves all type handlers that implement a specific interface.
public <T, U extends T> Collection<U> getInterfaceHandlers(
    Class<T> interfaceClass,
    TypeHandler<R, ChunkerEntityType, D, ? extends Entity> lastHandler
)
interfaceClass
Class<T>
The interface to find handlers for
lastHandler
TypeHandler
The main handler for the entity type
returns
Collection<U>
Collection of handlers implementing the interface

Abstract Methods

registerTypeHandlers()
Called during initialization to register entity type handlers.
protected abstract void registerTypeHandlers(Version version)
constructDataType()
Constructs the format-specific data container for an entity.
protected abstract D constructDataType(ChunkerEntityType type)
getKey()
Extracts the entity type key from format-specific data.
public abstract Optional<ChunkerEntityType> getKey(D input)

Bedrock Implementation

BedrockEntityResolver

Resolver for converting Bedrock entities between Chunker and NBT.
public BedrockEntityResolver(
    Version version,
    BedrockResolvers resolvers
)

Entity Type Key

Bedrock uses the identifier field for entity types:
@Override
public Optional<ChunkerEntityType> getKey(CompoundTag input) {
    return input.getOptionalValue("identifier", String.class)
        .flatMap(resolvers.entityTypeResolver()::to);
}

Registered Handlers

register(new BedrockEntityHandler());
register(new BedrockHangingEntityHandler());

Example Usage

BedrockEntityResolver resolver = new BedrockEntityResolver(version, resolvers);

// Read entity from NBT
CompoundTag entityNbt = // ... from world data
Optional<Entity> entity = resolver.to(entityNbt);

// Write entity to NBT
PaintingEntity painting = new PaintingEntity();
paint.setPositionX(100);
paint.setPositionY(64);
paint.setPositionZ(200);
Optional<CompoundTag> nbt = resolver.from(painting);

Java Implementation

JavaEntityResolver

Resolver for converting Java entities between Chunker and NBT.
public JavaEntityResolver(
    Version version,
    JavaResolvers resolvers
)

Entity Type Key

Java uses the id field for entity types:
@Override
public Optional<ChunkerEntityType> getKey(CompoundTag input) {
    return input.getOptionalValue("id", String.class)
        .flatMap(resolvers.entityTypeResolver()::to);
}

Registered Handlers

register(new JavaEntityHandler());
register(new JavaHangingEntityHandler());

Example Usage

JavaEntityResolver resolver = new JavaEntityResolver(version, resolvers);

// Read entity from NBT
CompoundTag entityNbt = // ... from world data
Optional<Entity> entity = resolver.to(entityNbt);

// Write entity to NBT
ItemFrameEntity itemFrame = new ItemFrameEntity();
itemFrame.setPositionX(100);
itemFrame.setPositionY(64);
itemFrame.setPositionZ(200);
itemFrame.setItem(new ChunkerItemStack(ChunkerVanillaItemType.DIAMOND));
Optional<CompoundTag> nbt = resolver.from(itemFrame);

Entity Handler Interfaces

Entity handlers can implement special interfaces for additional functionality:

DoNotProcessEntityHandler

Marks entities that should be removed before processing.
public interface DoNotProcessEntityHandler<T extends Entity> {
    boolean shouldRemoveBeforeProcess(ChunkerColumn column, T entity);
}

DoNotWriteEntityHandler

Marks entities that should be removed before writing.
public interface DoNotWriteEntityHandler<T extends Entity> {
    boolean shouldRemoveBeforeWrite(ChunkerColumn column, T entity);
}

UpdateBeforeProcessEntityHandler

Allows entity modification before processing.
public interface UpdateBeforeProcessEntityHandler<R, T extends Entity> {
    T updateBeforeProcess(R resolvers, ChunkerColumn column, T entity);
}

UpdateBeforeWriteEntityHandler

Allows entity modification before writing.
public interface UpdateBeforeWriteEntityHandler<R, T extends Entity> {
    T updateBeforeWrite(R resolvers, ChunkerColumn column, T entity);
    Class<?> getAdditionalHandledClass();
}

GenerateBeforeProcessEntityHandler

Generates entities from blocks before processing.
public interface GenerateBeforeProcessEntityHandler<T extends Entity> {
    Collection<ChunkerBlockType> getGenerateBeforeProcessBlockTypes();
    void generateBeforeProcess(
        ChunkerColumn column,
        int x, int y, int z,
        T entity,
        ChunkerBlockIdentifier block
    );
}

GenerateBeforeWriteEntityHandler

Generates entities from blocks before writing.
public interface GenerateBeforeWriteEntityHandler<T extends Entity> {
    Collection<ChunkerBlockType> getGenerateBeforeWriteBlockTypes();
    void generateBeforeWrite(
        ChunkerColumn column,
        int x, int y, int z,
        T entity,
        ChunkerBlockIdentifier block
    );
}

Working with Entities

Reading Entities from World Data

// Read all entities in a column
for (Entity entity : column.getEntities()) {
    // Process entity
    if (entity instanceof PaintingEntity painting) {
        ChunkerPaintingMotive motive = painting.getMotive();
        // ...
    } else if (entity instanceof ItemFrameEntity itemFrame) {
        ChunkerItemStack item = itemFrame.getItem();
        // ...
    }
}

Creating and Adding Entities

// Create a new painting entity
PaintingEntity painting = new PaintingEntity();
painting.setEntityType(ChunkerVanillaEntityType.PAINTING);
painting.setPositionX(100.5);
painting.setPositionY(64.0);
painting.setPositionZ(200.5);
painting.setMotive(ChunkerPaintingMotive.KEBAB);
painting.setDirection(Direction.NORTH);

// Add to column
column.getEntities().add(painting);

Entity Processing Pipeline

// Before processing (reading)
resolver.generateBeforeProcessEntities(column, chunk);
for (Entity entity : new ArrayList<>(column.getEntities())) {
    if (resolver.shouldRemoveBeforeProcess(column, entity)) {
        column.getEntities().remove(entity);
    } else {
        Entity updated = resolver.updateBeforeProcess(column, entity);
        if (updated != entity) {
            column.getEntities().remove(entity);
            column.getEntities().add(updated);
        }
    }
}

// Before writing
resolver.generateBeforeWriteEntities(column, chunk);
for (Entity entity : new ArrayList<>(column.getEntities())) {
    if (resolver.shouldRemoveBeforeWrite(column, entity)) {
        column.getEntities().remove(entity);
    } else {
        Entity updated = resolver.updateBeforeWrite(column, entity);
        if (updated != entity) {
            column.getEntities().remove(entity);
            column.getEntities().add(updated);
        }
    }
}

Unknown Entity Preservation

When preserveUnknownEntities is enabled, entities that don’t have handlers are preserved:
// Unknown entities are wrapped in UnknownEntity
if (entity instanceof UnknownEntity unknownEntity) {
    ChunkerEntityType originalType = unknownEntity.getEntityType();
    // Entity data is preserved for round-trip conversion
}

Common Entity Types

Supported Entities

Currently, the resolvers support the following entity types:
ChunkerVanillaEntityType.PAINTING
PaintingEntity
Paintings on walls with various motives
ChunkerVanillaEntityType.ITEM_FRAME
ItemFrameEntity
Item frames holding items
ChunkerVanillaEntityType.GLOW_ITEM_FRAME
GlowItemFrameEntity
Glowing item frames (Java only)

Entity Properties

Base Entity Properties

All entities have these properties from Entity class:
// Position
double positionX = entity.getPositionX();
double positionY = entity.getPositionY();
double positionZ = entity.getPositionZ();

// Entity type
ChunkerEntityType type = entity.getEntityType();

Hanging Entity Properties

Entities that hang on walls (paintings, item frames):
// Direction the entity faces
Direction direction = hangingEntity.getDirection();
hangingEntity.setDirection(Direction.NORTH);

Item Frame Properties

ItemFrameEntity itemFrame = (ItemFrameEntity) entity;

// Item in the frame
ChunkerItemStack item = itemFrame.getItem();
itemFrame.setItem(new ChunkerItemStack(ChunkerVanillaItemType.DIAMOND));

// Item rotation (0-7)
int rotation = itemFrame.getItemRotation();
itemFrame.setItemRotation(4);

Painting Properties

PaintingEntity painting = (PaintingEntity) entity;

// Painting motive
ChunkerPaintingMotive motive = painting.getMotive();
painting.setMotive(ChunkerPaintingMotive.KEBAB);
Entity support is currently limited to hanging entities (paintings and item frames). Support for more entity types can be added by implementing additional entity handlers.

Build docs developers (and LLMs) love