Item API provides a way to manipulate item properties on the client side without maintaining server-side state.
Like an onion, the item api has layers
Items can be described via json. I am too lazy to describe this format for now.
The API provides a way to register items. A custom item simply needs to implement an interface, which provides callbacks that allows you to render specific items. This allows you to:
- Render item names
- Render item lore
- Render other item properties
- Load/store custom persistent data with NBT API
A proper implementation of equals
and hashCode
is enough to enable caching. To disable caching, override isCachable
to return false.
Mixin Injection into ItemStack
the ResourceLocation
that corresponds to the custom item's identifier. On NBT load, we figure out the custom item id (by reading a tag). If no tag is present, we look at the default custom item registry. If that is not present, return and do nothing. We then pass additional nbt data to the interface specified above.
TODO: figure this out
When sending stuff to the client, we replace the item being sent with the rendered version. This is very similar to Polymer's (a fabric mod) behavior, which means we can borrow logic.
Purely from the architecture of this mod, we get a few free optimizations:
- Free compression of nbt data (both at runtime/memory and when persisted to disk) - the server doesn't store any "unnecessary" properties such as lore.
- This should also solve issues with nbt comparison taking a long time
- Fast-path virtual items (without hooking into protocollib)
Things to think about:
- Caching "rendered" items
- Perhaps we should cache serialized nbts instead, since that gives us fast packet serialization (maybe better than vanilla)
By minimizing the amount of data stored server-side, we naturally cover most applications of item updates (modifying attributes, lore, etc). In our current implementation:
ItemStack@1 -> ("Foo", lore_data, attribute_data, ...)
ItemStack@2 -> ("Foo", lore_data, attribute_data, ...)
ItemStack@3 -> ("Bar", lore_data, attribute_data, ...)
ItemStack@4 -> ("Bar", lore_data, attribute_data, ...)
However, with item index:
"monumenta:foo" -> ("Foo", lore_data, attribute_data, ...)
"monumenta:bar" -> ("Bar", lore_data, attribute_data, ...)
ItemStack@1 -> (id = "monumenta:foo")
ItemStack@2 -> (id = "monumenta:foo")
ItemStack@3 -> (id = "monumenta:bar")
ItemStack@4 -> (id = "monumenta:bar")
Since the source of truth is the item index, server-side item upgrade is free.
TODO