-
-
Notifications
You must be signed in to change notification settings - Fork 697
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Custom item API v2 #5189
base: master
Are you sure you want to change the base?
Custom item API v2 #5189
Conversation
FYI I believe that the plan for items on Bedrock itself is to eventually deprecate render offsets on items in favor of attachables/texture meshes, so we should probably note that in any documentation. Also as long as you're adding stuff, it might be nice to add some sort of a priority value at the top level of the mappings file for specifying the load order of files since I've seen a lot of cases where people want to separate the same item across files for organizational reasons, but cannot because it results in predicates being applied incorrectly. Otherwise I think the plan for the format is solid. Haven't reviewed the code yet since it sounds like that's still a WIP. |
I had a feeling that might be the case - maybe we should just mark the whole render offsets option as deprecated all together, telling users to use attachables/texture meshes instead? As for priority values, I've been working on automatically sorting predicates. For example, let's say you have 3 item definitions for the same item model: - one with predicate A Geyser would then automatically sort them from most predicates to least, so that it'll match them in this order: This way no matter the order you put predicates in the mappings, they'd always be checked in the right order so that the This worked pretty well until I got to range dispatch predicates - I made these sort by comparing their threshold value, and predicates with higher threshold values will be checked first. This doesn't always work properly however, for example when you have a definition with multiple range dispatch predicates checking for different properties with different thresholds. It might be a good idea to add an optional {
"type": "group",
"model": "geyser_mc:test_item",
"definitions": [
{
"bedrock_identifier": "geyser_mc:test_item_1",
"priority": 1,
"predicate": [
{
"type": "range_dispatch",
"property": "custom_model_data",
"threshold": 100.0,
"index": 0
},
{
"type": "range_dispatch",
"property": "custom_model_data",
"threshold": 50.0,
"index": 1
}
]
},
{
"bedrock_identifier": "geyser_mc:test_item_2",
"priority": 2,
"predicate": [
{
"type": "range_dispatch",
"property": "custom_model_data",
"threshold": 20.0,
"index": 1
},
{
"type": "range_dispatch",
"property": "custom_model_data",
"threshold": 30.0,
"index": 2
}
]
}
]
} This way the second custom item definition would be checked first. And yeah - code is definitely still WIP. |
# Conflicts: # core/src/main/java/org/geysermc/geyser/item/type/Item.java # core/src/main/java/org/geysermc/geyser/registry/type/ItemMapping.java # core/src/main/java/org/geysermc/geyser/translator/item/CustomItemTranslator.java # core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaCooldownTranslator.java
2b03c8f
to
7fabf0c
Compare
…nd better error messages, read nutrition and saturation values from mappings
# Conflicts: # core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java # core/src/main/resources/mappings
…s component verification
This PR adds a new format for mapping custom items.
This new format was necessary to incorporate the amount of changes made recently to items in Minecraft Java, primarily the introduction of new item components and item model definitions, adding a new predicate system. The new format is designed to be somewhat similar to the component system and item model definitions.
The currently existing format will be deprecated, but will continue to be usable. Mappings in the existing format will automatically be translated at runtime to the new format.
Along with introducing a new format for item mappings, this PR also cleans up the custom item registry populator a bit and makes use of default item components to get the properties of vanilla items.
Before going into the specification, here is some vocabulary used in custom items on Java and Bedrock:
assets/<namespace>/items/
resource pack directory. They decide which model a Java item should use based on a set of rules and item properties. Every Java item stores its item model definition in itsminecraft:item_model
item component, which can in term be overridden on an item stack by a datapack to use a custom item model definition defined in a resource pack.The new format
Currently, the new format looks somewhat like this:
The start of the format is similar to the current format. There is an
items
key, which is an object in which keys are Java items, and in which each value is an array of custom item definitions for that Java item, or an object specifying a group of such.Specifically, each value in the array can either look like this:
Which is a single custom item definition for a Java item model definition, or like this:
Which is a group of custom item definitions. All definitions in the group inherit the Java model definition of the group, if any (so, a group is not required to have a model, in which case the definitions in the group have to specify the model themselves). Definitions in a group are also allowed to be a group, and definitions in a group can also override the Java model definition of the group.
Note that, when the
type
key is not specified, it is defaulted todefinition
.The
bedrock_identifier
key of a custom item definition determines its identifier on Bedrock, which is also used in e.g. Bedrock attachables. If no namespace is given here, then thegeyser_custom
namespace is used. Every item definition is required to have a unique Bedrock identifier.Alongside these 3 keys, there are 4 more keys item definitions can have:
bedrock_options
components
predicate
predicate_strategy
priority
Custom item definition bedrock options
The
bedrock_options
key is an object that sets options for the item on Bedrock, that cannot be set using Java item components. Possible keys are:icon
: determines the icon to use for the item. If not set, the item's bedrock identifier is used,:
replaced with.
and/
with_
(for example,geyser_mc:a_cool_item
turns intogeyser_mc.a_cool_item
).allow_offhand
: if the item should be allowed in the offhand slot. Defaults totrue
.creative_category
: sets the item's creative category (for the recipe book). Can benone
,construction
,nature
,equipment
, oritems
. Defaults tonone
.display_handheld
: if the item should display handheld, like a tool or weapon. Defaults tofalse
.protection_value
: determines how many armour points should be shown when this item is worn. This is purely visual. Only has an effect when the item is equippable, and defaults to 0.render_offsets
: render offsets, similar to the existing format. This key is deprecated, as it is now preferred to use attachables rather than render offsets.texture_size
: the size of the texture on Bedrock. Defaults to16
. This key is deprecated, as it makes use of render offsets internally.tags
: Bedrock tags the item has, can be used in Molang.Custom item definition components
The
components
key defines properties for the item, in the Java item component format. It is expected that the item will always have these components when the custom item definition is used. Currently, the following components are supported:minecraft:consumable
: doesn't support consume particles/sounds.minecraft:equippable
: doesn't support the camera overlay or swappable properties.minecraft:food
minecraft:max_damage
minecraft:max_stack_size
minecraft:use_cooldown
minecraft:enchantable
minecraft:enchantable
component withslot=all
. This should, but does not guarantee, allow for compatibility with vanilla enchantments. Non-vanilla enchantments are unlikely to work.Some components, like
minecraft:rarity
,minecraft:enchantment_glint_override
, andminecraft:attribute_modifiers
are already automatically translated and don't need to be specified here.Custom item definition predicates
predicate
is either an object (single predicate) or an array of objects (multiple predicates). For each combination of a Java item and a Java item model definition, there can be one item definition without a predicate, and one or multiple definitions with a predicate. There can't be multiple item definitions with the same predicates for the same Java item and Java item model definition. If the Java item model definition is in theminecraft
namespace, there can't be an item definition without a predicate.Each predicate has a
type
and aproperty
key. Currently, there are 3 predicate types:condition
match
range_dispatch
The
condition
predicate type checks for a boolean property and returnstrue
if the property matches the expected value. It has 4 possible properties:broken
: if the item is broken (has only 1 durability point left).damaged
: if the item is damaged (not at full durability).unbreakable
: if the item is unbreakable.custom_model_data
: checks the item's custom model data flags. Defaults tofalse
.The
condition
predicate also has theexpected
key, which specifies if the property has to betrue
orfalse
for this predicate to betrue
. Defaults totrue
.The
match
predicate type checks for a text-like property and returnstrue
if it matches the given value. It has 4 possible properties:charge_type
: the item currently charged in the crossbow (in theminecraft:charged_projectiles
component). Can benone
,arrow
, orrocket
.trim_material
: the trim material (resource location) of this item.context_dimension
: the dimension (resource location) the player is currently in.custom_model_data
: fetches a string from the item's custom model data strings.The
match
predicate requires a value to be specified in thevalue
key.The
range_dispatch
predicate type checks for a numeric property and returnstrue
if it is above the specified threshold. It has 4 possible properties:bundle_fullness
: checks the item's bundle fullness. Returns the total stack count of all the items in a bundle (in theminecraft:bundle_contents
component).damage
: checks the item's damage value. Can be normalised.count
: checks the item's count. Can be normalised.custom_model_data
: checks the item's custom model data floats. Defaults to0.0
.The
range_dispatch
predicate has 3 extra keys, one of them required:threshold
: the threshold required to return true (required).scale
: the factor to scale the property value by before comparing it with the threshold. Defaults to1.0
.normalize
: if the property value should be normalized before scaling it and comparing it with the threshold. Defaults tofalse
, only works for certain properties.All predicates can also have an
index
key, which determines which index to use when using a custom model data property. Defaults to0
.Some may notice these predicates are similar to the ones possible in Java 1.21.4's item model definitions. I plan to possibly extend the current predicates. Some examples of how predicates can look:
There is also a
predicate_strategy
key, which can beand
oror
and defaults toand
. This was inspired by the advancement requirement strategies, and decides if all predicates (and
), or only one predicate (or
) of an item definition has to match for it to be used.Custom item definition sorting and priority
Custom item definitions are automatically sorted so that the definitions' predicates are checked in a correct order when translating items. Specifically, Geyser sorts custom item definitions like this:
This system ensures that in most cases, item definitions with predicates are checked in proper order, no matter which order they are put in the mappings. In the few cases that Geyser does not sort definitions correctly (that will most likely occur when using multiple
range_dispatch
predicates, or using them in combination with other predicates), thepriority
key can be used to specify which definitions should be checked first.This new format has a few key benefits over the current format:
Code changes unrelated to the API
To allow for matching trim materials and dimensions in custom item predicates,
JavaRegistry<T>
now stores its entries wrapped in aRegistryEntryData<T>
object, which stores the entry key and the entry object.TODOs
This PR still needs a bit of work. The one big thing left is support for non vanilla custom items. Other than that, here's a TODO list I've been working with:
Possibly main hand match propertynot possibleusing item,has component, cast fishing rod,selected bundle itemcondition propertiesConsumable component properties (sound, consume particles, etc.) if those are possibleMight be server side, checkTested, consume particles are done entirely client side, and the sound is only sent to clients other than the client consuming the item. Doesn't seem possible to emulate this to me.minecraft:tool
Java componentequippable
is set since Bedrock doesn't support armour with a stack size above 1, also validate other components (e.g. damage and stack size combination)registeredItemNames
may be identifiers,identifierToKey
method needs to go elsewhere,customItemName
is always the bedrock identifierAlthough the PR is not finished yet, the code is decently clean, and (especially the API module), somewhat well documented. Reviews are welcome!
Testing
Some testing has been done already with a lot of (relatively simple) custom items that make use out of components like
consumable
,equippable
anduse_cooldown
and use thecondition
andmatch
predicates. This seemed to work decent so far. Testing that still has to be done:minecraft:
item model with a predicateError handling(To do: add more here)