|
|
(33 intermediate revisions by 8 users not shown) |
Line 1: |
Line 1: |
− | Another guide is available:
| + | Luanti has a scripting '''API''', which is used to program games and mods, creating whole new experiences or extending existing ones. |
| | | |
− | <big>'''the [http://rubenwardy.com/minetest_modding_book/ Minetest Modding Online Tutorial Book] is a more complete and easier to understand guide in learning to mod Minetest.'''</big>
| + | The API is accessed using Lua, an easy-to-use programming language. |
| + | Version 5.1 of Lua is used, but many people run LuaJIT for greater performance. |
| | | |
− | -------------------------
| + | The only thing you will need is ''basic'' programming knowledge. |
| | | |
| + | == Documentation == |
| | | |
| + | === Tutorials === |
| + | The [https://rubenwardy.com/minetest_modding_book/ Luanti Modding Book] is a friendly introduction to Luanti modding and game creation, introducing you to various aspects of the API. |
| | | |
| + | It is recommended you start here, even if you are already apt at programming, to get a good understanding of how Luanti mods work and are structured. |
| | | |
| + | === Lua API Reference === |
| + | The official Lua API documentation is <code>lua_api.md</code>. It's available as [https://github.com/minetest/minetest/blob/master/doc/lua_api.md markdown] or [https://api.minetest.net/ HTML]. You can find the plaintext version in your Luanti installation, in the <code>doc</code> directory. |
| | | |
− | Minetest has a scripting '''API''' ('''A'''pplication '''P'''rogramming '''I'''nterface), which is used to program '''mods''' (short for "modifications") for the game, extending its features and adding new items.
| + | This is a concise description of the entire API, explaining functions, data structures, registration templates & more. The core developers of Luanti maintain it, changes going through a quality control process. |
| | | |
− | This API is accessed using an easy-to-use programming language called Lua.
| + | Any functions not listed here are subject to change and not guaranteed to be compatible across versions, though usually they are. |
| | | |
− | The only thing you will need is ''basic'' programming knowledge. If you don't have any programming experience, you can use [http://www.codecademy.com/tracks/javascript Codecademy] to learn. It will teach you the basics of programming (it is JavaScript, not Lua, but still helps). | + | === The Minetest-Docs Project === |
| + | A work-in-progress project is underway to create new, more detailed, documentation. They can be read from its [https://github.com/minetest/minetest_docs/ GitHub repo], contributions are greatly appreciated. |
| | | |
− | More specifically, the version of Lua is 5.1. [http://www.lua.org/manual/5.1/ Reference manual], [http://www.lua.org/pil/ book]
| |
| | | |
− | == Path of user data == | + | == Useful tools == |
| + | Here are some useful tools that most modders use when making Luanti mods: |
| | | |
− | See [[Installing_Mods]].
| + | * [https://code.visualstudio.com/ Visual Studio Code]/[https://vscodium.com/ VSCodium], powerful code editor with a [https://marketplace.visualstudio.com/items?itemName=GreenXenith.minetest-tools Minetest extension] available for code completion. |
| + | * [https://github.com/lunarmodules/luacheck luacheck], static analysis tool for Lua. See [https://rubenwardy.com/minetest_modding_book/en/quality/luacheck.html this modding book chapter] for more information on how to use it with Luanti. |
| | | |
− | == Modding basics == | + | == Other useful links == |
| + | * Check out [https://content.minetest.net/ ContentDB] to see mods that have been published by the community. |
| + | * Get mod help from the community: |
| + | ** [https://forum.minetest.net/viewforum.php?f=47 Forums] |
| + | ** [https://discord.gg/minetest Discord] |
| + | ** [https://matrix.to/#/#minetest:tchncs.de Matrix] |
| + | ** ...[https://www.minetest.net/get-involved/ more] |
| + | * Suggest a mod idea in the [https://forum.minetest.net/viewtopic.php?f=9&t=2434 mod request thread]. |
| | | |
− | === Types of objects in Minetest ===
| |
− |
| |
− | There are the three types of object that can be defined in Minetest. The type of the object is important as it plays a part in the properties of that object.
| |
− | * '''Node''' ([[minetest.register_node]]): A block from the world.
| |
− | * '''Tool''' ([[minetest.register_tool]]): A tool/weapon that can dig and damage things according to tool_capabilities.
| |
− | * '''Craftitem''' ([[minetest.register_craftitem]]): A miscellaneous item.
| |
− |
| |
− | === Mod packs and item names ===
| |
− |
| |
− | Each Node, Tool and Craftitem needs a unique name to identify it in the API.
| |
− |
| |
− | The name's format is like this: <code>modname:itemname</code>. In this case, the mod is called <code>modname</code> (name is preset by the folder name) and the block is called <code>itemname</code>. In this tutorial, we will make the node <code>tutorial:decowood</code>.
| |
− |
| |
− | For example, <code>default:dirt</code> is the unique name for dirt.
| |
− |
| |
− | == Mod folder structure==
| |
− |
| |
− | The following describes the folder structure of a mod. The only required file is <code>init.lua</code>
| |
− | <pre>
| |
− | mods
| |
− | |-- modname
| |
− | | |-- description.txt
| |
− | | |-- depends.txt
| |
− | | |-- init.lua
| |
− | | |-- mod.conf
| |
− | | |-- readme.md
| |
− | | |-- screenshot.png
| |
− | | |-- settingtypes.txt
| |
− | | |-- textures
| |
− | | | |-- modname_stuff.png
| |
− | | | \-- modname_something_else.png
| |
− | | |-- sounds
| |
− | | |-- media
| |
− | | \-- custom_data
| |
− | |
| |
− | \-- another_mod
| |
− |
| |
− | </pre>
| |
− | * <code>mods</code> — Path to Minetest's mods.
| |
− | * <code>modname</code> — The name of your mod.
| |
− | * <code>description.txt</code> — A description of your mod (used by mod managers). The first sentence should be less than 100 characters. It should be enough to describe the mod. Further information can be put into other sentences.
| |
− | * <code>depends.txt</code> — List of dependencies.<br>List of mods that have to be loaded before loading this mod. A single line contains a single modname.
| |
− | * <code>init.lua</code> — Main Lua script.<br>The main Lua script. Running this script should register everything it wants to register. Subsequent execution depends on Minetest calling the registered callbacks.
| |
− | * <code>mod.conf</code> — For now contains only "name = mod_name" but may contain many mod information in the future. See this [https://forum.minetest.net/viewtopic.php?f=47&t=14224 forum thread] for more information.
| |
− | * <code>readme.md</code> — Martkdown page describing and explaining your mod if you are using github.
| |
− | * <code>screenshot.png</code> — Screenshot of your mod (used by mod managers). It should be 3:2 with a minimum size of 300x200px.
| |
− | * <code>[[settingtypes.txt]]</code> — Mods settings displayed in the settings menu.
| |
− | * <code>textures</code>, <code>sounds</code>, <code>media</code> — Media files (textures, sounds, whatever).<br>These will be transferred to the client and will be available for use by the mod.
| |
− |
| |
− | See [https://forum.minetest.net/viewtopic.php?f=47&t=19589 modding standards forum thread] for up to date information about mod files.
| |
− |
| |
− | == Define a node ==
| |
− |
| |
− | We are going to make a mod that adds a special kind of wood that can only be used for decoration.
| |
− |
| |
− | First, create a folder called <code>tutorial</code> in the Minetest mods folder (see [[Installing Mods|installing mods]]).
| |
− |
| |
− | Next, create a file called <code>init.lua</code> and paste in the following:
| |
− | <source>
| |
− | minetest.register_node("tutorial:decowood", {
| |
− | tiles = {"tutorial_decowood.png"},
| |
− | groups = {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=3},
| |
− | })
| |
− | </source>
| |
− |
| |
− | You can download the image by right clicking [https://raw.github.com/Jeija/minetest-modding-tutorial/master/textures/tutorial_decowood.png tutorial_decowood.png] and then click save as.
| |
− |
| |
− | The function <source enclose="none">minetest.register_node(name, table)</source> is responsible for adding new blocks to the game. Nodes are blocks as well as torches, signs, etc.
| |
− |
| |
− | It takes 2 Parameters: The name of the new block <code>tutorial:decowood</code>, and a table containing the properties of the block.
| |
− |
| |
− | The name of the block MUST start with the mod name, followed by a colon, eg. <code>tutorial:</code>.
| |
− |
| |
− | In this example we define the following properties:
| |
− | * <code>tiles</code> — Sets the texture of the block; You can use only 1 texture or multiple textures, separated by commas <code>{"tex1.png", "tex2.png", …}</code>. The game checks for the texture files in ALL textures folders of the game.
| |
− | * <code>groups</code> — This sets attributes about the block including the time it takes to destroy the block, and the tool required. It also defines that the node will burn when is close to fire or lava.
| |
− |
| |
− | == Try it out ==
| |
− |
| |
− | Launch the game now, and notice that the mods are automatically loaded and compiled.
| |
− |
| |
− | This means when changing the code you simply have to "Exit to Menu" and "Start Game/Connect" again to try out the changes.
| |
− |
| |
− | Let's try out our first mod! Open the chat window in-game (press t) and type <code>/giveme tutorial:decowood 99</code>. This will add 99 blocks of the decorative wood to your inventory!
| |
− |
| |
− | :{{Template:Note|The "give" privilege is required for the <code>/give</code> and <code>/giveme</code> commands to work. In singleplayer you have this privilege by default. On servers a server admin has to execute <code>/grant player_name give</code>}}
| |
− |
| |
− | == Define a crafting recipe ==
| |
− |
| |
− | Minetest also uses different crafting recipes. Therefore it is important to know what crafting means and how to code it.
| |
− |
| |
− | Crafting means to create tools, blocks and other stuff. Minetest offers a 3 × 3 crafting grid by default with one output slot.
| |
− |
| |
− | A stone pickaxe can be made out of 2 sticks and 3 cobblestone:
| |
− | <pre>
| |
− | C C C <--- S = stick, C = stone group (cobblestone, stone, desert stone, …)
| |
− | S
| |
− | S
| |
− | </pre>
| |
− |
| |
− | Let's make a crafting recipe for the decorative wood.
| |
− |
| |
− | Just add this to your <code>init.lua</code> file:
| |
− | <source>
| |
− | minetest.register_craft({
| |
− | output = 'tutorial:decowood 2',
| |
− | recipe = {
| |
− | {'default:wood', 'default:wood', ''},
| |
− | {'default:wood', 'default:wood', ''},
| |
− | {'', '', ''},
| |
− | }
| |
− | })
| |
− | </source>
| |
− |
| |
− | The function <source enclose="none">minetest.register_craft()</source> registers a crafting process, it defines the recipe for something.
| |
− |
| |
− | It takes 1 parameter which is a table that contains 2 properties: (and an optional third)
| |
− | * <code>output</code> — which sets the outcome of the crafting process and recipe which is the actual recipe for the output.
| |
− | * <code>recipe</code> — must be a table with other tables inside. Every of the 3 tables defines another row of the crafting field. Every row contains 3 columns.
| |
− | * <code>type</code> — if you want to make it a furnace craft add <code>type="cook"</code>
| |
− |
| |
− | Let's define a cooking recipe to see how that works. This will allow the node to be placed in the top of a furnace which will convert it to another item. Fuel must be added to the bottom of the furnace for the craft to take effect.
| |
− | <source>
| |
− | minetest.register_craft({
| |
− | type = "cooking",
| |
− | recipe = "tutorial:decowood",
| |
− | output = "default:wood",
| |
− | })
| |
− | </source>
| |
− |
| |
− | Let's also define a fuel recipe. This will allow the node to be placed in the furnace to fuel cooking recipes.
| |
− | <source>
| |
− | minetest.register_craft({
| |
− | type = "fuel",
| |
− | recipe = "tutorial:decowood",
| |
− | burntime = 7,
| |
− | })
| |
− | </source>
| |
− |
| |
− | You can use the [https://forum.minetest.net/viewtopic.php?f=9&t=5831 craft recipe checker] when modding to check for typos.
| |
− |
| |
− | :Why are wooden planks not simply called <code>wood</code> but <code>default:wood</code>?
| |
− | :Indeed, The name of a node/tool/craftitem object '''must''' be <code>modname:name</code> (with two exceptions: <code>air</code> and <code>ignore</code> which are built-in). In this case, the mod is called <code>tutorial</code> (name is preset by the folder name) and the block is called <code>decowood</code>, so it's <code>tutorial:decowood</code>.
| |
− | :The <code>default</code> mod is the most important “mod” in Minetest, in fact Minetest itself is more like just a game engine, all the contents, materials, and other stuff are in several mods, like <code>default</code> (standard tools/blocks), <code>bucket</code> (Buckets: Lava/Water), and many more.
| |
− | :If you want to find out more about these mods and maybe use features they contain, just have a look in their init.lua!
| |
− | :Windows: <code>Minetest/games/minetest_game/</code>
| |
− | :GNU/Linux, run-in-place: <code>~/.minetest/games/minetest_game/</code>
| |
− | :GNU/Linux, non-run-in-place (such as a package): <code>/usr/share/minetest/games/minetest_game</code>
| |
− |
| |
− | == Define an ABM ==
| |
− |
| |
− | ABMs add actions to blocks. For instance, the tutorial-wood could become normal wood after a few seconds.
| |
− |
| |
− | Append this code to your <code>init.lua</code>:
| |
− | <source>
| |
− | minetest.register_abm({
| |
− | nodenames = {"tutorial:decowood"},
| |
− | interval = 30,
| |
− | chance = 1,
| |
− | action = function(pos)
| |
− | minetest.add_node(pos, {name="default:wood"})
| |
− | end,
| |
− | })
| |
− | </source>
| |
− |
| |
− | Try it out! It's really annoying to see all your decowood creations destroyed after 30 seconds, they simply become normal wood.
| |
− |
| |
− | ''But how does this work?'' The function <source enclose="none">minetest.register_abm()</source> registers an action for each block of the same type.
| |
− | * <code>nodenames = {"tutorial:decowood'}</code> means that the action is processed for each decowood block. You could also try <code>"default:stone"</code> instead of that to turn all stone blocks into wood.
| |
− | * <code>interval</code> = 30 means that the action is performed every 30 seconds. It starts counting at the beginning of the game. After 30 seconds all actions are processed, it doesn't matter when the block was placed. - This is not a per-block timer!
| |
− | * <code>chance</code> = 1 means that the probability of the action is 1:1, it happens in every case. A higher value means that it's less probable (eg. 1:2, 1:3, …).
| |
− | * <code>action = function(pos)</code> is the function that is actually performed.
| |
− |
| |
− | It contains the command <source enclose="none">minetest.add_node()</source>. This takes two parameters:
| |
− |
| |
− | First of all the position parameter (more information later) and also a table which defines the properties of the block, e.g. the name, the direction it faces. In this case the name is enough to define what block you can see.
| |
− |
| |
− | So let's assume we want to create a mod that makes junglegrass grow above every dirt-with-grass block. This should be a slow process, one dirt-with-grass block after the other should be grown over. This is what we do:
| |
− | <source>
| |
− | minetest.register_abm({
| |
− | nodenames = {"default:dirt_with_grass"},
| |
− | interval = 2,
| |
− | chance = 100,
| |
− | action = function(pos)
| |
− | pos.y = pos.y + 1
| |
− | minetest.add_node(pos, {name="default:junglegrass"})
| |
− | end,
| |
− | })
| |
− | </source>
| |
− |
| |
− | You should already know everything else but the line <code>pos.y=pos.y+1</code>. What is that for?
| |
− |
| |
− | To understand it, you should know what a [[position]] variable in Minetest is a table made up out of 3 values: <code>x</code>, <code>y</code> and <code>z</code>.
| |
− |
| |
− | <code>x</code> and <code>z</code> are forward/backward; left/right values. <code>y</code> is the up/down value. The player usually spawns near <code>0,0,0</code>.
| |
− |
| |
− | The line <code>pos.y = pos.y + 1</code> manipulates the position to 1 block above the dirt-with-grass node.
| |
− |
| |
− | There are some small other differences to our first abm. The interval is 1 in this case, but the chance (probability) is 100. Therefore the function is executed every second, but only in 1 of 100 cases. This makes your Minetest garden slowly been overgrown by junglegrass.
| |
− |
| |
− | == Where to go next ==
| |
− |
| |
− | Have a look at the [http://rubenwardy.com/minetest_modding_book/ Minetest Modding Online Tutorial Book] for more complete guide.
| |
− |
| |
− | Check out the [http://minetest.net/forum/viewforum.php?f=11 Mod Releases forum] to see mods that have been published by the community.
| |
− |
| |
− | Get mod help from the [https://forum.minetest.net/viewtopic.php?f=9&t=4668 modding questions thread].
| |
− |
| |
− | Suggest a mod idea in the [https://forum.minetest.net/viewtopic.php?f=9&t=2434 mod request thread].
| |
− |
| |
− | <!--== Credits and afterword ==
| |
− | ''Originally based on rubenwardy's version of Jeija's modding tutorial.''-->
| |
− |
| |
− | [[Category:Misc]]
| |
| [[Category:Modding API]] | | [[Category:Modding API]] |