Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MerchantPug/1e97f9496064bcdc46f48ef139398aea to your computer and use it in GitHub Desktop.
Save MerchantPug/1e97f9496064bcdc46f48ef139398aea to your computer and use it in GitHub Desktop.

Written by MerchantPug 12/16/2023

Disclaimer: This migration guide is provided in Yarn mappings, if you're using different mappings and don't know what any of these are, I'd recommend looking up your mappings using Linkie

TL;DR - for Addon Devs

If you are making a datapack, this change exclusively is an internal one, you should not have to change anything about your datapack for it to function with this. If there is any incorrect behaviour as a result of this rewrite though, you're best to report it here.

If you're an addon dev, this change might affect you, as any code that references Item Actions will need to be updated.

  • Replace the type of direct Item Action references (Pair<World, ItemStack>) with Pair<World, StackReference>.
  • If you are registering any Item Actions, use the new ItemActionFactory class. In most cases, ItemActionFactory#createItemStackBased should work just fine. If you need to replace the stack's item with a different item, use the default constructor.
  • Some of your item action code may need re-adjusting to fit StackReferences, InventoryUtil has a few extra helper methods for getting StackReferences.

That's it. If you have any questions, feel free to talk in the Origins Discord's #addon-dev channel, I won't be there, so if you wish to reach out to me specifically regarding this change, please DM me on Discord, @merchantpug.

Why?

Apoli had a memory leak issue due to poor etiquite code that was used for Modify Enchantment Level and allowing certain actions to run on empty ItemStacks, this code basically caused a cache map to be bloated up with values, values which didn't remove upon entities being removed.

We felt that the best route was to rewrite item actions to use StackReference instead of ItemStack for two main reasons.

  1. It was a vanilla way of supporting setting items in an entity's inventory.
  2. We could deprecate the MutableItemStack interface, of which potentially caused issues with content where a stack's item type is used and is being cached, such as the Fabric Item Lookup API in some cases.

What is a StackReference?

StackReferences are pretty much how inventories can reference a slot with an item in them, and then replace that slot. It consists of two methods get and set, with both having custom implementation defined by the instance of the class.

Examples

For example, you may use StackReference#of(Lnet/minecraft/entity/LivingEntity;Lnet/minecraft/entity/EquipmentSlot;) to get and set the specified entity's item in the specified equipment slot.

Another example would be InventoryUtil#createStackReference, where it will basically hold a copy of the specified ItemStack, of which you are free to modify and use in other StackReference based code.

How it works now?

"Workable" empty ItemStacks are now only set through the modify_enchantment_level power type, or if the StackReference that's currently being worked on within an item action currently holds an empty ItemStack, they are then replaced with the global ItemStack#EMPTY once the entity has no modify_enchantment_level powers, or if the item action returns an empty stack.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment