Merge pull request #2 from rubenwardy/master

Pull Requests: English txt and new english html
master
Jeija 2012-09-04 07:42:34 -07:00
commit a6b4c2c27d
6 changed files with 835 additions and 272 deletions

4
README
View File

@ -1,4 +0,0 @@
This is a modding tutorial for minetest.
If noone else does it, the german one will be discontinued.
There is a German HTML version already, have a look at the html folder.

16
README.md Normal file
View File

@ -0,0 +1,16 @@
This is a modding tutorial for minetest.
If no-one else does it, the german one will be discontinued.
View tutorial online at: tinyurl.com/mt-tut
ENGLISH
=======
raw text) mtmoddeven.txt
webpage) html/englishEN.html
GERMAN
======
raw text) mtmoddev.txt
webpage) html/germanDE.html

BIN
html/download.zip Normal file

Binary file not shown.

447
html/englishEN.html Normal file
View File

@ -0,0 +1,447 @@
<html>
<head>
<title>Beginners Guide to Minetest Modding</title>
<link rel="stylesheet" type="text/css" href="stylesheet.css" />
</head>
<body>
<table width="100%" bgcolor="#FFFFBB">
<tr>
<td width="80"><img src="1.png" width=80 alt="Minetest Logo" /></td>
<th><center><h1>Minetest-c55: Modding in Lua</h1><center></th>
<td width="100"><a href="download.zip">Download Resources</a></td>
</tr>
</table>
<h1>CONTENTS</h1>
<h2>The Basics</h2>
<ul>
<li><a href="#intro">Introduction</a></li>
<li><a href="#chap1">Chapter 1</a> - Modding Basics and Required understanding</li>
</ul>
<h2>Part One: Declaring and Crafting Nodes</h2>
<ul>
<li><a href="#chap2">Chapter 2</a> - Defining a node</li>
<li><a href="#chap3">Chapter 3</a> - Setting up a craft recipe</li>
</ul>
<h2>Part Two: ABMs</h2>
<ul>
<li><a href="#chap4">Chapter 4</a> - ABM Basics and the Position Variable</li>
<li>more comming soon</li>
</ul>
<h2>Part Three: Lua Files and Debuging</h2>
<ul>
<li><a href="#include">Chapter #</a> - Including LUA Files</li>
<li><a href="#chap_print">Chapter #</a> - Exceptions, Bugs, and the print function</li>
</ul>
<h1>The Basics</h1>
<h2><a name="intro">Introduction</a></h2>
<table>
<tr>
<td>
<img src="2.png" height=200 alt="Screenshot" />
</td>
<td>
<p><a href="http://minetest.net">Minetest-c55</a> is a Minecraft clone, developed by the Finnish programmer 'celeron55' and contributors.</p>
<p>Minetest has a ScriptAPI (Applictation Programming Interface), which is used to program Mods (Modifications) for the game, extending its features and adding new items.</p>
<p>This ScriptAPI is accessed using an easy-to-use programming langauge called Lua.</p>
<h3>Requirements</h3>
<ul>
<li>Basic Programming Knowledge, ideally in the Lua Language (<a href="#learntocode">learn</a>)</li>
</ul>
</td>
</tr>
</table>
<h2><a name="chap1">Chapter 1 - Modding basics</a></h2>
<h3>Types of objects in Minetest</h3>
Here are the three types of items you can define in Minetest:
<ul>
<li>Node (register_node): A Block from the world</li>
<li>Tool (register_tool): A tool/weapon that can dig and damage things according to tool_capabilities</li>
<li>Craftitem (register_craftitem): A miscellaneous item</li>
</ul>
The type of the object is important as it plays a part in the properties of that object.
<h3>Mod packs and item names</h3>
<p>In minetest, each node, tool and item needs a unique name to identify it in the api.<br />
The name's format is like this:</p>
<p><code>
modname:itemname
</code></p>
In this case, the mod is called 'modname' (name is preset by the folder name)
and the block is called 'itemname', so it's tutorial:decowood.<br />
so for example, default:dirt is the unique name for dirt.
<h3>Creating a mod</h3>
<div id="step">1) Create a new folder with the name of your mod in the mod folder</div>
<p>
<table>
<tr bgcolor="#FCFCFC"><td>
Linux Systemwide: <i>~/.minetest*/usermods/</i><br /><br />
Windows + Linux Run-in-place: <i>minetest*/mods/minetest</i>
</td></tr>
<tr bgcolor="#F0F0F0"><td>
minetest* The place where minetest was installed/extracted to.
</td></tr>
</table>
</p>
<div id="step">2) In the new folder, create a file called 'init.lua'. This is the file that will contain the source code for the mod.</div>
<p><table bgcolor="#FFFFCC">
<tr><td><center>
To do this on Windows, use WordPad.<br />Click file>save as, dropdown to all files, and type 'init.lua' in the file name box.<br />
<br />Or you can use a lua compatible editor, a few examples: 'Context', 'luaedit', 'Geany (linux)', 'Bluefish (linux)'<br /><br />
</center>
</td></tr>
<tr><th>
<font color="#FF0000">WARNING: DO NOT USE NOTEPAD</font>
</th></tr>
</table></p>
<div id="step">3) Next make another sub folder called 'textures'. This is where you will place the textures</div>
<h1>Part One: Declaring and Crafting Nodes</h1>
<h2><a name="chap2">Chapter 2: Defining a node</a></h2>
We are going to make a mod that adds a special kind of wood that can only be used for decoration.<br />
For this, create a new mod called 'tutorial' using the method described in Chapter 0.
<h3>Registering the decowood node</h3>
<div id="step">1) copy-paste this into 'init.lua':</div>
<p><code><pre>
minetest.register_node("tutorial:decowood", {
tile_images = {"tutorial_decowood.png"},
groups={choppy},
})
</pre></code></p>
<div id="step">2) Copy the file 'tutorial_decowood.png' supplied with this Document to the textures folder in the mod.</div>
<br />
Try it) 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.
<br />
Let's try out our first mod! Open the chat window ingame (press t) and enter "/giveme tutorial:decowood 99" (Without "" of course). This will add 99 blocks of the decorative wood to your inventory!
<p><table bgcolor="#FFFFCC">
<tr><td><center>
The "give" privilage is required for the /giveme command to work<br /><br />
To grant yourself the "give" privilage, go to worlds/gamename/auth.txt and open it.<Br />
Add ",give" after "shout,interact" to make it "shout,interact,give"<br />
</center></td></tr>
</table></p>
<h3>Let's have a look at the source code:</h3>
<p>The function minetest.register_node(name, table) is responsible for adding new blocks to the game (node=block, but also torches, rails, ...)<br />
It takes 2 Parameters: The name of the new block ("tutorial:decowood", the string before : MUST be the name of the mod folder) and a table with several properties of the block.</p>
<p>In this case we use 2 properties:</p>
<ul>
<li>tile_images: Sets the texture of the block; You can use only 1 texture or multiple textures,
seperated by commas {"tex1.png", "tex2.png", ...}. The game checks for the texture files in ALL textures folders of the game.</li>
<li>group: This sets the time it takes to destroy the block, and the tool required <a href="http://minetest.net/wiki/doku.php?id=roadmap:digging_time_groups">See more</a></li>
</ul>
<!--You could also use minetest.digprop_woodlike(1.5) which makes destruction with axes faster.-->
<h2><a name="chap3">Chapter 3 - Crafting</a></h2>
<h3>What is crafting?</h3>
<p>Crafting does not only play an important role in Minecraft, Minetest also uses different crafting recipes. Therefore it is important to know what crafting means and how to code it!<br />
<p>Crafting means to creating Tools, Blocks and Other Objects.<br />
In minetest you have a 3x3 crafting area by default with a 1x1 output field.</p>
<p>For example, a stone pickaxe can be made out of 2 Sticks and 3 Cobblestones:<br />
<p><img src="3.png" alt="The craft recipe for a stone pick-axe" /></p>
<br />
S=Stick C=Cobblestone; Looks quite logic, doesn't it?
</p>
<h3>Lets make a recipe for our decowood mod</h3>
So let's make a crafting recipe for the decorative wood of Chapter 0!<br />
<div id="step">Just append (add) this to your init.lua file:</div>
<p><code><pre>
minetest.register_craft({
output = '"tutorial:decowood" 2',
recipe = {
{'default:wood', 'default:wood', ''},
{'default:wood', 'default:wood', ''},
{'', '', ''},
}
})
</pre></code></p>
The function minetest.register_craft() registers a crafting process, it defines the recipe for something.<br />
<p>
It takes 1 parameter which is a table that contains 2 properties: (and an optional third)<br />
<ol>
<li>output - which sets the outcome of the crafting process and recipe which is the actual recipe for the output.</li>
<li>recipe must be a table with other tables inside.<br />
Every of the 3 tables defines another row of the crafting field. Every row contains 3 columns.<br />
In this case The crafting recipe is like this:<br /><p><img src="4.png" alt="The craft recipe for our decowood" /></p></li>
<li>[optional] type - if you want to make it a furnace craft add type="cook" before the "output" property</li>
</ol>
</p>
Easy, isn't it? You may also try out some other combinations!<br />
<h3>What is the mod "default"?</h3>
<p>So what is default? 'default' is the most important "mod" of minetest, in fact minetest itself is more like just a game engine,
all the contents, materials, and other stuff are in several mods, like 'default' (standard tools/blocks), 'bucket' (Buckets: Lava/Water),...</p>
If you want to find out more about these mods and maybe use features they contain, just have a look in their init.lua!</br />
<p><table bgcolor="#FFFFCC">
<tr><td><center>
For Windows & Linux run-in-place these mods are in <i>minetest/games/minetest_game/</i><br /><br />
For Linux systemwide installation, these mods are in <i>/usr/share/minetest/games/minetest_game</i>
</center></td></tr>
</table><p>
<h2><a name="chap4">Chapter 4: ABMs</a></h2>
ABMs stands for "Active Block Modifiers" and they add actions to blocks. For instance, the tutorial-wood could become normal wood after a few seconds.<br />
<div id="step">Append this code to your init.lua:</div>
<p><code><pre>
minetest.register_abm(
{nodenames = {"tutorial:decowood"},
interval = 30,
chance = 1,
action = function(pos)
minetest.env:add_node(pos, {name="default:wood"})
end,
})
</pre></code></p>
Try it out! It's really annoying to see all your decowood creations destroyed after 30 seconds, they simply become normal wood.<br />
<p>But how does this work?<br />
The function minetest.register_abm registers an action for each block of the same type.</p>
<p>nodenames = {"tutorial:decowood'} means that the action is processed for each decowood block.</p>
<p>You could also try "default:stone" instead of that to turn all stone blocks into wood.</p>
<p>interval = 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.</p>
<p>This is not a per-block timer!</p>
<p>chance = 1 means that the probability of the action is 1:1, it happens in every case.<br />
A higher value means that it's less probable.</p>
<p>action = function(pos) is the function that is actually performed.</p>
<p>It contains the command minetest.env:add_node. More about it in the next section<br />
<h3>minetest.env:add_node</h3>
<p>This is a function that is used to add/replace a node the given place</p>
<p>minetest.env:add_node has 2 parameters.
<uL>
<li>The position parameter (more information later)<br />
<li>A table which defines the properties of the block, e.g. the name, the direction it faces, ...<br /><br />
</ul>
In this case the name is enough to define what block you can see.
</p>
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:<br />
<p><code><pre>
minetest.register_abm(
{nodenames = {"default:dirt_with_grass"},
interval = 1,
chance = 100,
action = function(pos)
pos.y=pos.y+1
minetest.env:add_node(pos, {name="default:junglegrass"})
end,
})
</pre></code></p>
<p>You should already know everything else but the line "pos.y=pos.y+1".</p>
<h3>The Position Variable</h3>
To understand the position variable, you need to know that in 3d space, positions are determind by three co-ordinates: x,y,z<br />
The player usually spawns near 0,0,0.<br />
<p>The line pos.y=pos.y+1 manipulates the position to 1 Block above the dirt-with-grass node.</p>
<p>There are some small other differences to our first abm.<br />
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.
<br />This makes your minetest garden slowly been overgrown by junglegrass.</div>
<h1>Part Three - Lua Files and Debugging</h1>
<h2><a name="include">Chapter # - Including Files</a></h2>
<h3>The dofile function</h3>
Sometimes you have so much code, a single init.lua file is too hard to maintain.
<p>
But there is a solution! <code>dofile(minetest.get_modpath("tutorial").."/anotherfile.lua")</code> will tell Minetest to look for anotherfile.lua in the same folder as init.lua, and load its contents.
</p>
<h2><a name="chap_print">Chapter # - Debugging</a></h2>
<h3>Types of errors and Bugs</h3>
As with most programming, when you develop you tend to get what are called "bugs" and errors, which are basically human mistakes.<br />
There are three types of bugs/errors
<p><ul>
<li>Compile Time Errors - These occur when Minetest is loading the mods, and are caused by syntax errors (a simple mistake like leaving a "}" out)</li>
<li>Runtime Errors - These occur while the game is being played, and often crash the game. (eg: mod "modname:blockname" is not defined)</li>
<li>Runtime Bugs - These bugs cause the mod not to work as planned</li>
</ul></p>
<h3>Avoiding Syntax Mistakes</h3>
To help avoid syntax mistakes, make sure your code is easy to read.
<p>
<table bgcolor="#FFFFCC">
<tr><td>
Which one of these codes is easier to read?
<p>
<code><pre>
minetest.register_abm(
{nodenames = {"default:dirt_with_grass"},
interval = 1,
chance = 100,
action = function(pos)
pos.y=pos.y+1
minetest.env:add_node(pos, {name="default:junglegrass"})
end,
})
</pre></code>
</p>
<p>
<code><pre>
minetest.register_abm({nodenames = {"default:dirt_with_grass"},interval = 1,chance = 100,
action = function(pos)
pos.y=pos.y+1
minetest.env:add_node(pos, {name="default:junglegrass"})
end,
})
</pre></code>
</p>
</td></tr>
</table>
</p>
Also you should check your work and put comments in
<p>
<code>
pos.y=pos.y+1 --This line increases the position's y axis by 1
</code>
</p>
<h3>Avoiding Runtime Mistakes</h3>
<table bgcolor="#FFFFCC">
<tr><td><p>
The Console is the black window with writing in that appears when Minetest runs.</p>
</td></tr>
</table>
<p>LUA has a function called "print" and it displays a message to the console.</p>
<p>
<code>
print("message to send")
</code>
</p>
You should the print function so you know how far Minetest gets in a program.<br />
<p>
<table bgcolor="#FFFFCC">
<tr><th>Why use <u>print</u></th></tr><tr><td>
For example, you have a mistake in the code:
<p>
<code>
<pre>
check_something(1)
function check_something(value)
if value=0 then
print("it ends up here")
else
print("but you are certern that value=1")
end
end
</pre>
</code>
</p>
The aboves Runtime bug was caused by a single "=" instead of double "==", and so instead of checking if value was equal to 0, it set it to 0 resulting in true<br />
And so having print helps point out your mistake.
</td></tr>
</table>
</p>
<h1>Apendix</h1>
<h2><a name="learntocode">Learn to code</a></h2>
Don't have any knowledge? Use the following to learn:
<ul>
<li><a href="http://codecademy.com">Codecademy</a> -Learn the basics of programming (it is Javascript (not Java) but still helps)</li>
<li>Internet Search (google,yahoo) lua tutorials</li>
</ul>
<h2>Credits and Afterword</h2>
<p>This is Jeija's modding tutorial Version 20120823,
<br />Updated, Rewriten and Reformated for english by "Rubenwardy".<br />Html coded by Rubenwardy.</p>
<p>Check for new version at <a href="http://www.github.com/Jeija/minetest-modding-tutorial">GitHub</a>.</p>
<p>See <a href="https://dl.dropbox.com/u/82668184/Moddinghelper.zip">InfinityProject's Moddinghelper</a></p>
<p>For more advanced (and often cryptic) information about minetest modding have a look at this reference:
<a href="https://github.com/celeron55/minetest/blob/master/doc/lua_api.txt">Lua_api.txt</a></p>
<p>For generic modding questions or specific questions, feel free to ask in the minetest forum:
minetest.net/forum</p>
<p>For questions about this tutorial, ask in the thread for this tutorial:
minetest.net/forum/...</p>
<p>Thanks you for reading! Good luck in creating your amazing dream mod!</p>
</body>
</html>

37
html/stylesheet.css Normal file
View File

@ -0,0 +1,37 @@
body
{
font-family:"Arial",arial,arial;
}
h1
{
color:black;
text-align:left;
font-size:20pt;
}
h2
{
color:black;
text-align:left;
font-size:18pt;
text-decoration:underline;
}
h3
{
color:0000BB;
text-align:left;
font-size:12pt;
}
#step
{
color:#BB0000;
font-size:12pt;
}
#help
{
background-color:#FFFFCC;
}

View File

@ -1,269 +1,336 @@
Minetest-c55: Modding in Lua
Introduction
============
Minetest-c55 (Website: minetest.net) is a Minecraft clone, developed by the Finnish programmer 'celeron55' and contributers.
Minetest has a ScriptAPI (Applictation Programming Interface), which is used to program Mods (Modifications) for the game, extending its features and adding new items.
This ScriptAPI is accessed using an easy-to-use programming langauge called Lua.
Requirements:
=============
Basic Programming Knowledge, at best in Lua Language
--- Don't have any knowledge? Use the following to learn:
-------- codecademy.com -Learn the basics of programming (it is Javascript (not Java) but still helps)
-------- Internet Search (google,yahoo) lua tutorials
Chapter 0: Creating a mod
===========================
For creating a minetest mod you have to create a new folder with the name of your mod in the mod folder
-----------------------------------------------------------------
| Linux Systemwide: ~/.minetest*/usermods/ |
| |
| Windows + Linux Run-in-place: minetest*/mods/minetest |
|---------------------------------------------------------------|
| * The place where minetest was installed/extracted to. |
-----------------------------------------------------------------
In the new folder, create a file called 'init.lua'. This is the file that will contain the source code for the mod.
----------------------------------------------------------
| To do this on Window, use WordPad. Click file>save as |
| dropdown to all files, and type 'init.lua' in the file |
| name box. |
| Or you can use a lua compatible editor such |
| as 'context' WARNING: DO NOT USE NOTEPAD |
---------------------------------------------------------
Then make another sub folder called 'textures'. This is where you will place the textures
Additionally, create a file called 'init.lua'. This is the file that contains the source code of your mod.
Chapter 1: Your first mod!
==========================
We are going to make a mod that adds a special kind of wood that can only be used for decoration.
For this, create a new mod called 'tutorial' using the method described in Chapter 0.
Step 1) copy-paste this into 'init.lua':
----------------------------------------------------
| Code |
----------------------------------------------------
minetest.register_node("tutorial:decowood", {
tile_images = {"tutorial_decowood.png"},
material = minetest.digprop_constanttime(1),
})
----------------------------------------------------
| end of Code |
----------------------------------------------------
Step 2) Copy the file 'tutorial_decowood.png' supplied with this Document to the textures folder in the mod.
Try it) 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 ingame (press t) and enter "/giveme tutorial:decowood 99" (Without "" of course). This will add 99 blocks of the decorative wood to your inventory!
--------------------------------------------------------------------------
| HELP TIP |
|------------------------------------------------------------------------|
| The "give" privilage is required for the /giveme command to work |
| To grant yourself the "give" privilage, go to worlds/gamename/auth.txt |
| And add ",give" after "shout,interact" to make it "shout,interact,give"|
--------------------------------------------------------------------------
-----------------------------------------
| Let's have a look at the source code: |
-----------------------------------------
The function minetest.register_node(name, table) is responsible for adding new blocks to the game (node=block, but also torches, rails, ...) .
It takes 2 Parameters: The name of the new block ("tutorial:decowood", the string before : MUST be the name of the mod folder) and a table with several properties of the block.
In this case we use 2 properties:
tile_images: Sets the texture of the block; You can use only 1 texture or multiple textures,
seperated by commas {"tex1.png", "tex2.png", ...}. The game checks for the texture files in ALL textures folders of the game.
material: This sets the time it takes to destroy the block. In this case (minetest.digprop_constanttime(1)) it is a constant time of 1 second.
You could also use minetest.digprop_woodlike(1.5) which makes destruction with axes faster.
Chapter 2: Crafting!
====================
Crafting does not only play an important role in minecraft, minetest also uses different crafting recipes. Therefore it is important to know what crafting means and how to code it!
Crafting means to creating Tools, Blocks and Other Objects.
In minetest you have a 3x3 crafting area by default with a 1x1 output field.
For example, a stone pickaxe can be made out of 2 Sticks and 3 Cobblestones:
C C C
S
S
S=Stick C=Cobblestone; Looks quite logic, doesn't it?
So let's make a crafting recipe for the decorative wood of Chapter 0!
Just append (add) this to your init.lua file:
----------------------------------------------------
| Code |
----------------------------------------------------
minetest.register_craft({
output = '"tutorial:decowood" 2',
recipe = {
{'default:wood', 'default:wood', ''},
{'default:wood', 'default:wood', ''},
{'', '', ''},
}
})
----------------------------------------------------
| End of Code |
----------------------------------------------------
The function minetest.register_craft() 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)
1) output - which sets the outcome of the crafting process and recipe which is the actual recipe for the output.
2) Recipe 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. In this case The crafting recipe is like that:
W W
W W
W=Wood
3) type - if you want to make it a furnace craft add type="cook",
Easy, isn't it? You may also try out some other combinations!
But why are wooden planks not simply called wood but 'default:wood'?
Indeed, The name of a tool/block/other object MUST be modname:name. In this case, the mod is called 'tutorial' (name is preset by the folder name) and the block is called 'decowood', so it's tutorial:decowood.
So what is 'default'? 'default' is the most important "mod" of minetest, in fact minetest itself is more like just a game engine, all the contents, materials, and other stuff are in several mods, like 'default' (standard tools/blocks), 'bucket' (Buckets: Lava/Water),...
If you want to find out more about these mods and maybe use features they contain, just have a look in their init.lua!
For Windows & Linux run-in-place these mods are in minetest/games/minetest_game/;
for Linux systemwide installation, these mods are in /usr/share/minetest/games/minetest_game
Chapter 3: ABMs & Positioning
=============================
ABMs add actions to blocks. For instance, the tutorial-wood could become normal wood after a few seconds. Append this code to your init.lua:
minetest.register_abm(
{nodenames = {"tutorial:decowood"},
interval = 30,
chance = 1,
action = function(pos)
minetest.env:add_node(pos, {name="default:wood"})
end,
})
Try it out! It's really annoying to see all your decowood creations destroyed after 30 seconds, they simple become normal wood.
But how does this work?
The function minetest.register_abm registers an action for each block of the same type.
nodenames = {"tutorial:decowood'} means that the action is processed for each decowood block.
You could also try "default:stone" instead of that to turn all stone blocks into wood.
interval = 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!
chance = 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.
action = function(pos) is the function that is actually performed.
It contains the command minetest.env:add_node. 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:
minetest.regis----------------------------------------------------
| Code |
----------------------------------------------------
ter_abm(
{nodenames = {"default:dirt_with_grass"},
interval = 1,
chance = 100,
action = function(pos)
pos.y=pos.y+1
minetest.env:add_node(pos, {name="default:junglegrass"})
end,
})
You should already know everything else but the line pos.y=pos.y+1.
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:
x, y and z.
x and z are forward/backward; left/right values. Y is the up/down value. The player usually spawns near 0,0,0.
The line pos.y=pos.y+1 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.
Credits and Afterword
=====================
This is Jeija's modding tutorial Version 20120218, rewriten and formated for english by "Rubenwardy"
Check for new version on github.com/Jeija/minetest-modding-tutorial.
For more advanced (and often cryptic) information about minetest modding have a look at this reference:
http://c55.me/minetest/wiki/doku.php?id=code:lua_api
For generic modding questions or specific questions, feel free to ask in the minetest forum:
c55.me/minetest/forum
For questions about this tutorial, ask in the thread for this tutorial:
c55.me/minetest/forum/...
Minetest-c55: Modding in Lua
CONTENTS:
=========
Introduction
--- Modding with Minetest
--- Requirements
Chapter 1 - Modding Basics and Required understanding
---Mod packs and item names
---Creating a mod
Tutorial 0ne: Decowood
----------------------
Chapter 2 - Defining a node
Chapter 3 - Setting up a craft recipe
Chapter 4 - ADMs and Positioning
---Adms and Positioning
Introduction
============
Minetest-c55 (Website: minetest.net) is a Minecraft clone, developed by the Finnish programmer 'celeron55' and contributors.
Minetest has a ScriptAPI (Applictation Programming Interface), which is used to program Mods (Modifications) for the game, extending its features and adding new items.
This ScriptAPI is accessed using an easy-to-use programming langauge called Lua.
Requirements:
=============
Basic Programming Knowledge, at best in Lua Language
--- Don't have any knowledge? Use the following to learn:
-------- codecademy.com -Learn the basics of programming (it is Javascript (not Java) but still helps)
-------- Internet Search (google,yahoo) lua tutorials
Chapter 1 - Modding basics
==========================
---Types of objects in Minetest---
Here are the three types of items you can define in Minetest:
Node (register_node): A Block from the world
Tool (register_tool): A tool/weapon that can dig and damage things according to tool_capabilities
Craftitem (register_craftitem): A miscellaneous item
The type of the object is important as it plays a part in the properties of that object.
--- Mod packs and item names ---
In minetest, each node, tool and item need a unique name to identify it in the api.
The names format is like this:
------------------------
| modpackname:itemname |
------------------------
so for example, default:dirt is the unique name for dirt.
--- Creating a mod ---
To create a minetest mod, you have to create a new folder with the name of your mod in the mod folder
-----------------------------------------------------------------
| Linux Systemwide: ~/.minetest*/usermods/ |
| |
| Windows + Linux Run-in-place: minetest*/mods/minetest |
|---------------------------------------------------------------|
| minetest* The place where minetest was installed/extracted to.|
-----------------------------------------------------------------
In the new folder, create a file called 'init.lua'. This is the file that will contain the source code for the mod.
----------------------------------------------------------
| To do this on Windows, use WordPad. Click file>save as |
| dropdown to all files, and type 'init.lua' in the file |
| name box. |
| Or you can use a lua compatible editor such |
| as 'context' WARNING: DO NOT USE NOTEPAD |
---------------------------------------------------------
Then make another sub folder called 'textures'. This is where you will place the textures
Additionally, create a file called 'init.lua'. This is the file that contains the source code of your mod.
Chapter 2: [tutorial] Your first mod!
=====================================
We are going to make a mod that adds a special kind of wood that can only be used for decoration.
For this, create a new mod called 'tutorial' using the method described in Chapter 0.
--- Creating decowood ---
Step 1) copy-paste this into 'init.lua':
----------------------------------------------------
| Code |
----------------------------------------------------
minetest.register_node("tutorial:decowood", {
tile_images = {"tutorial_decowood.png"},
groups={level=1},
})
----------------------------------------------------
| end of Code |
----------------------------------------------------
Step 2) Copy the file 'tutorial_decowood.png' supplied with this Document to the textures folder in the mod.
Try it) 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 ingame (press t) and enter "/giveme tutorial:decowood 99" (Without "" of course). This will add 99 blocks of the decorative wood to your inventory!
--------------------------------------------------------------------------
| HELP TIP |
|------------------------------------------------------------------------|
| The "give" privilage is required for the /giveme command to work |
| To grant yourself the "give" privilage, go to worlds/gamename/auth.txt |
| And add ",give" after "shout,interact" to make it "shout,interact,give"|
--------------------------------------------------------------------------
-----------------------------------------
| Let's have a look at the source code: |
-----------------------------------------
The function minetest.register_node(name, table) is responsible for adding new blocks to the game (node=block, but also torches, rails, ...) .
It takes 2 Parameters: The name of the new block ("tutorial:decowood", the string before : MUST be the name of the mod folder) and a table with several properties of the block.
In this case we use 2 properties:
tile_images: Sets the texture of the block; You can use only 1 texture or multiple textures,
seperated by commas {"tex1.png", "tex2.png", ...}. The game checks for the texture files in ALL textures folders of the game.
material: This sets the time it takes to destroy the block. In this case (minetest.digprop_constanttime(1)) it is a constant time of 1 second.
You could also use minetest.digprop_woodlike(1.5) which makes destruction with axes faster.
Chapter 3 - Crafting
====================
Crafting does not only play an important role in minecraft, minetest also uses different crafting recipes. Therefore it is important to know what crafting means and how to code it!
Crafting means to creating Tools, Blocks and Other Objects.
In minetest you have a 3x3 crafting area by default with a 1x1 output field.
For example, a stone pickaxe can be made out of 2 Sticks and 3 Cobblestones:
C C C
S
S
S=Stick C=Cobblestone; Looks quite logic, doesn't it?
So let's make a crafting recipe for the decorative wood of Chapter 0!
Just append (add) this to your init.lua file:
----------------------------------------------------
| Code |
----------------------------------------------------
minetest.register_craft({
output = '"tutorial:decowood" 2',
recipe = {
{'default:wood', 'default:wood', ''},
{'default:wood', 'default:wood', ''},
{'', '', ''},
}
})
----------------------------------------------------
| End of Code |
----------------------------------------------------
The function minetest.register_craft() 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)
1) output - which sets the outcome of the crafting process and recipe which is the actual recipe for the output.
2) Recipe 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. In this case The crafting recipe is like that:
W W
W W
W=Wood
3) type - if you want to make it a furnace craft add type="cook",
Easy, isn't it? You may also try out some other combinations!
But why are wooden planks not simply called wood but 'default:wood'?
Indeed, The name of a tool/block/other object MUST be modname:name. In this case, the mod is called 'tutorial' (name is preset by the folder name) and the block is called 'decowood', so it's tutorial:decowood.
So what is 'default'? 'default' is the most important "mod" of minetest, in fact minetest itself is more like just a game engine, all the contents, materials, and other stuff are in several mods, like 'default' (standard tools/blocks), 'bucket' (Buckets: Lava/Water),...
If you want to find out more about these mods and maybe use features they contain, just have a look in their init.lua!
For Windows & Linux run-in-place these mods are in minetest/games/minetest_game/;
for Linux systemwide installation, these mods are in /usr/share/minetest/games/minetest_game
Chapter 4: ABMs & Positioning
=============================
ABMs add actions to blocks. For instance, the tutorial-wood could become normal wood after a few seconds. Append this code to your init.lua:
----------------------------------------------------
| Code |
----------------------------------------------------
minetest.register_abm(
{nodenames = {"tutorial:decowood"},
interval = 30,
chance = 1,
action = function(pos)
minetest.env:add_node(pos, {name="default:wood"})
end,
})
----------------------------------------------------
| end of Code |
----------------------------------------------------
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 minetest.register_abm registers an action for each block of the same type.
nodenames = {"tutorial:decowood'} means that the action is processed for each decowood block.
You could also try "default:stone" instead of that to turn all stone blocks into wood.
interval = 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!
chance = 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.
action = function(pos) is the function that is actually performed.
It contains the command minetest.env:add_node. 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:
----------------------------------------------------
| Code |
----------------------------------------------------
minetest.register_abm(
{nodenames = {"default:dirt_with_grass"},
interval = 1,
chance = 100,
action = function(pos)
pos.y=pos.y+1
minetest.env:add_node(pos, {name="default:junglegrass"})
end,
})
----------------------------------------------------
| end of Code |
----------------------------------------------------
You should already know everything else but the line pos.y=pos.y+1.
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:
x, y and z.
x and z are forward/backward; left/right values. Y is the up/down value. The player usually spawns near 0,0,0.
The line pos.y=pos.y+1 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.
Credits and Afterword
=====================
This is Jeija's modding tutorial Version 20120218, Rewriten and formated for english by "Rubenwardy"
Check for new version on github.com/Jeija/minetest-modding-tutorial.
For more advanced (and often cryptic) information about minetest modding have a look at this reference:
http://c55.me/minetest/wiki/doku.php?id=code:lua_api
For generic modding questions or specific questions, feel free to ask in the minetest forum:
c55.me/minetest/forum
For questions about this tutorial, ask in the thread for this tutorial:
c55.me/minetest/forum/...
Thanks you for reading! Good luck in creating your amazing dream mod!