Backporting for Pain and Profit

I spent this week tidying up some little issues with the mod here and there. I had a couple of small requests and bug reports over Christmas which I added to my backlog. All of this is slowing my plans to even start working on the third release, but these little things are all improving the mod.

After fixing a bug reported regarding a missing texture, I went back to a comment left on my mod’s Curseforge page.

Of course, I thought that this would be too much work. Backporting and maintaining a mod for an earlier version would be complicated and take away too much time from developing new features that could be added to the mod.

Right?

How I Ported Butterflies to 1.19.2


We start, of course, by creating a new branch. Thanks to the latest gradle setup, starting a downgrade is as simple as changing a few numbers in your gradle.properties. I set everything up to use 1.19.2 of Minecraft, as well as the latest stable release of Forge for that version (in this case 43.3.0). I also set the pack format in pack.mcmeta to 9.

Errors Galore

I reload the gradle project, generate IntelliJ runs, and click “run client”. Then I waited for the game to start.

75 Errors

I wasn’t expecting it to be that easy. 75 errors isn’t bad though. I can probably get this working.

The first issue was down to the UI. GuiGraphics doesn’t exist in this version of Minecraft. Instead the screen code uses a PoseStack directly, making some extra calls into the RenderSystem to set up the shaders and textures first:

        this.renderBackground(poseStack);

        RenderSystem.setShader(GameRenderer::getPositionTexShader);
        RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
        RenderSystem.setShaderTexture(0, ButterflyTextures.BOOK);

        int i = (this.width - 192) / 2;
        this.blit(poseStack, i, 2, 0, 0, 192, 192);

Font rendering and setting up the close(x) widget were also slightly different. But since my screens were mostly copies of the vanilla books, it was easy to figure out how to fix these.

66 Errors

Next up, there was no Axis class in this version. I was using this to create quaternions. It was an extremely useful class, as my understanding of quaternions is terrible. Thankfully, they exist in the Vector3f class in 1.19, so it was just a case of changing which class I was referencing.

52 Errors

There is no built in registry for cat types. Thankfully all we need to do is switch to an enum value.

49 Errors

There were a lot of errors registering my custom leaves blocks. Block properties have changed a fair bit between 1.19 and 1.20, so my block registration was full of errors. Thankfully they just need to use the same properties as vanilla, so all I needed to do was chase down the code and copy/paste.

I’m planning a change on how eggs are planted in leaves in a future version which should allow eggs to work with leaves from any mod, using much less code.

The other thing I needed to do in this file was to remove the Cherry Leaves, since they are a 1.20 feature.

42 Errors

The LootParams class is called LootContext in 1.19. This one was easy.

36 Errors

In 1.19 the creative tab for an item was set using a tab property, rather than in response to an event during load.

    public ButterflyBookItem() {
        super(new Item.Properties().stacksTo(1).tab(CreativeModeTab.TAB_MISC));
    }

Honestly, I don’t know why this changed. Setting it as an item property like this is so much easier and cleaner. If anyone knows why they switched to an event for this, I’d love to know.

27 Errors

There were a lot of errors in the ButterflyCherryLeaves class, since Cherry Leaves don’t exist in 1.19. Another easy one to fix. I deleted the class.

8 Errors

The last few errors were because what was getLevel() in 1.19 was renamed to level() in 1.20. Trivial to fix this one.

0 Errors

And now I could run the game! Except not quite. It didn’t work the first time. But after reloading the gradle project again I managed to get the game running.

Data Packs Also Changed

I choose to create a new world to test this version of the game and….

If you were keen-eyed you may have noticed that I changed the pack format to “9”. I made a mistake. Pack format 10 is used in 1.19.2. Easy then!

I changed the pack format, ran the game, try to create a world and…

Ah. Maybe this isn’t so simple after all. I checked the debug output and foundout there were still a few problems with my data.

Firstly, I still had a model for cherry leaves in there. So I deleted it. Secondly, the biome modifiers for the butterflies referenced the Cherry Grove biome, which doesn’t exist in 1.19. So they had to be removed as well.

Finally, the loot table format has changed between 1.19 and 1.20, so all of my tree loot tables were using properties that don’t exist yet. For this I just copied the 1.19 loot tables from vanilla, since these are meant to behave in exactly the same way.

After these changes, I was able to create a new world. Finally I had 1.19.2 running the butterflies mod. Finally I could play it and see butterflies in an older version of Minecraft!

It Still Wasn’t Working

I ran around the world ready to test all the features. Initially I couldn’t see any butterflies. No matter, they probably just haven’t spawned yet. Then I spotted some, and there was a bit of a snag.

For some reason, Minecraft bases the distance it culls an entity based on its size. Since butterflies were small, they would pop in and out of view at short distances. This was even worse for caterpillars and chrysalises, which I couldn’t see at all no matter what I did. This is obviously better in 1.20, but I wonder if this is why bees are so big (and why fireflies were dropped)?

Anyway, I fixed this by overriding a method in the mod’s entities so they would still be visible from a larger distance.

    /**
     * Overridden so that butterfly entities will render at a decent distance.
     * @param distance The distance to check.
     * @return TRUE if we should render the entity.
     */
    @Override
    public boolean shouldRenderAtSqrDistance(double distance) {
        double d0 = this.getBoundingBox().getSize() * 10.0D;
        if (Double.isNaN(d0)) {
            d0 = 1.0D;
        }

        d0 *= 64.0D * getViewScale();
        return distance < d0 * d0;
    }

With this increased distance, they appear as they should in 1.19. I went through and tested other features of the mod. Everything seems to be working as well as in 1.20 now, so it’s time for another release!

I don’t know if I’ll support any other versions of Minecraft, or if I’ll keep maintaining 1.19.2. But it’s fun doing something nice for someone.