In this lesson we'll be talking all about crafting. Crafts can come in many shapes and sizes, by default the largest we can make is a 3x3 grid. Using Replacements we can require an item in a recipe, but give it back to the player. If we want we can make recipes that have no shape, so the player can put the items at any location in the grid and get the output, this has some things to watch out for, which I'll cover in more detail later in the lesson. We can create crafts that take two of the same tools and merge them into one with less damage. Cooking and fuels are also both considered to be crafts, and will be covered at the end of this lesson.

Basic crafts always look something like this,

minetest.register_craft({ output = "mod:nodename #", recipe = { {"mod:nodename", "mod:nodename", "mod:nodename"}, {"mod:nodename", "mod:nodename", "mod:nodename"}, {"mod:nodename", "mod:nodename", "mod:nodename"} } })

Where mod:nodename is the name of the item being created and used in the recipe. The # in the output is the number of resulting items from the recipe. If left blank this defaults to one. A recipe can have blanks. Any of the recipe elements can be left blank, and if an entire row or column is empty you can simply omit it from the code, here are some examples.

minetest.register_craft({ output = "mod_1:first", recipe = { {"default:dirt", "default:dirt", "default:dirt"}, {"default:dirt", "default:dirt", "default:dirt"} } }) minetest.register_craft({ output = "mod_1:fake_diamond 3", recipe = { {"mod_1:first", "mod_1:first"}, {"mod_1:first", "mod_1:first"}, {"mod_1:first", "mod_1:first"} } }) minetest.register_craft({ output = "default:dirt 6", recipe = { {"", "", ""}, {"", "mod_1:fake_diamond", "mod_1:fake_diamond"}, {"", "mod_1:fake_diamond", "mod_1:fake_diamond"} } })

Launching Minetest and loading our world we'll find that we can put these recipes at any location in the crafting grid and get our output.

Blank spaces are not always ignored however, consider the following code. The top row of blanks will be ignored, and we'll be able to make our recipe in the upper two or lower two rows, but we will have to stagger the items.

minetest.register_craft({ output = "default:dirt 7", recipe = { {"", "", ""}, {"mod_1:fake_diamond", "mod_1:fake_diamond", ""}, {"", "mod_1:fake_diamond", "mod_1:fake_diamond"} } })

As you should have noticed by now our crafts can yield results from mods other than the their own. A few of these recipes have yielded dirt, and we could give output from any mod we want. It is important to include that mod in your depends file, or you'll end up with unknown items. What's an unknown item you ask, well lets go ahead and make one, it's simple to do. All we need to do is misspell the output for any of our crafts, how about changing the output on the last recipe we made.

minetest.register_craft({ output = "defaulat:dirt 7", recipe = { {"", "", ""}, {"mod_1:fake_diamond", "mod_1:fake_diamond", ""}, {"", "mod_1:fake_diamond", "mod_1:fake_diamond"} } })

The game will still load properly, but when we got to craft the item we'll get this unknown item node. We can take it from the result and place it in our inventory, and into chests or any other inventory, but when we try to place it in the world we'll get an error saying Item "defaulat:dirt" not defined. If we correct the output in the recipe our unknown items will still remain, the only way to get rid of them is to toss them in the trash. If we have the output correctly named, but it's an item from another mod, that isn't enabled we'll still get the unknown item, but if we ever enable the mod in the future the unknown items will turn into their respective items.

Most crafts will be simple like these examples, but what about something more advanced, such as replacements? As alluded to earlier in the lesson using replacements we can require an item in a craft recipe, but return it to the player after they've taken the craft result. The code is the same as usual, but there is an extra line added at the end which lists what the replacements are. Currently there is a lot of silly recipes, so I'm going to create something entirely new, using items from default.

Here's the code

minetest.register_craft({ output = 'default:gravel', recipe = { {"default:cobble", "default:pick_steel"} }, replacements = {{"default:pick_steel", "default:pick_steel"}}, })

We replace the pick with a pick, which might look odd, but when we craft this in game, and take our output we'll see that we still have a pick in the craft grid. This does introduce a little hack though, if our pick is damaged and we use it in the craft we'll get a pick back that has no damage. The same goes for any tool. The replacements can of course be used for things other than tools. The first mod that comes to mind that uses it is Columnia which uses a blueprint item in the crafts to make different column parts, and then returns the blueprint. The replacement can of course be a different item as well, we can even do multiple replacements as in the following code.

minetest.register_craft({ output = 'default:sand', recipe = { {"default:cobble", "default:pick_steel"} }, replacements = {{"default:cobble", "default:dirt"}, {"default:pick_steel", "default:pick_steel"}}, })

The replacements are just listed as pairs, the first item being the starting item, and the second item what it gets replaced with.

We can get even more advanced and do something like this.

minetest.register_craft({ output = 'default:sand', recipe = { {"default:cobble", "default:pick_steel", "default:cobble"} }, replacements = {{"default:cobble", ""}, {"default:pick_steel", "default:pick_steel"}, {"default:cobble", "default:dirt"}}, })

If your craft has multiple of the same node you can actually list several different replacements for each one, but it will only work correctly if you have just one item in each stack, so there is space in the crafting grid for the replacements to be placed. If you have stacks with more than one item the replacements will be lost on some of the items. Interestingly enough though if your replacements are all different input items, you can have stacks in the input slots and when you take resulting craft the replacements will be added to the players inventory. A great use for replacements would be harvesting grains, you could harvest a stalk, and then craft it to get the seeds, and hay as a replacement.

Shapeless crafts are interesting to work with, because they can easily cause conflicts with other crafts. To create a shapeless craft we just need to add the line type = "shapeless", to the top of the registration.

minetest.register_craft({ type = "shapeless", output = "default:sand", recipe = {"default:dirt", "default:dirt"}, })

Nothing much has changed, but any craft recipe that that uses two dirt nodes will now be uncraftable. If we launch our world we'll discover that we can no longer craft the first node, because it's recipe is two dirt blocks side by side. If you are going to use shapeless crafts be careful, and check your recipes to make sure you haven't accidentally made something impossible to craft. Unfortunately there is no tool to automate this process, and it can be hard to find conflicts. Shapeless crafts can be good for upgrading items, for example in default the wooden chest can be upgrade to a locked chest with an steel ingot. I'd suggest using shapeless crafts as infrequently as possible, but feel free to do as you'd like, just don't say you weren't warned.

Tool repair lets us change how much additional_wear is added or removed when we combine two tools in the crafting grid. This is game wide, so we can't change the amount of wear per tool. Minetest_game sets it up in the default mod with -.02 additional_wear which gives a slight gain when combining the tools. If you want to change that amount you just need to add the following code in your mod. Your mod will also have to depend on default, to be loaded after default is loaded, and to have your additional_wear amount override the value set in default. A negative value will provide extra uses whereas a positive value will remove uses from the resulting tool.

minetest.register_craft({ type = "toolrepair", additional_wear = -0.02, })

To make things cookable, or burnable we also use crafts. We chance the type to cooking and change from using a table for the recipe to a single item. Our output can still have multiple items if we'd like. By default it will take three seconds to cook an item, but that can easily be changed by adding the cooktime and a new length.

minetest.register_craft({ type = "cooking", output = "mod_1:first 2", recipe = "default:dirt", cooktime = 4, })

Things need to be able to burn so we can fuel the furnace, or any other item that can cook things, and to define that we register a craft with a type of fuel, add the item as the recipe and give it a burntime.

minetest.register_craft({ type = "fuel", recipe = "mod_1:fake_diamond", burntime = 7, })

Items can be fuels and also be able to be cooked to create something different. When being used in a furnace, or any other node that can burn or cook items, the node's code will determine whether the item is a fuel to burn, or a recipe to cook and act accordingly.

Crafts can also use groups in place of specific nodes in the recipe. I'll discuss this in the future when we talk about groups, as the only group we've mentioned so far is the oddly_breakably_by_hand group, and that's probably not a group you'd want to use in a recipe for anything.

That concludes this lesson, now on to the challenge. You should know how to create several types of recipes. Make one of each, patterned, shapeless, one using replacements, tool repair, a fuel, and a cookable item. Feel free to create new nodes or use nodes from other mods for the recipes and outputs. Make sure all of your crafts are working, try out your fuel and cooking recipes in a furnace.