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.
Located at: com.hivemc.chunker.conversion.encoding.base.resolver.entity.EntityResolver
The resolvers used by this format (e.g., JavaResolvers, BedrockResolvers)
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
)
The resolvers used by this format
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)
The input entity data (e.g., NBT CompoundTag)
Optional specific entity class to convert to
The converted Chunker entity, or empty if not supported
from()
Converts a Chunker entity to format-specific data.
public Optional<D> from(Entity input)
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
)
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
)
The interface to find handlers for
The main handler for the entity type
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
Base Handlers
Specific Entities
register(new BedrockEntityHandler());
register(new BedrockHangingEntityHandler());
register(new BedrockPaintingEntityHandler());
register(new BedrockItemFrameEntityHandler());
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
Base Handlers
Specific Entities
register(new JavaEntityHandler());
register(new JavaHangingEntityHandler());
register(new JavaPaintingEntityHandler());
register(new JavaItemFrameEntityHandler());
register(new EmptyEntityHandler<>(
ChunkerVanillaEntityType.GLOW_ITEM_FRAME,
GlowItemFrameEntity.class,
GlowItemFrameEntity::new
));
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
Paintings on walls with various motives
ChunkerVanillaEntityType.ITEM_FRAME
Item frames holding items
ChunkerVanillaEntityType.GLOW_ITEM_FRAME
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.