Items
Lesson 12.1
Time to add something new to the game: an item of your own. An item needs two parts: a registration in your script, so the game knows it exists, and assets, so it has a name and a picture.
Registering an item
cl.on("lifecycle.register", function()
cl.items.register{
id = "ruby",
creative_tab = "minecraft:ingredients",
vanilla_fallback = "minecraft:emerald",
}
end)
- Items are registered in the
lifecycle.registerevent, once, while the game starts. After that the list of items is frozen, and registering raises awrong_phaseerror. id = "ruby"becomesmy_mod:ruby: an id without a:gets your mod id in front. You can only register in your own namespace.creative_tabputs it into a creative inventory tab.vanilla_fallbackis the vanilla item that players without your mod see instead.
cl.items.register{ ... } is a function call with a table, the shortcut from part 1. It returns the registered entry; its id field is the full id, "my_mod:ruby".
Since registration only happens at startup, a new or changed item needs a game restart. Hot reload logs restart required and keeps the old one.
Item options
| Field | Default | Means |
|---|---|---|
id |
The item’s id. Required. | |
max_stack_size |
64 |
How many fit in one slot, 1 to 99. Use 1 for tools. |
creative_tab |
none | "minecraft:ingredients", "minecraft:tools_and_utilities", "minecraft:combat", "minecraft:food_and_drinks", "minecraft:building_blocks", … |
vanilla_fallback |
"minecraft:paper" |
What players without the mod see. |
copy_from |
none | A vanilla item to base this one on, when there is no fallback. |
behavior |
none | Your own code for using the item (below). |
Assets: name and picture
The game finds an item’s look by its id. For my_mod:ruby it needs these files:
assets/my_mod/
items/ruby.json which model to use
models/item/ruby.json the model
textures/item/ruby.png the picture, 16 x 16 pixels
lang/en_us.json the name
items/ruby.json points at the model:
{
"model": {
"type": "minecraft:model",
"model": "my_mod:item/ruby"
}
}
models/item/ruby.json says “a flat item with this texture”, the same as most vanilla items:
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "my_mod:item/ruby"
}
}
And the name goes into the language file. Item keys are item.<mod id>.<name>:
{
"item.my_mod.ruby": "Ruby"
}
These are the same files a resource pack uses, so everything you know about resource packs works here. A missing texture shows the purple and black checkerboard; a missing name shows the key.
Using it in code
Your item is a normal item now. Everything from Players works with it:
player:give("my_mod:ruby", 5)
if player:held_item().id == "my_mod:ruby" then
player:send_message("Shiny!")
end
Behaviour: when the item is used
behavior gives the item its own code. Right now an item can react to use: the player right-clicks with it in hand.
cl.on("lifecycle.register", function()
cl.items.register{
id = "heal_crystal",
max_stack_size = 16,
creative_tab = "minecraft:tools_and_utilities",
behavior = {
use = function(ctx)
local player = ctx.entity
player:set_health(20)
player:send_action_bar("You feel better.")
return "success"
end,
},
}
end)
use gets one table, ctx, with:
| Field | Means |
|---|---|
ctx.entity |
The player using the item. |
ctx.level |
The world it happens in. |
ctx.hand |
"main" or "off". |
ctx.stack |
The item stack being used. |
The return value says what happened:
"success": the use worked; the arm swings."consume": it worked, without the swing."fail": it was refused.nil(no return): your code did nothing, so the game handles the click as for the fallback item.
Unlike registrations, the behaviour’s code reloads: change the body of use, save, and the next right-click runs the new code.
An item can use itself up. ctx.entity:held_item(ctx.hand) is the live slot the item is in, so shrink takes one away, like eating an apple:
use = function(ctx)
local player = ctx.entity
player:set_health(20)
player:held_item(ctx.hand):shrink(1) -- one crystal is used up
return "success"
end,
Players has the other ways to take items.
Try it
Register an item my_mod:compass_stone with a stack size of 1 in the tools tab. When it is used, it tells the player their coordinates in the action bar, like x 12, y 64, z -30. Add the language entry too.
Show a solution
cl.on("lifecycle.register", function()
cl.items.register{
id = "compass_stone",
max_stack_size = 1,
creative_tab = "minecraft:tools_and_utilities",
vanilla_fallback = "minecraft:flint",
behavior = {
use = function(ctx)
local p = ctx.entity.pos
ctx.entity:send_action_bar(("x %d, y %d, z %d"):format(math.floor(p.x), math.floor(p.y), math.floor(p.z)))
return "success"
end,
},
}
end)
assets/my_mod/lang/en_us.json:
{
"item.my_mod.compass_stone": "Compass Stone"
}
Without a texture it shows the checkerboard, which is fine for testing. Add items/, models/item/ and textures/item/ files like the ruby’s when you have a picture.
Recap: register items in lifecycle.register with cl.items.register{ id = ... }, give them a model, texture and name under assets/<mod id>/, and add behavior.use for right-click code.