Skip to content

Item Behaviors

In Nova, item logic is implemented via ItemBehaviors. There are some default behaviors available, but you can also create your own custom behaviors.

Default Item Behaviors

Default Item Behaviors

These are the default item behaviors that Nova provides:

Allows you to make a custom consumable item. Example:

val EXAMPLE_ITEM = registerItem("example_item", Consumable)
configs/example_item.yml
# The nutrition value this food provides.
nutrition: 4
# The saturation this food provides.
saturation: 0.3
# Whether the food can always be eaten, or only when hungry.
can_always_eat: false
# The time it takes for the food to be consumed, in ticks.
consume_time: 40
# The item stack that remains after the food is consumed.
remains: "minecraft:bowl"
# A list of effects to apply to the player when this food is consumed.
effects: []
Example Effect
effects:
# A level 1 speed effect that lasts 10 seconds.
- type: speed # (1)!
  duration: 200 # (2)!
  amplifier: 0 # (3)!
  ambient: true # (4)!
  particles: true # (5)!
  icon: true # (6)!
  probability: 1.0 # (7)!
  1. The type of the effect.
    A list of all effect types can be found here.
  2. The duration of the effect in ticks.
  3. The amplifier of the effect. An amplifier of 0 is a level 1 effect.
  4. Whether the effect is ambient or not.
    Default value: true
  5. Whether the effect has particles or not.
    Default value: true
  6. Whether the effect has an icon or not.
    Default value: true
  7. The probability of the effect being applied. Defaults to 1.0.

Allows you to make an item that can be equipped in a players armor slots.

val EXAMPLE_ITEM = registerItem("example_item", Wearable(ArmorType.CHESTPLATE, Sound.ITEM_ARMOR_EQUIP_DIAMOND))
configs/example_item.yml
armor: 8.0
armor_toughness: 3.0
knockback_resistance: 2.0

If you need some examples for the armor, armorToughness and knockback_resistance values, you can check out the Minecraft wiki.

You can also use this behavior with custom armor textures.

See Tools.

Makes an item damageable.

val EXAMPLE_ITEM = registerItem("example_item", Damageable)
configs/example_item.yml
# The maximum durability of the item.
max_durability: 200
# The damage the item takes when it is used to attack an entity.
item_damage_on_attack_entity: 1
# The damage the item takes when it is used to break a block.
item_damage_on_break_block: 2
# The repair ingredient that can be used in anvils.
repair_ingredient: "minecraft:paper"

Gives your item the ability to strip wood, logs, oxidization layers and wax.

val EXAMPLE_ITEM = registerItem("example_item", Stripping)

Gives your item the ability to create dirt paths.

val EXAMPLE_ITEM = registerItem("example_item", Flattening)

Gives your item the ability to extinguish campfires.

val EXAMPLE_ITEM = registerItem("example_item", Extinguishing)

Gives your item the ability to till dirt.

val EXAMPLE_ITEM = registerItem("example_item", Tilling)

Allows your item to be used as fuel in furnaces.

val EXAMPLE_ITEM = registerItem("example_item", Fuel)
configs/example_item.yml
burn_time: 20 # (1)!
  1. The burn time of the item in ticks.

Makes your item fire resistant.

val EXAMPLE_ITEM = registerItem("example_item", FireResistant)

Allows you to make an item that stores energy. This should mostly be used with other custom item behaviors, since there is no default implementation for consuming energy.

val EXAMPLE_ITEM = registerItem("example_item", Chargeable)

The above example uses the durability bar to display the item's charge. If you don't want this, you can disable this behavior:

val EXAMPLE_ITEM = registerItem("example_item", Chargeable(false))

The energy capacity can then be configured in the material config file:

configs/example_item.yml
max_energy: 100000

Custom Item Behaviors

You can create a custom item behavior by implementing the ItemBehavior interface.

There, you'll be able to override baseDataComponents, which are the default data components of NovaItems with that behavior.

Alternatively, you can also override defaultPatch, which is the default component patch that will be present on all item stacks of NovaItems with that behavior.

Vanilla material properties

Some functionality can not yet be achieved by using data components, as it is still bound to the vanilla item type. As such, you can specify VanillaMaterialProperties which will change the client-side item type.

Client-side item stack

To modify the client-side item, you can override modifyClientSideStack. The data of the client-side stack will not be stored in the world and is only intended for display purposes. Furthermore, the components of the client-side stack will not affect the tooltip, e.g. adding the DAMAGE component will not cause the damage value to be shown in the advanced tooltip. (Assuming advanced tooltips are handled by Nova via /nova advancedTooltips).

ItemBehaviorHolder and ItemBehaviorFactory

ItemBehaviorHolder is a sealed interface with two implementations: ItemBehavior and ItemBehaviorFactory, where ItemBehaviorFactory creates ItemBehavior instances based on a NovaItem instance. This allows you to create factories for your ItemBehaviors that read from the item's config file.

Example custom ItemBehavior with ItemBehaviorFactory
class MyBehavior(value: Provider<Int>) : ItemBehavior {

   private val value by value // (1)!

   companion object : ItemBehaviorFactory<MyBehavior> {

      override fun create(item: NovaItem): MyBehavior {
         return MyBehavior(item.config.entry<Int>("value"))
      }

   }

}
  1. Delegating to the obtained provider makes this property config-reloadable without any additional code.

Now, you could, for example, assign the same ItemBehaviorFactory to multiple items, while still accessing different configs.

@Init(stage = InitStage.PRE_PACK) // (1)!
object Items : ItemRegistry by ExampleAddon.registry {

    val EXAMPLE_ITEM_1 = registerItem("example_1", MyBehavior) // configs/example_1.yml
    val EXAMPLE_ITEM_2 = registerItem("example_2", MyBehavior) // configs/example_2.yml
    val EXAMPLE_ITEM_3 = registerItem("example_3", MyBehavior) // configs/example_3.yml

}
  1. Nova will load this class during addon initialization, causing the item fields to be initialized and your items to be registered.

Item Data

Data for Nova's ItemStacks can be stored in a NamespacedCompound, which serializes data using CBF.
You can retrieve the NamespacedCompound of an ItemStack by calling ItemStack.novaCompound. After updating it, you'll need to write it back to the ItemStack.

Alternatively, you can also read and write data using ItemStack.storeData and ItemStack.retrieveData, which access the NamespacedCompound for you.

NovaItems can also have default data stored in their NamespacedCompound, which can be applied using the defaultCompound property in a custom ItemBehavior.

Of course, you can also use Bukkit's persistent data container for data storage.