Cleaning Out the Butterflies Backlog

During any development it’s inevitable that you introduce bugs or leave minor tasks behind. The Butterflies Mod is no exception. We have a list of small details that are incomplete, as well as some bugs we’ve picked up on while testing. This week we try to clear out that list.

Caterpillar Textures


Last time we implemented caterpillars, but didn’t quite finish them off. We wanted individual textures and models for each species. We now have a complete texture set for the caterpillars, so players can figure out what species they are before they form chrysalises.

We do still need to actually implement chrysalises, however…

We Bottled “Bottled It”


While testing the mod, we noticed that the Bottled It advancement was being unlocked when a player obtained random items. This obviously wasn’t correct, so we needed to figure out why it was happening.

It turns out that we had formatted the item criterion wrong in our JSON data. We had used an item property to specify our item IDs.

  "criteria": {
    "bottled_butterfly": {
      "trigger": "minecraft:inventory_changed",
      "conditions": {
        "items": [
          {
            "item": butterflies:bottled_butterfly"
          }
        ]
      }
    }
  },

What we actually needed was an array of items instead.

  "criteria": {
    "bottled_butterfly": {
      "trigger": "minecraft:inventory_changed",
      "conditions": {
        "items": [
          {
            "items": [
              "butterflies:bottled_butterfly"
            ]
          }
        ]
      }
    }
  },

The reason it seemed to work with other achievements is because every other advancement also relied on NBT data. Since our modded items were the only ones in the game with these specific NBT tags, the advancements didn’t unlock for other items that didn’t have these tags. This was the only advancement that didn’t use NBT data so far, which meant it basically unlocked any time our inventory changes.

Butterfly Egg Advancements


We forgot to add advancements for the butterfly eggs when we added that feature. By adding an extra couple of JSON files, players can now earn advancements for collecting butterfly eggs. It’s also making our custom advancement tree start to look like it has some real detail.

Bottle Textures


We implemented bottled butterflies, but in order to know what kind of butterfly was in the bottle, we had to hover the mouse over it and look at the item description. We have new textures now so that players can tell at a glance what species of butterfly each bottle holds.

Immortal Lava Butterflies


This was a weird bug we noticed early on. Bottled butterflies could be destroyed by lava, but this would also release the butterflies. Since these were placed butterflies and were invulnerable, the world could effectively be filled with immortal butterflies that never despawn. As cool as this sounds, this is clearly unintentional so needed to be fixed.

It turns out that when lava destroys a block, destroy() is not called. This means that the butterfly isn’t removed alongside the bottle. The solution is to override onRemove() instead.

    /**
     * Called when the block is replaced with another block
     * @param oldBlockState The original block state.
     * @param level The current level.
     * @param position The block's position.
     * @param newBlockState The new block state.
     * @param flag Unknown.
     */
    @Override
    public void onRemove(@NotNull BlockState oldBlockState,
                         @NotNull Level level,
                         @NotNull BlockPos position,
                         @NotNull BlockState newBlockState,
                         boolean flag) {
        super.onRemove(oldBlockState, level, position, newBlockState,flag);

        removeButterfly(level, position, Entity.RemovalReason.KILLED);
    }

    /**
     * Removes a butterfly for the specified reason.
     * @param level The current level.
     * @param position The block's position.
     * @param reason The removal reason.
     */
    private void removeButterfly(LevelAccessor level, BlockPos position, Entity.RemovalReason reason) {
        AABB aabb = new AABB(position);
        List<Butterfly> butterflies = level.getEntitiesOfClass(Butterfly.class, aabb);
        for(Butterfly i : butterflies) {
            i.remove(reason);
        }
    }

We use an Entity.RemovalReason parameter to specify how the entity is removed. If the block is destroyed by lava then the butterfly is KILLED. Otherwise it is simply DISCARDED, since the butterfly is still alive.

TODO: More Features!


With the backlog clear, it’s time to move on to the next feature. Next time we will look at implementing the chrysalis, and will finally complete the butterfly’s life cycle. Then we will finally be close to releasing the first version of this mod.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.