This week I’ve added the Orizoba Silkmoth, followers of the End’s Ītzpāpālōtl. These moths like cocoa beans and can be used to create silk. In order to get the feeding mechanic to work, I’ve had to refactor some of the Goals I wrote a long time ago.
All-Consuming Butterflies
The original ButterflyEatCropGoal used CropBlock.AGE to de-age a block when it was eaten by a Butterfly or Moth. This meant that the goal would only work with CropBlocks, essentially anything that had 7 stages of growth like Wheat. Since Cocoa Beans use a different Age Property, I needed to rewrite this class to support more blocks.
To do this, I added a helper method that would extract any property with the name "age":
@Nullable
private IntegerProperty getEdibleAgeProperty(BlockState state) {
for (Property<?> property : state.getProperties()) {
if (property instanceof IntegerProperty intProp && "age".equals(property.getName())) {
return intProp;
}
}
return null;
}
With this method in play, I could replace all references to CropBlock.AGE with a call to this method, and now the goal will work with any kind of block that grows over time: Mushrooms, Chorus Fruit, and more importantly Cocoa Beans.

Other than this I tidied up some of the logic for Butterflies leaving a block once it had finished eating, and renamed to to ButterflyConsumeGoal to reflect that it now works with more than just CropBlocks.
Feeding and Pollination
Of course, the other goal I needed to modify was ButterflyPollinateFlowerGoal, since that handles the Butterfly Feeder. I want players to be able to add Cocoa Beans to the Butterfly Feeders so they can feed the Orizaba Silkmoths alongside the other species. Mostly this was making some of the same fixes as for `ButterflyConsumeGoal, but I also added a lookup table for FLOWER_BUDS and split out the behaviour for pollinating flowers and eating from a feeder.

In hindsight, this should really have been two separate goals, as it is handling two completely different behaviours. In the future I’m going to rewrite this class so that it is two separate goals, and each can be activated under different conditions.
Food Blocks and Food Items
Up until now all Butterfly Food have been Item Blocks, meaning the Resource Location for the item and the block are the same. Unfortunately this isn’t the case for Cocoa. The Cocoa Block uses "minecraft:cocoa", whereas the Cocoa Beans Item uses "minecraft:cocoa_beans". This has led me to add a very hacky piece of code which I’m almost embarrassed to paste here:
/**
* Helper method for getting a food source item from a non-item block.
* @return The Resource Location of the food source item.
*/
public ResourceLocation getFoodSourceItem() {
if (foodSource.getPath().equals("cocoa")) {
return new ResourceLocation("minecraft:cocoa_beans");
}
return foodSource;
}
This code is problematic because it is both error prone and needs to be rewritten if I ever want to add other non-Item Blocks. So I also plan to change the Butterfly Data structure so that it has both a foodItem and a foodBlock as two separate properties. In this way, I’ll be able to use any Item or Block in the game as a food source for any butterfly. In most cases it will be the same block, but it will easily be expanded to others.

This will also ensure that the food item is listed correctly in the Butterfly Book if players wish to learn more about Butterflies, since they can look up both the block and the item location strings.
Shoutout
I want to give a thank you to a user named Spagles who submitted a Pull Request that fixed a networking bug I wasn’t even aware of. I’m grateful people want to help improve this mod, and anyone can help. You don’t have to be a coder, you can simply open a ticket to submit any bugs you’ve notice, or to add suggestions for new features.
