Item Model Definitions¶
Item model definitions allow defining rules that are then used by the client to select a model for an item at runtime. These rules are constantly evaluated by the client, so the item model can change very dynamically based on the player's actions, such as holding a keybind, or the state of the item, such as its use duration.
Nova offers a DSL builder for creating item model definitions:
@Init(stage = InitStage.PRE_PACK)
object Items {
val EXAMPLE_ITEM = ExampleAddon.item("example_item") {
modelDefinition {
model = /* ... */
}
}
}
In this scope, you'll need to set the "root" model of the item. Your options here are:
model: A normal model, allows defining tints. You may want to use the shortcut functionbuildModelinstead.composite: A composite model, which allows rendering multiple models in the same space.condition: A model is selected based on a condition that is eithertrueorfalse.select: A model is selected based on a value, such as an enum or a string.rangeDispatch: A model is selected based on a number. If there is no exact match, the closest lower value is used.empty: An empty model- Various "special" models, that use hardcoded rendering logic.
There are also some shortcut functions available for generating rangeDispatch models: numberedModels, rangedModels
Models are nested, so you can have, for example, a select model that chooses another select model.
Refer to the KDocs for a full list of available functions and properties.
Model¶
This is the most basic model type. You will need this type as a leaf of all your models, as it is the only type that directly links to a model file. Additionally, this type also allows you to define tints.
model = model {
tintSource[0] = TintSource.CustomModelData(Color.WHITE, 0) // (1)!
model = { getModel("item/my_item") } // (2)!
}
- This sets
tintindex0 to read the color value 0 from theminecraft:custom_model_datacomponent. - This sets the model to
item/my_item. In the model selector scope, you have additional functionality available that can be used to generate models at runtime.
Composite¶
This model type allows you to render multiple models in the same space.
- Adds a model to the composite. You can either create a model like for the root model, or define a model selector lambda directly.
Condition¶
This model type allows you to choose a model based on a condition.
model = condition(ConditionItemModelProperty.KeybindDown(Keybind.LEFT)) { // (1)!
onTrue = buildModel { getModel("item/left") } // (2)!
onFalse = buildModel { getModel("item/not_left") }
}
- This condition checks if the keybind
LEFTis pressed. If it is, the modelitem/leftis used, otherwiseitem/not_left. buildModel { /* ... */ }is a shortcut formodel { model = { /* ... */ } }.
Select¶
This model type allows you to choose a model based on a value.
model = select(SelectItemModelProperty.ChargedType) { // (1)!
case[ChargedType.NONE] = { getModel("item/crossbow") }
case[ChargedType.ARROW] = { getModel("item/crossbow_arrow") }
case[ChargedType.ROCKET] = composite { /* ... */ }
}
- Selects over the value of the
minecraft:charged_projectilescomponent.
Range Dispatch¶
model = rangeDispatch(RangeDispatchItemModelProperty.Cooldown) { // (1)!
entry[0] = { getModel("item/my_item_ready") }
entry[0.5] = { getModel("item/my_item_half_ready") }
entry[1] = { getModel("item/my_item_not_ready") }
}
- Selects a model based on the item's remaining cooldown, scaled from
0(no cooldown) to1(full cooldown). You can add as many intermediate models as you want. The client will always render the one with the closest lower value.
Special¶
There are various special model types available. These use hardcoded rendering logic and are not achievable through regular model files.