Replace tab character with four spaces for better formatting

This commit is contained in:
rubenwardy 2017-08-26 19:01:51 +01:00
parent d68975ba9f
commit 5d64318342
18 changed files with 778 additions and 778 deletions

170
README.md
View File

@ -41,19 +41,19 @@ fit my idea of quality.
I use [Jekyll](http://jekyllrb.com/) 2.5.3 I use [Jekyll](http://jekyllrb.com/) 2.5.3
# For Linux based: # For Linux based:
$ sudo apt-get install ruby-dev $ sudo apt-get install ruby-dev
$ gem install jekyll $ gem install jekyll
$ gem install jekyll-sitemap $ gem install jekyll-sitemap
# You may need to use sudo on the above commands # You may need to use sudo on the above commands
### Building as a website ### Building as a website
You can build it as a website using [Jekyll](http://jekyllrb.com/) You can build it as a website using [Jekyll](http://jekyllrb.com/)
$ jekyll build $ jekyll build
Goes to _site/ Goes to _site/
@ -62,7 +62,7 @@ Goes to _site/
You can start a webserver on localhost which will automatically You can start a webserver on localhost which will automatically
rebuild pages when you modify their markdown source. rebuild pages when you modify their markdown source.
$ jekyll serve $ jekyll serve
This serves at <http://localhost:4000> on my computer, but the port This serves at <http://localhost:4000> on my computer, but the port
@ -89,107 +89,107 @@ Replace spaces with underscores ( _ )
{% raw %} {% raw %}
--- ---
title: Player Physics title: Player Physics
layout: default layout: default
root: ../ root: ../
--- ---
Introduction Introduction
------------ ------------
Write an paragraph or so explaining what will be covered in this chapter. Write an paragraph or so explaining what will be covered in this chapter.
Explain why/how these concepts are useful in modding Explain why/how these concepts are useful in modding
* List the * List the
* Parts in * Parts in
* This chapter * This chapter
Section Section
------- -------
Explaining the concept of something. Explaining the concept of something.
You can link to other chapters like this: [chapter title]({{ relative }}/chaptertitle/).// You can link to other chapters like this: [chapter title]({{ relative }}/chaptertitle/).//
Do it like Wikipedia, link words in a sentence but avoid explicitly telling the user to view it// Do it like Wikipedia, link words in a sentence but avoid explicitly telling the user to view it//
or click the link. or click the link.
Mod Name Mod Name
- init.lua - the main scripting code file, which is run when the game loads. - init.lua - the main scripting code file, which is run when the game loads.
- (optional) depends.txt - a list of mod names that needs to be loaded before this mod. - (optional) depends.txt - a list of mod names that needs to be loaded before this mod.
- (optional) textures/ - place images here, commonly in the format modname_itemname.png - (optional) textures/ - place images here, commonly in the format modname_itemname.png
- (optional) sounds/ - place sounds in here - (optional) sounds/ - place sounds in here
- (optional) models/ - place 3d models in here - (optional) models/ - place 3d models in here
...and any other lua files to be included by init.lua ...and any other lua files to be included by init.lua
Code snippets are tabbed one level in, except for lua snippets, which use a code highligter. Code snippets are tabbed one level in, except for lua snippets, which use a code highligter.
Section 2 Section 2
--------- ---------
Explaining another concept Explaining another concept
{% highlight lua %} {% highlight lua %}
print("This file will be run at load time!") print("This file will be run at load time!")
minetest.register_node("mymod:node",{ minetest.register_node("mymod:node",{
description = "This is a node", description = "This is a node",
tiles = { tiles = {
"mymod_node.png", "mymod_node.png",
"mymod_node.png", "mymod_node.png",
"mymod_node.png", "mymod_node.png",
"mymod_node.png", "mymod_node.png",
"mymod_node.png", "mymod_node.png",
"mymod_node.png" "mymod_node.png"
}, },
groups = {cracky = 1} groups = {cracky = 1}
}) })
{% endhighlight %} {% endhighlight %}
Use the highlight tags to highlight Lua code. Use the highlight tags to highlight Lua code.
Section 3 Section 3
--------- ---------
You should include plenty of examples. Each example should You should include plenty of examples. Each example should
be able to be installed in a mod and used. Don't do the thing where be able to be installed in a mod and used. Don't do the thing where
you make the reading create the mod line-by-line, it is rather annoying you make the reading create the mod line-by-line, it is rather annoying
and good code can explain itself. Explaining line-by-line is needed in earlier chapters, and good code can explain itself. Explaining line-by-line is needed in earlier chapters,
and when introducing new concepts. and when introducing new concepts.
### Mod Folder ### Mod Folder
mymod/ mymod/
- init.lua - init.lua
- depends.txt - depends.txt
default default
{% highlight lua %} {% highlight lua %}
print("This file will be run at load time!") print("This file will be run at load time!")
minetest.register_node("mymod:node",{ minetest.register_node("mymod:node",{
description = "This is a node", description = "This is a node",
tiles = { tiles = {
"mymod_node.png", "mymod_node.png",
"mymod_node.png", "mymod_node.png",
"mymod_node.png", "mymod_node.png",
"mymod_node.png", "mymod_node.png",
"mymod_node.png", "mymod_node.png",
"mymod_node.png" "mymod_node.png"
}, },
groups = {cracky = 1} groups = {cracky = 1}
}) })
{% endhighlight %} {% endhighlight %}
Explain the code here, but there is no need to explain every single line. Explain the code here, but there is no need to explain every single line.
Use comments and indentation well. Use comments and indentation well.
Your Turn Your Turn
--------- ---------
* **Set Tasks:** Make tasks for the reader to do. * **Set Tasks:** Make tasks for the reader to do.
* **Start easy, get hard:** Start with easier ones, and work up to harder ones. * **Start easy, get hard:** Start with easier ones, and work up to harder ones.
{% endraw %} {% endraw %}

View File

@ -23,21 +23,21 @@ blocks.
{% highlight lua %} {% highlight lua %}
minetest.register_node("aliens:grass", { minetest.register_node("aliens:grass", {
description = "Alien Grass", description = "Alien Grass",
light_source = 3, -- The node radiates light. Values can be from 1 to 15 light_source = 3, -- The node radiates light. Values can be from 1 to 15
tiles = {"aliens_grass.png"}, tiles = {"aliens_grass.png"},
groups = {choppy=1}, groups = {choppy=1},
on_use = minetest.item_eat(20) on_use = minetest.item_eat(20)
}) })
minetest.register_abm({ minetest.register_abm({
nodenames = {"default:dirt_with_grass"}, nodenames = {"default:dirt_with_grass"},
neighbors = {"default:water_source", "default:water_flowing"}, neighbors = {"default:water_source", "default:water_flowing"},
interval = 10.0, -- Run every 10 seconds interval = 10.0, -- Run every 10 seconds
chance = 50, -- Select every 1 in 50 nodes chance = 50, -- Select every 1 in 50 nodes
action = function(pos, node, active_object_count, active_object_count_wider) action = function(pos, node, active_object_count, active_object_count_wider)
minetest.set_node({x = pos.x, y = pos.y + 1, z = pos.z}, {name = "aliens:grass"}) minetest.set_node({x = pos.x, y = pos.y + 1, z = pos.z}, {name = "aliens:grass"})
end end
}) })
{% endhighlight %} {% endhighlight %}

View File

@ -26,9 +26,9 @@ minetest.chat_send_all("This is a chat message to all players")
Here is an example of how it would appear ingame (there are other messages Here is an example of how it would appear ingame (there are other messages
around it). around it).
<player1> Look at this entrance <player1> Look at this entrance
This is a chat message to all players This is a chat message to all players
<player2> What about it? <player2> What about it?
## Send a message to a certain player ## Send a message to a certain player
@ -59,12 +59,12 @@ In order to register a chat command, such as /foo, use register_chatcommand:
{% highlight lua %} {% highlight lua %}
minetest.register_chatcommand("foo", { minetest.register_chatcommand("foo", {
privs = { privs = {
interact = true interact = true
}, },
func = function(name, param) func = function(name, param)
return true, "You said " .. param .. "!" return true, "You said " .. param .. "!"
end end
}) })
{% endhighlight %} {% endhighlight %}
@ -74,7 +74,7 @@ Let's do a break down:
{% highlight lua %} {% highlight lua %}
privs = { privs = {
interact = true interact = true
}, },
{% endhighlight %} {% endhighlight %}
@ -116,8 +116,8 @@ You can use register_on_chat_message, like so:
{% highlight lua %} {% highlight lua %}
minetest.register_on_chat_message(function(name, message) minetest.register_on_chat_message(function(name, message)
print(name .. " said " .. message) print(name .. " said " .. message)
return false return false
end) end)
{% endhighlight %} {% endhighlight %}
@ -130,12 +130,12 @@ player messages, you need to do this:
{% highlight lua %} {% highlight lua %}
minetest.register_on_chat_message(function(name, message) minetest.register_on_chat_message(function(name, message)
if message:sub(1, 1) == "/" then if message:sub(1, 1) == "/" then
print(name .. " ran chat command") print(name .. " ran chat command")
return false return false
end end
print(name .. " said " .. message) print(name .. " said " .. message)
return false return false
end) end)
{% endhighlight %} {% endhighlight %}

View File

@ -28,21 +28,21 @@ Because of this, I created a library to do this for you.
{% highlight lua %} {% highlight lua %}
ChatCmdBuilder.new("sethp", function(cmd) ChatCmdBuilder.new("sethp", function(cmd)
cmd:sub(":target :hp:int", function(name, target, hp) cmd:sub(":target :hp:int", function(name, target, hp)
local player = minetest.get_player_by_name(target) local player = minetest.get_player_by_name(target)
if player then if player then
player:set_hp(hp) player:set_hp(hp)
return true, "Killed " .. target return true, "Killed " .. target
else else
return false, "Unable to find " .. target return false, "Unable to find " .. target
end end
end) end)
end, { end, {
description = "Set hp of player", description = "Set hp of player",
privs = { privs = {
kick = true kick = true
-- ^ probably better to register a custom priv -- ^ probably better to register a custom priv
} }
}) })
{% endhighlight %} {% endhighlight %}
@ -94,7 +94,7 @@ function in order.
{% highlight lua %} {% highlight lua %}
cmd:sub(":target :hp:int", function(name, target, hp) cmd:sub(":target :hp:int", function(name, target, hp)
-- subcommand function -- subcommand function
end) end)
{% endhighlight %} {% endhighlight %}
@ -118,55 +118,55 @@ Here is an example that creates a chat command that allows us to do this:
{% highlight lua %} {% highlight lua %}
local admin_log local admin_log
local function load() local function load()
admin_log = {} admin_log = {}
end end
local function save() local function save()
-- todo -- todo
end end
load() load()
ChatCmdBuilder.new("admin", function(cmd) ChatCmdBuilder.new("admin", function(cmd)
cmd:sub("kill :name", function(name, target) cmd:sub("kill :name", function(name, target)
local player = minetest.get_player_by_name(target) local player = minetest.get_player_by_name(target)
if player then if player then
player:set_hp(0) player:set_hp(0)
return true, "Killed " .. target return true, "Killed " .. target
else else
return false, "Unable to find " .. target return false, "Unable to find " .. target
end end
end) end)
cmd:sub("move :name to :pos:pos", function(name, target, pos) cmd:sub("move :name to :pos:pos", function(name, target, pos)
local player = minetest.get_player_by_name(target) local player = minetest.get_player_by_name(target)
if player then if player then
player:setpos(pos) player:setpos(pos)
return true, "Moved " .. target .. " to " .. minetest.pos_to_string(pos) return true, "Moved " .. target .. " to " .. minetest.pos_to_string(pos)
else else
return false, "Unable to find " .. target return false, "Unable to find " .. target
end end
end) end)
cmd:sub("log :username", function(name, target) cmd:sub("log :username", function(name, target)
local log = admin_log[target] local log = admin_log[target]
if log then if log then
return true, table.concat(log, "\n") return true, table.concat(log, "\n")
else else
return false, "No entries for " .. target return false, "No entries for " .. target
end end
end) end)
cmd:sub("log :username :message", function(name, target, message) cmd:sub("log :username :message", function(name, target, message)
local log = admin_log[target] or {} local log = admin_log[target] or {}
table.insert(log, message) table.insert(log, message)
admin_log[target] = log admin_log[target] = log
save() save()
return true, "Logged" return true, "Logged"
end) end)
end, { end, {
description = "Admin tools", description = "Admin tools",
privs = { privs = {
kick = true, kick = true,
ban = true ban = true
} }
}) })
{% endhighlight %} {% endhighlight %}

View File

@ -31,19 +31,19 @@ learning curve as lots of its features are hidden away.
### Use the pencil tool to edit individual pixels ### Use the pencil tool to edit individual pixels
<figure> <figure>
<img src="{{ page.root }}/static/pixel_art_gimp_pencil.png" alt="Pencil in GIMP"> <img src="{{ page.root }}/static/pixel_art_gimp_pencil.png" alt="Pencil in GIMP">
<figcaption> <figcaption>
Pencil in GIMP Pencil in GIMP
</figcaption> </figcaption>
</figure> </figure>
### Set the rubber to hard edge ### Set the rubber to hard edge
<figure> <figure>
<img src="{{ page.root }}/static/pixel_art_gimp_rubber.png" alt="Rubber in GIMP"> <img src="{{ page.root }}/static/pixel_art_gimp_rubber.png" alt="Rubber in GIMP">
<figcaption> <figcaption>
Rubber in GIMP Rubber in GIMP
</figcaption> </figcaption>
</figure> </figure>
## Common Mistakes ## Common Mistakes

View File

@ -27,13 +27,13 @@ Mod names can be made up of letters, numbers, or underscores. The folder a mod i
in needs to be called the same as the mod name. in needs to be called the same as the mod name.
### Mod Folder Structure ### Mod Folder Structure
Mod name (eg: "mymod") Mod name (eg: "mymod")
- init.lua - the main scripting code file, which is run when the game loads. - init.lua - the main scripting code file, which is run when the game loads.
- (optional) depends.txt - a list of mod names that needs to be loaded before this mod. - (optional) depends.txt - a list of mod names that needs to be loaded before this mod.
- (optional) textures/ - place images here, commonly in the format modname_itemname.png - (optional) textures/ - place images here, commonly in the format modname_itemname.png
- (optional) sounds/ - place sounds in here - (optional) sounds/ - place sounds in here
- (optional) models/ - place 3d models in here - (optional) models/ - place 3d models in here
...and any other lua files to be included by init.lua ...and any other lua files to be included by init.lua
Only the init.lua file is required in a mod for it to run on game load; however, Only the init.lua file is required in a mod for it to run on game load; however,
the other items are needed by some mods to perform their functionality. the other items are needed by some mods to perform their functionality.
@ -45,9 +45,9 @@ needs to be loaded before this mod.
**depends.txt** **depends.txt**
modone modone
modtwo modtwo
modthree? modthree?
As you can see, each modname is on its own line. As you can see, each modname is on its own line.
@ -64,43 +64,43 @@ They are useful if you want to supply multiple mods to a player but don't
want to make them download each one individually. want to make them download each one individually.
### Mod Pack Folder Structure ### Mod Pack Folder Structure
modpackfolder/ modpackfolder/
- modone/ - modone/
- modtwo/ - modtwo/
- modthree/ - modthree/
- modfour/ - modfour/
- modpack.txt signals that this is a mod pack, content does not matter - modpack.txt signals that this is a mod pack, content does not matter
## Example Time ## Example Time
Are you confused? Don't worry, here is an example putting all of this together. Are you confused? Don't worry, here is an example putting all of this together.
### Mod Folder ### Mod Folder
mymod/ mymod/
- textures/ - textures/
- - mymod_node.png - - mymod_node.png
- init.lua - init.lua
- depends.txt - depends.txt
### depends.txt ### depends.txt
default default
### init.lua ### init.lua
{% highlight lua %} {% highlight lua %}
print("This file will be run at load time!") print("This file will be run at load time!")
minetest.register_node("mymod:node", { minetest.register_node("mymod:node", {
description = "This is a node", description = "This is a node",
tiles = { tiles = {
"mymod_node.png", "mymod_node.png",
"mymod_node.png", "mymod_node.png",
"mymod_node.png", "mymod_node.png",
"mymod_node.png", "mymod_node.png",
"mymod_node.png", "mymod_node.png",
"mymod_node.png" "mymod_node.png"
}, },
groups = {cracky = 1} groups = {cracky = 1}
}) })
{% endhighlight %} {% endhighlight %}

View File

@ -7,10 +7,10 @@ root: ../../
## Introduction ## Introduction
<figure class="right_image"> <figure class="right_image">
<img src="{{ page.root }}/static/formspec_example.png" alt="Furnace Inventory"> <img src="{{ page.root }}/static/formspec_example.png" alt="Furnace Inventory">
<figcaption> <figcaption>
Screenshot of furnace formspec, labelled. Screenshot of furnace formspec, labelled.
</figcaption> </figcaption>
</figure> </figure>
In this chapter we will learn how to create a formspec and display it to the user. In this chapter we will learn how to create a formspec and display it to the user.
@ -32,7 +32,7 @@ tend to disrupt game play.
Formspecs have a rather weird syntax. Formspecs have a rather weird syntax.
They consist of a series of tags which are in the following form: They consist of a series of tags which are in the following form:
element_type[param1;param2;...] element_type[param1;param2;...]
Firstly the element type is declared, and then the attributes are given Firstly the element type is declared, and then the attributes are given
in square brackets. in square brackets.
@ -42,7 +42,7 @@ as size or background).
Here are two elements, of types foo and bar. Here are two elements, of types foo and bar.
foo[param1]bar[param1] foo[param1]bar[param1]
### Size[w, h] ### Size[w, h]
@ -53,7 +53,7 @@ The reason this is used is because it is independent on screen resolution -
The form should work just as well on large screens as small screens. The form should work just as well on large screens as small screens.
You can use decimals in sizes and co-ordinates. You can use decimals in sizes and co-ordinates.
size[5,2] size[5,2]
Co-ordinates and sizes only use one attribute. Co-ordinates and sizes only use one attribute.
The x and y values are separated by a comma, as you can see above. The x and y values are separated by a comma, as you can see above.
@ -64,7 +64,7 @@ This is a textbox element. Most other elements have a similar style of attribute
The "name" attribute is used in callbacks to get the submitted information. The "name" attribute is used in callbacks to get the submitted information.
The others are pretty self-explaintary. The others are pretty self-explaintary.
field[1,1;3,1;firstname;Firstname;] field[1,1;3,1;firstname;Firstname;]
It is perfectly valid to not define an attribute, like above. It is perfectly valid to not define an attribute, like above.
@ -78,7 +78,7 @@ It is near line 1019, at time of writing.
Here is a generalized way to show a formspec Here is a generalized way to show a formspec
minetest.show_formspec(playername, formname, formspec) minetest.show_formspec(playername, formname, formspec)
Formnames should be itemnames, however that is not enforced. Formnames should be itemnames, however that is not enforced.
There is no need to override a formspec here, formspecs are not registered like There is no need to override a formspec here, formspecs are not registered like
@ -90,23 +90,23 @@ and see if the callback is relevant.
### Example ### Example
<figure class="right_image"> <figure class="right_image">
<img src="{{ page.root }}/static/formspec_name.png" alt="Name Formspec"> <img src="{{ page.root }}/static/formspec_name.png" alt="Name Formspec">
<figcaption> <figcaption>
The formspec generated by<br /> The formspec generated by<br />
the example's code the example's code
</figcaption> </figcaption>
</figure> </figure>
{% highlight lua %} {% highlight lua %}
-- Show form when the /formspec command is used. -- Show form when the /formspec command is used.
minetest.register_chatcommand("formspec", { minetest.register_chatcommand("formspec", {
func = function(name, param) func = function(name, param)
minetest.show_formspec(name, "mymod:form", minetest.show_formspec(name, "mymod:form",
"size[4,3]" .. "size[4,3]" ..
"label[0,0;Hello, " .. name .. "]" .. "label[0,0;Hello, " .. name .. "]" ..
"field[1,1.5;3,1;name;Name;]" .. "field[1,1.5;3,1;name;Name;]" ..
"button_exit[1,2;2,1;exit;Save]") "button_exit[1,2;2,1;exit;Save]")
end end
}) })
{% endhighlight %} {% endhighlight %}
@ -126,29 +126,29 @@ Let's expand on the above example.
{% highlight lua %} {% highlight lua %}
-- Show form when the /formspec command is used. -- Show form when the /formspec command is used.
minetest.register_chatcommand("formspec", { minetest.register_chatcommand("formspec", {
func = function(name, param) func = function(name, param)
minetest.show_formspec(name, "mymod:form", minetest.show_formspec(name, "mymod:form",
"size[4,3]" .. "size[4,3]" ..
"label[0,0;Hello, " .. name .. "]" .. "label[0,0;Hello, " .. name .. "]" ..
"field[1,1.5;3,1;name;Name;]" .. "field[1,1.5;3,1;name;Name;]" ..
"button_exit[1,2;2,1;exit;Save]") "button_exit[1,2;2,1;exit;Save]")
end end
}) })
-- Register callback -- Register callback
minetest.register_on_player_receive_fields(function(player, formname, fields) minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= "mymod:form" then if formname ~= "mymod:form" then
-- Formname is not mymod:form, -- Formname is not mymod:form,
-- exit callback. -- exit callback.
return false return false
end end
-- Send message to player. -- Send message to player.
minetest.chat_send_player(player:get_player_name(), "You said: " .. fields.name .. "!") minetest.chat_send_player(player:get_player_name(), "You said: " .. fields.name .. "!")
-- Return true to stop other minetest.register_on_player_receive_fields -- Return true to stop other minetest.register_on_player_receive_fields
-- from receiving this submission. -- from receiving this submission.
return true return true
end) end)
{% endhighlight %} {% endhighlight %}
@ -176,8 +176,8 @@ for a clicked button.
-- An example of what fields could contain, -- An example of what fields could contain,
-- using the above code -- using the above code
{ {
name = "Foo Bar", name = "Foo Bar",
exit = true exit = true
} }
{% endhighlight %} {% endhighlight %}
@ -198,21 +198,21 @@ Let's say you are making a form to handle land protection information.
local land_formspec_context = {} local land_formspec_context = {}
minetest.register_chatcommand("land", { minetest.register_chatcommand("land", {
func = function(name, param) func = function(name, param)
if param == "" then if param == "" then
minetest.chat_send_player(name, "Incorrect parameters - supply a land ID") minetest.chat_send_player(name, "Incorrect parameters - supply a land ID")
return return
end end
-- Save information -- Save information
land_formspec_context[name] = {id = param} land_formspec_context[name] = {id = param}
minetest.show_formspec(name, "mylandowner:edit", minetest.show_formspec(name, "mylandowner:edit",
"size[4,4]" .. "size[4,4]" ..
"field[1,1;3,1;plot;Plot Name;]" .. "field[1,1;3,1;plot;Plot Name;]" ..
"field[1,2;3,1;owner;Owner;]" .. "field[1,2;3,1;owner;Owner;]" ..
"button_exit[1,3;2,1;exit;Save]") "button_exit[1,3;2,1;exit;Save]")
end end
}) })
@ -221,25 +221,25 @@ minetest.register_chatcommand("land", {
-- Step 2) retrieve context when player submits the form -- Step 2) retrieve context when player submits the form
-- --
minetest.register_on_player_receive_fields(function(player, formname, fields) minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= "mylandowner:edit" then if formname ~= "mylandowner:edit" then
return false return false
end end
-- Load information -- Load information
local context = land_formspec_context[player:get_player_name()] local context = land_formspec_context[player:get_player_name()]
if context then if context then
minetest.chat_send_player(player:get_player_name(), "Id " .. context.id .. " is now called " .. minetest.chat_send_player(player:get_player_name(), "Id " .. context.id .. " is now called " ..
fields.plot .. " and owned by " .. fields.owner) fields.plot .. " and owned by " .. fields.owner)
-- Delete context if it is no longer going to be used -- Delete context if it is no longer going to be used
land_formspec_context[player:get_player_name()] = nil land_formspec_context[player:get_player_name()] = nil
return true return true
else else
-- Fail gracefully if the context does not exist. -- Fail gracefully if the context does not exist.
minetest.chat_send_player(player:get_player_name(), "Something went wrong, try again.") minetest.chat_send_player(player:get_player_name(), "Something went wrong, try again.")
end end
end) end)
{% endhighlight %} {% endhighlight %}
@ -252,20 +252,20 @@ the player the chest formspec.
{% highlight lua %} {% highlight lua %}
minetest.register_node("mymod:rightclick", { minetest.register_node("mymod:rightclick", {
description = "Rightclick me!", description = "Rightclick me!",
tiles = {"mymod_rightclick.png"}, tiles = {"mymod_rightclick.png"},
groups = {cracky = 1}, groups = {cracky = 1},
after_place_node = function(pos, placer) after_place_node = function(pos, placer)
-- This function is run when the chest node is placed. -- This function is run when the chest node is placed.
-- The following code sets the formspec for chest. -- The following code sets the formspec for chest.
-- Meta is a way of storing data onto a node. -- Meta is a way of storing data onto a node.
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
meta:set_string("formspec", meta:set_string("formspec",
"size[5,5]".. "size[5,5]"..
"label[1,1;This is shown on right click]".. "label[1,1;This is shown on right click]"..
"field[1,2;2,1;x;x;]") "field[1,2;2,1;x;x;]")
end, end,
on_receive_fields = function(pos, formname, fields, player) on_receive_fields = function(pos, formname, fields, player)
if(fields.quit) then return end if(fields.quit) then return end
print(fields.x) print(fields.x)

View File

@ -5,10 +5,10 @@ root: ../../
--- ---
<div class="notice"> <div class="notice">
<h2>Experimental Feature</h2> <h2>Experimental Feature</h2>
The HUD feature will probably be rewritten in an upcoming Minetest release. The HUD feature will probably be rewritten in an upcoming Minetest release.
Be aware that you may need to update your mods if the API is changed. Be aware that you may need to update your mods if the API is changed.
</div> </div>
## Introduction ## Introduction
@ -84,11 +84,11 @@ Here is our earlier example, but with comments to explain each part:
{% highlight lua %} {% highlight lua %}
local idx = player:hud_add({ local idx = player:hud_add({
hud_elem_type = "text", -- This is a text element hud_elem_type = "text", -- This is a text element
position = {x = 1, y = 0}, position = {x = 1, y = 0},
offset = {x=-100, y = 20}, offset = {x=-100, y = 20},
scale = {x = 100, y = 100}, -- Maximum size of text, crops off any out of these bounds scale = {x = 100, y = 100}, -- Maximum size of text, crops off any out of these bounds
text = "My Text" -- The actual text shown text = "My Text" -- The actual text shown
}) })
{% endhighlight %} {% endhighlight %}
@ -99,12 +99,12 @@ Colors are in [Hexadecimal form](http://www.colorpicker.com/).
{% highlight lua %} {% highlight lua %}
local idx = player:hud_add({ local idx = player:hud_add({
hud_elem_type = "text", hud_elem_type = "text",
position = {x = 1, y = 0}, position = {x = 1, y = 0},
offset = {x=-100, y = 20}, offset = {x=-100, y = 20},
scale = {x = 100, y = 100}, scale = {x = 100, y = 100},
text = "My Text", text = "My Text",
number = 0xFF0000 -- Red number = 0xFF0000 -- Red
}) })
{% endhighlight %} {% endhighlight %}

View File

@ -13,21 +13,21 @@ This chapter assumes that you already know how to create and manipulate
* Basic Concepts. * Basic Concepts.
* Types of Inventories. * Types of Inventories.
* Player Inventories. * Player Inventories.
* Node Inventories. * Node Inventories.
* Detached Inventories. * Detached Inventories.
* InvRef and Lists. * InvRef and Lists.
* Type of inventory. * Type of inventory.
* List sizes. * List sizes.
* List is empty. * List is empty.
* Lua Tables. * Lua Tables.
* Lua Tables for Lists. * Lua Tables for Lists.
* InvRef, Items and Stacks. * InvRef, Items and Stacks.
* Adding to a list. * Adding to a list.
* Checking for room. * Checking for room.
* Taking items. * Taking items.
* Contains. * Contains.
* Manipulating Stacks. * Manipulating Stacks.
## Basic Concepts ## Basic Concepts
@ -45,17 +45,17 @@ There are three ways you can get inventories:
* **Detached Inventories** - an inventory which is not attached to a node or player. * **Detached Inventories** - an inventory which is not attached to a node or player.
<figure> <figure>
<img src="{{ page.root }}/static/inventories_lists.png" alt="The player inventory formspec, with annotated list names."> <img src="{{ page.root }}/static/inventories_lists.png" alt="The player inventory formspec, with annotated list names.">
<figcaption> <figcaption>
This image shows the two inventories visible when you press i. This image shows the two inventories visible when you press i.
The gray boxes are inventory lists.<br /> The gray boxes are inventory lists.<br />
The creative inventory, left (in red) is detached and it made up of a The creative inventory, left (in red) is detached and it made up of a
single list.<br /> single list.<br />
The player inventory, right (in blue) is a player inventory The player inventory, right (in blue) is a player inventory
and is made up of three lists.<br /> and is made up of three lists.<br />
Note that the trash can is a <a href="formspecs.html">formspec</a> Note that the trash can is a <a href="formspecs.html">formspec</a>
element, and is not part of the inventory. element, and is not part of the inventory.
</figcaption> </figcaption>
</figure> </figure>
@ -124,11 +124,11 @@ They also have a width, which is used to divide them into a grid.
{% highlight lua %} {% highlight lua %}
if inv:set_size("main", 32) then if inv:set_size("main", 32) then
inv:set_width("main", 8) inv:set_width("main", 8)
print("size: " .. inv.get_size("main")) print("size: " .. inv.get_size("main"))
print("width: " .. inv:get_width("main")) print("width: " .. inv:get_width("main"))
else else
print("Error!") print("Error!")
end end
{% endhighlight %} {% endhighlight %}
@ -140,7 +140,7 @@ a list doesn't have a width or height, only the maximum number of stacks/slots.-
{% highlight lua %} {% highlight lua %}
if inv:is_empty("main") then if inv:is_empty("main") then
print("The list is empty!") print("The list is empty!")
end end
{% endhighlight %} {% endhighlight %}
@ -156,20 +156,20 @@ It will be in this form:
{% highlight lua %} {% highlight lua %}
{ {
list_one = { list_one = {
ItemStack, ItemStack,
ItemStack, ItemStack,
ItemStack, ItemStack,
ItemStack, ItemStack,
-- inv:get_size("list_one") elements -- inv:get_size("list_one") elements
}, },
list_two = { list_two = {
ItemStack, ItemStack,
ItemStack, ItemStack,
ItemStack, ItemStack,
ItemStack, ItemStack,
-- inv:get_size("list_two") elements -- inv:get_size("list_two") elements
} }
} }
{% endhighlight %} {% endhighlight %}
@ -193,11 +193,11 @@ It will be in this form:
{% highlight lua %} {% highlight lua %}
{ {
ItemStack, ItemStack,
ItemStack, ItemStack,
ItemStack, ItemStack,
ItemStack, ItemStack,
-- inv:get_size("list_one") elements -- inv:get_size("list_one") elements
} }
{% endhighlight %} {% endhighlight %}
@ -217,7 +217,7 @@ Please note that the sizes of lists will not change.
local stack = ItemStack("default:stone 99") local stack = ItemStack("default:stone 99")
local leftover = inv:add_item("main", stack) local leftover = inv:add_item("main", stack)
if leftover:get_count() > 0 then if leftover:get_count() > 0 then
print("Inventory is full! " .. leftover:get_count() .. " items weren't added") print("Inventory is full! " .. leftover:get_count() .. " items weren't added")
end end
{% endhighlight %} {% endhighlight %}
@ -227,7 +227,7 @@ end
{% highlight lua %} {% highlight lua %}
if not inv:room_for_item("main", stack) then if not inv:room_for_item("main", stack) then
print("Not enough room!") print("Not enough room!")
end end
{% endhighlight %} {% endhighlight %}
@ -246,7 +246,7 @@ are stacks of 99 + 95 + 6.
{% highlight lua %} {% highlight lua %}
if not inv:contains_item(listname, stack) then if not inv:contains_item(listname, stack) then
print("Item not in inventory!") print("Item not in inventory!")
end end
{% endhighlight %} {% endhighlight %}

View File

@ -33,9 +33,9 @@ You could alternatively create a blank ItemStack and fill it using methods:
{% highlight lua %} {% highlight lua %}
local items = ItemStack() local items = ItemStack()
if items:set_name("default:dirt") then if items:set_name("default:dirt") then
items:set_count(99) items:set_count(99)
else else
print("An error occured!") print("An error occured!")
end end
{% endhighlight %} {% endhighlight %}
@ -57,10 +57,10 @@ print(items:get_name()) -- default:stone
print(items:get_count()) -- 99 print(items:get_count()) -- 99
if items:set_name("default:dirt") then if items:set_name("default:dirt") then
print(items:get_name()) -- default:dirt print(items:get_name()) -- default:dirt
print(items:get_count()) -- 99 print(items:get_count()) -- 99
else else
error("This shouldn't happen") error("This shouldn't happen")
end end
{% endhighlight %} {% endhighlight %}

View File

@ -10,10 +10,10 @@ In this chapter we will talk about scripting in Lua, the tools required,
and go over some techniques which you will probably find useful. and go over some techniques which you will probably find useful.
* Tools * Tools
* Recommended Editors * Recommended Editors
* Integrated Programming Environments * Integrated Programming Environments
* Coding in Lua * Coding in Lua
* Selection * Selection
* Programming * Programming
* Local and Global * Local and Global
* Including other Lua Scripts * Including other Lua Scripts
@ -26,17 +26,17 @@ depending on what they mean. This allows you to spot mistakes.
{% highlight lua %} {% highlight lua %}
function ctf.post(team,msg) function ctf.post(team,msg)
if not ctf.team(team) then if not ctf.team(team) then
return false return false
end end
if not ctf.team(team).log then if not ctf.team(team).log then
ctf.team(team).log = {} ctf.team(team).log = {}
end end
table.insert(ctf.team(team).log,1,msg) table.insert(ctf.team(team).log,1,msg)
ctf.save() ctf.save()
return true return true
end end
{% endhighlight %} {% endhighlight %}
@ -69,7 +69,7 @@ One such IDE is Eclipse with the Koneki Lua plugin:
## Coding in Lua ## Coding in Lua
<div class="notice"> <div class="notice">
This section is a Work in Progress. May be unclear. This section is a Work in Progress. May be unclear.
</div> </div>
Programs are a series of commands that run one after another. Programs are a series of commands that run one after another.
@ -138,9 +138,9 @@ The most basic selection is the if statement. It looks like this:
local random_number = math.random(1, 100) -- Between 1 and 100. local random_number = math.random(1, 100) -- Between 1 and 100.
if random_number > 50 then if random_number > 50 then
print("Woohoo!") print("Woohoo!")
else else
print("No!") print("No!")
end end
{% endhighlight %} {% endhighlight %}
@ -166,7 +166,7 @@ That doesn't contain every possible operator, and you can combine operators like
{% highlight lua %} {% highlight lua %}
if not A and B then if not A and B then
print("Yay!") print("Yay!")
end end
{% endhighlight %} {% endhighlight %}
@ -180,7 +180,7 @@ local A = 5
local is_equal = (A == 5) local is_equal = (A == 5)
if is_equal then if is_equal then
print("Is equal!") print("Is equal!")
end end
{% endhighlight %} {% endhighlight %}
@ -211,13 +211,13 @@ A local variable is only accessible from where it is defined. Here are some exam
local one = 1 local one = 1
function myfunc() function myfunc()
-- Accessible from within this function -- Accessible from within this function
local two = one + one local two = one + one
if two == one then if two == one then
-- Accessible from within this if statement -- Accessible from within this if statement
local three = one + two local three = one + two
end end
end end
{% endhighlight %} {% endhighlight %}
@ -227,7 +227,7 @@ Whereas global variables can be accessed from anywhere in the script file, and f
my_global_variable = "blah" my_global_variable = "blah"
function one() function one()
my_global_variable = "three" my_global_variable = "three"
end end
print(my_global_variable) -- Output: "blah" print(my_global_variable) -- Output: "blah"
@ -243,11 +243,11 @@ Local variables must be identified as such.
{% highlight lua %} {% highlight lua %}
function one() function one()
foo = "bar" foo = "bar"
end end
function two() function two()
print(dump(foo)) -- Output: "bar" print(dump(foo)) -- Output: "bar"
end end
one() one()
@ -260,17 +260,17 @@ which show it is a string.
This is sloppy coding, and Minetest will in fact warn you about this: This is sloppy coding, and Minetest will in fact warn you about this:
[WARNING] Assigment to undeclared global 'foo' inside function at init.lua:2 [WARNING] Assigment to undeclared global 'foo' inside function at init.lua:2
To correct this, use "local": To correct this, use "local":
{% highlight lua %} {% highlight lua %}
function one() function one()
local foo = "bar" local foo = "bar"
end end
function two() function two()
print(dump(foo)) -- Output: nil print(dump(foo)) -- Output: nil
end end
one() one()
@ -286,7 +286,7 @@ as other mods could have functions of the same name.
{% highlight lua %} {% highlight lua %}
local function foo(bar) local function foo(bar)
return bar * 2 return bar * 2
end end
{% endhighlight %} {% endhighlight %}
@ -297,7 +297,7 @@ you add them all into a table with the same name as the mod:
mymod = {} mymod = {}
function mymod.foo(bar) function mymod.foo(bar)
return "foo" .. bar return "foo" .. bar
end end
-- In another mod, or script: -- In another mod, or script:

View File

@ -5,10 +5,10 @@ root: ../../
--- ---
<div class="notice"> <div class="notice">
<h2>This chapter is incomplete</h2> <h2>This chapter is incomplete</h2>
Some drawtypes have not been explained yet, Some drawtypes have not been explained yet,
and placeholder images are being used. and placeholder images are being used.
</div> </div>
## Introduction ## Introduction
@ -25,12 +25,12 @@ the title of the sections, except in lower case.
* Normal * Normal
* Airlike * Airlike
* Liquid * Liquid
* FlowingLiquid * FlowingLiquid
* Glasslike * Glasslike
* Glasslike_Framed * Glasslike_Framed
* Glasslike_Framed_Optional * Glasslike_Framed_Optional
* Allfaces * Allfaces
* Allfaces_Optional * Allfaces_Optional
* Torchlike * Torchlike
* Nodebox * Nodebox
@ -46,10 +46,10 @@ This article is not complete yet. These drawtypes are missing:
## Normal ## Normal
<figure class="right_image"> <figure class="right_image">
<img src="{{ page.root }}/static/drawtype_normal.png" alt="Normal Drawtype"> <img src="{{ page.root }}/static/drawtype_normal.png" alt="Normal Drawtype">
<figcaption> <figcaption>
Normal Drawtype Normal Drawtype
</figcaption> </figcaption>
</figure> </figure>
This is, well, the normal drawtypes. This is, well, the normal drawtypes.
@ -59,18 +59,18 @@ Notice how you don't need to declare the drawtype.
{% highlight lua %} {% highlight lua %}
minetest.register_node("mymod:diamond", { minetest.register_node("mymod:diamond", {
description = "Alien Diamond", description = "Alien Diamond",
tiles = { tiles = {
"mymod_diamond_up.png", "mymod_diamond_up.png",
"mymod_diamond_down.png", "mymod_diamond_down.png",
"mymod_diamond_right.png", "mymod_diamond_right.png",
"mymod_diamond_left.png", "mymod_diamond_left.png",
"mymod_diamond_back.png", "mymod_diamond_back.png",
"mymod_diamond_front.png" "mymod_diamond_front.png"
}, },
is_ground_content = true, is_ground_content = true,
groups = {cracky = 3}, groups = {cracky = 3},
drop = "mymod:diamond_fragments" drop = "mymod:diamond_fragments"
}) })
{% endhighlight %} {% endhighlight %}
@ -81,34 +81,34 @@ These nodes are see through and thus have no textures.
{% highlight lua %} {% highlight lua %}
minetest.register_node("myair:air", { minetest.register_node("myair:air", {
description = "MyAir (you hacker you!)", description = "MyAir (you hacker you!)",
drawtype = "airlike", drawtype = "airlike",
paramtype = "light", paramtype = "light",
-- ^ Allows light to propagate through the node with the -- ^ Allows light to propagate through the node with the
-- light value falling by 1 per node. -- light value falling by 1 per node.
sunlight_propagates = true, -- Sunlight shines through sunlight_propagates = true, -- Sunlight shines through
walkable = false, -- Would make the player collide with the air node walkable = false, -- Would make the player collide with the air node
pointable = false, -- You can't select the node pointable = false, -- You can't select the node
diggable = false, -- You can't dig the node diggable = false, -- You can't dig the node
buildable_to = true, -- Nodes can be replace this node. buildable_to = true, -- Nodes can be replace this node.
-- (you can place a node and remove the air node -- (you can place a node and remove the air node
-- that used to be there) -- that used to be there)
air_equivalent = true, air_equivalent = true,
drop = "", drop = "",
groups = {not_in_creative_inventory=1} groups = {not_in_creative_inventory=1}
}) })
{% endhighlight %} {% endhighlight %}
## Liquid ## Liquid
<figure class="right_image"> <figure class="right_image">
<img src="{{ page.root }}/static/drawtype_liquid.png" alt="Liquid Drawtype"> <img src="{{ page.root }}/static/drawtype_liquid.png" alt="Liquid Drawtype">
<figcaption> <figcaption>
Liquid Drawtype Liquid Drawtype
</figcaption> </figcaption>
</figure> </figure>
These nodes are complete liquid nodes, the liquid flows outwards from position These nodes are complete liquid nodes, the liquid flows outwards from position
@ -118,63 +118,63 @@ For each liquid node you should also have a flowing liquid node.
{% highlight lua %} {% highlight lua %}
-- Some properties have been removed as they are beyond the scope of this chapter. -- Some properties have been removed as they are beyond the scope of this chapter.
minetest.register_node("default:water_source", { minetest.register_node("default:water_source", {
drawtype = "liquid", drawtype = "liquid",
paramtype = "light", paramtype = "light",
inventory_image = minetest.inventorycube("default_water.png"), inventory_image = minetest.inventorycube("default_water.png"),
-- ^ this is required to stop the inventory image from being animated -- ^ this is required to stop the inventory image from being animated
tiles = { tiles = {
{ {
name = "default_water_source_animated.png", name = "default_water_source_animated.png",
animation = { animation = {
type = "vertical_frames", type = "vertical_frames",
aspect_w = 16, aspect_w = 16,
aspect_h = 16, aspect_h = 16,
length = 2.0 length = 2.0
} }
} }
}, },
special_tiles = { special_tiles = {
-- New-style water source material (mostly unused) -- New-style water source material (mostly unused)
{ {
name = "default_water_source_animated.png", name = "default_water_source_animated.png",
animation = {type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 2.0}, animation = {type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 2.0},
backface_culling = false, backface_culling = false,
} }
}, },
-- --
-- Behavior -- Behavior
-- --
walkable = false, -- The player falls through walkable = false, -- The player falls through
pointable = false, -- The player can't highlight it pointable = false, -- The player can't highlight it
diggable = false, -- The player can't dig it diggable = false, -- The player can't dig it
buildable_to = true, -- Nodes can be replace this node buildable_to = true, -- Nodes can be replace this node
alpha = 160, alpha = 160,
-- --
-- Liquid Properties -- Liquid Properties
-- --
drowning = 1, drowning = 1,
liquidtype = "source", liquidtype = "source",
liquid_alternative_flowing = "default:water_flowing", liquid_alternative_flowing = "default:water_flowing",
-- ^ when the liquid is flowing -- ^ when the liquid is flowing
liquid_alternative_source = "default:water_source", liquid_alternative_source = "default:water_source",
-- ^ when the liquid is a source -- ^ when the liquid is a source
liquid_viscosity = WATER_VISC, liquid_viscosity = WATER_VISC,
-- ^ how fast -- ^ how fast
liquid_range = 8, liquid_range = 8,
-- ^ how far -- ^ how far
post_effect_color = {a=64, r=100, g=100, b=200}, post_effect_color = {a=64, r=100, g=100, b=200},
-- ^ color of screen when the player is submerged -- ^ color of screen when the player is submerged
}) })
{% endhighlight %} {% endhighlight %}
@ -186,32 +186,32 @@ the same as the above example.
## Glasslike ## Glasslike
<figure class="right_image"> <figure class="right_image">
<img src="{{ page.root }}/static/drawtype_glasslike.png" alt="Glasslike Drawtype"> <img src="{{ page.root }}/static/drawtype_glasslike.png" alt="Glasslike Drawtype">
<figcaption> <figcaption>
Glasslike Drawtype Glasslike Drawtype
</figcaption> </figcaption>
</figure> </figure>
When you place multiple glasslike nodes together, you'll notice that the internal When you place multiple glasslike nodes together, you'll notice that the internal
edges are hidden, like this: edges are hidden, like this:
<figure> <figure>
<img src="{{ page.root }}/static/drawtype_glasslike_edges.png" alt="Glasslike's Edges"> <img src="{{ page.root }}/static/drawtype_glasslike_edges.png" alt="Glasslike's Edges">
<figcaption> <figcaption>
Glasslike's Edges Glasslike's Edges
</figcaption> </figcaption>
</figure> </figure>
{% highlight lua %} {% highlight lua %}
minetest.register_node("default:obsidian_glass", { minetest.register_node("default:obsidian_glass", {
description = "Obsidian Glass", description = "Obsidian Glass",
drawtype = "glasslike", drawtype = "glasslike",
tiles = {"default_obsidian_glass.png"}, tiles = {"default_obsidian_glass.png"},
paramtype = "light", paramtype = "light",
is_ground_content = false, is_ground_content = false,
sunlight_propagates = true, sunlight_propagates = true,
sounds = default.node_sound_glass_defaults(), sounds = default.node_sound_glass_defaults(),
groups = {cracky=3,oddly_breakable_by_hand=3}, groups = {cracky=3,oddly_breakable_by_hand=3},
}) })
{% endhighlight %} {% endhighlight %}
@ -221,26 +221,26 @@ This makes the node's edge go around the whole thing with a 3D effect, rather
than individual nodes, like the following: than individual nodes, like the following:
<figure> <figure>
<img src="{{ page.root }}/static/drawtype_glasslike_framed.png" alt="Glasslike_framed's Edges"> <img src="{{ page.root }}/static/drawtype_glasslike_framed.png" alt="Glasslike_framed's Edges">
<figcaption> <figcaption>
Glasslike_Framed's Edges Glasslike_Framed's Edges
</figcaption> </figcaption>
</figure> </figure>
{% highlight lua %} {% highlight lua %}
minetest.register_node("default:glass", { minetest.register_node("default:glass", {
description = "Glass", description = "Glass",
drawtype = "glasslike_framed", drawtype = "glasslike_framed",
tiles = {"default_glass.png", "default_glass_detail.png"}, tiles = {"default_glass.png", "default_glass_detail.png"},
inventory_image = minetest.inventorycube("default_glass.png"), inventory_image = minetest.inventorycube("default_glass.png"),
paramtype = "light", paramtype = "light",
sunlight_propagates = true, -- Sunlight can shine through block sunlight_propagates = true, -- Sunlight can shine through block
is_ground_content = false, -- Stops caves from being generated over this node. is_ground_content = false, -- Stops caves from being generated over this node.
groups = {cracky = 3, oddly_breakable_by_hand = 3}, groups = {cracky = 3, oddly_breakable_by_hand = 3},
sounds = default.node_sound_glass_defaults() sounds = default.node_sound_glass_defaults()
}) })
{% endhighlight %} {% endhighlight %}
@ -251,10 +251,10 @@ minetest.register_node("default:glass", {
## Allfaces ## Allfaces
<figure class="right_image"> <figure class="right_image">
<img src="{{ page.root }}/static/drawtype_allfaces.png" alt="Allfaces drawtype"> <img src="{{ page.root }}/static/drawtype_allfaces.png" alt="Allfaces drawtype">
<figcaption> <figcaption>
Allfaces drawtype Allfaces drawtype
</figcaption> </figcaption>
</figure> </figure>
Allfaces nodes are partially transparent nodes - they have holes on Allfaces nodes are partially transparent nodes - they have holes on
@ -264,9 +264,9 @@ Leaves in vanilla minetest_game use this drawtype.
{% highlight lua %} {% highlight lua %}
minetest.register_node("default:leaves", { minetest.register_node("default:leaves", {
description = "Leaves", description = "Leaves",
drawtype = "allfaces_optional", drawtype = "allfaces_optional",
tiles = {"default_leaves.png"} tiles = {"default_leaves.png"}
}) })
{% endhighlight %} {% endhighlight %}
@ -285,38 +285,38 @@ items which need to have different textures depending on where they are placed.
{% highlight lua %} {% highlight lua %}
minetest.register_node("foobar:torch", { minetest.register_node("foobar:torch", {
description = "Foobar Torch", description = "Foobar Torch",
drawtype = "torchlike", drawtype = "torchlike",
tiles = { tiles = {
{"foobar_torch_floor.png"}, {"foobar_torch_floor.png"},
{"foobar_torch_ceiling.png"}, {"foobar_torch_ceiling.png"},
{"foobar_torch_wall.png"} {"foobar_torch_wall.png"}
}, },
inventory_image = "foobar_torch_floor.png", inventory_image = "foobar_torch_floor.png",
wield_image = "default_torch_floor.png", wield_image = "default_torch_floor.png",
light_source = LIGHT_MAX-1, light_source = LIGHT_MAX-1,
-- Determines how the torch is selected, ie: the wire box around it. -- Determines how the torch is selected, ie: the wire box around it.
-- each value is { x1, y1, z1, x2, y2, z2 } -- each value is { x1, y1, z1, x2, y2, z2 }
-- (x1, y1, y1) is the bottom front left corner -- (x1, y1, y1) is the bottom front left corner
-- (x2, y2, y2) is the opposite - top back right. -- (x2, y2, y2) is the opposite - top back right.
-- Similar to the nodebox format. -- Similar to the nodebox format.
selection_box = { selection_box = {
type = "wallmounted", type = "wallmounted",
wall_top = {-0.1, 0.5-0.6, -0.1, 0.1, 0.5, 0.1}, wall_top = {-0.1, 0.5-0.6, -0.1, 0.1, 0.5, 0.1},
wall_bottom = {-0.1, -0.5, -0.1, 0.1, -0.5+0.6, 0.1}, wall_bottom = {-0.1, -0.5, -0.1, 0.1, -0.5+0.6, 0.1},
wall_side = {-0.5, -0.3, -0.1, -0.5+0.3, 0.3, 0.1}, wall_side = {-0.5, -0.3, -0.1, -0.5+0.3, 0.3, 0.1},
} }
}) })
{% endhighlight %} {% endhighlight %}
## Nodebox ## Nodebox
<figure class="right_image"> <figure class="right_image">
<img src="{{ page.root }}/static/drawtype_nodebox.gif" alt="Nodebox drawtype"> <img src="{{ page.root }}/static/drawtype_nodebox.gif" alt="Nodebox drawtype">
<figcaption> <figcaption>
Nodebox drawtype Nodebox drawtype
</figcaption> </figcaption>
</figure> </figure>
Nodeboxes allow you to create a node which is not cubic, but is instead made out Nodeboxes allow you to create a node which is not cubic, but is instead made out
@ -324,15 +324,15 @@ of as many cuboids as you like.
{% highlight lua %} {% highlight lua %}
minetest.register_node("stairs:stair_stone", { minetest.register_node("stairs:stair_stone", {
drawtype = "nodebox", drawtype = "nodebox",
paramtype = "light", paramtype = "light",
node_box = { node_box = {
type = "fixed", type = "fixed",
fixed = { fixed = {
{-0.5, -0.5, -0.5, 0.5, 0, 0.5}, {-0.5, -0.5, -0.5, 0.5, 0, 0.5},
{-0.5, 0, 0, 0.5, 0.5, 0.5}, {-0.5, 0, 0, 0.5, 0.5, 0.5},
}, },
} }
}) })
{% endhighlight %} {% endhighlight %}
@ -357,24 +357,24 @@ Sometimes you want different nodeboxes for when it is placed on the floor, wall,
{% highlight lua %} {% highlight lua %}
minetest.register_node("default:sign_wall", { minetest.register_node("default:sign_wall", {
drawtype = "nodebox", drawtype = "nodebox",
node_box = { node_box = {
type = "wallmounted", type = "wallmounted",
-- Ceiling -- Ceiling
wall_top = { wall_top = {
{-0.4375, 0.4375, -0.3125, 0.4375, 0.5, 0.3125} {-0.4375, 0.4375, -0.3125, 0.4375, 0.5, 0.3125}
}, },
-- Floor -- Floor
wall_bottom = { wall_bottom = {
{-0.4375, -0.5, -0.3125, 0.4375, -0.4375, 0.3125} {-0.4375, -0.5, -0.3125, 0.4375, -0.4375, 0.3125}
}, },
-- Wall -- Wall
wall_side = { wall_side = {
{-0.5, -0.3125, -0.4375, -0.4375, 0.3125, 0.4375} {-0.5, -0.3125, -0.4375, -0.4375, 0.3125, 0.4375}
} }
}, },
}) })
{% endhighlight %} {% endhighlight %}

View File

@ -53,11 +53,11 @@ local meta = minetest.get_meta(pos)
local value = meta:get_string("key") local value = meta:get_string("key")
if value then if value then
print(value) print(value)
else else
-- value == nil -- value == nil
-- metadata of key "key" does not exist -- metadata of key "key" does not exist
print(value) print(value)
end end
{% endhighlight %} {% endhighlight %}
@ -75,9 +75,9 @@ In order to do booleans, you should use `get_string` and `minetest.is_yes`:
local value = minetest.is_yes(meta:get_string("key")) local value = minetest.is_yes(meta:get_string("key"))
if value then if value then
print("is yes") print("is yes")
else else
print("is no") print("is no")
end end
{% endhighlight %} {% endhighlight %}

View File

@ -23,7 +23,7 @@ Each item, whether that be a node, craftitem, tool, or entity, has an item strin
This is sometimes referred to as registered name or just name. This is sometimes referred to as registered name or just name.
A string in programming terms is a piece of text. A string in programming terms is a piece of text.
modname:itemname modname:itemname
The modname is the name of the folder your mod is in. The modname is the name of the folder your mod is in.
You may call the itemname anything you like; however, it should be relevant to You may call the itemname anything you like; however, it should be relevant to
@ -55,8 +55,8 @@ They are used in recipes to create other items, or they can be used by the playe
{% highlight lua %} {% highlight lua %}
minetest.register_craftitem("mymod:diamond_fragments", { minetest.register_craftitem("mymod:diamond_fragments", {
description = "Alien Diamond Fragments", description = "Alien Diamond Fragments",
inventory_image = "mymod_diamond_fragments.png" inventory_image = "mymod_diamond_fragments.png"
}) })
{% endhighlight %} {% endhighlight %}
@ -70,9 +70,9 @@ Foods are items that cure health. To create a food item you need to define the o
{% highlight lua %} {% highlight lua %}
minetest.register_craftitem("mymod:mudpie", { minetest.register_craftitem("mymod:mudpie", {
description = "Alien Mud Pie", description = "Alien Mud Pie",
inventory_image = "myfood_mudpie.png", inventory_image = "myfood_mudpie.png",
on_use = minetest.item_eat(20) on_use = minetest.item_eat(20)
}) })
{% endhighlight %} {% endhighlight %}
@ -83,7 +83,7 @@ Hitpoints don't have to be integers (whole numbers), they can be decimals.
Sometimes you may want a food to be replaced with another item when being eaten, Sometimes you may want a food to be replaced with another item when being eaten,
for example smaller pieces of cake or bones after eating meat. To do this, use: for example smaller pieces of cake or bones after eating meat. To do this, use:
minetest.item_eat(hp, replace_with_item) minetest.item_eat(hp, replace_with_item)
Where replace_with_item is an item string. Where replace_with_item is an item string.
@ -94,28 +94,28 @@ such as send a message to the player?
{% highlight lua %} {% highlight lua %}
minetest.register_craftitem("mymod:mudpie", { minetest.register_craftitem("mymod:mudpie", {
description = "Alien Mud Pie", description = "Alien Mud Pie",
inventory_image = "myfood_mudpie.png", inventory_image = "myfood_mudpie.png",
on_use = function(itemstack, user, pointed_thing) on_use = function(itemstack, user, pointed_thing)
hp_change = 20 hp_change = 20
replace_with_item = nil replace_with_item = nil
minetest.chat_send_player(user:get_player_name(), "You ate an alien mud pie!") minetest.chat_send_player(user:get_player_name(), "You ate an alien mud pie!")
-- Support for hunger mods using minetest.register_on_item_eat -- Support for hunger mods using minetest.register_on_item_eat
for _ , callback in pairs(minetest.registered_on_item_eats) do for _ , callback in pairs(minetest.registered_on_item_eats) do
local result = callback(hp_change, replace_with_item, itemstack, user, pointed_thing) local result = callback(hp_change, replace_with_item, itemstack, user, pointed_thing)
if result then if result then
return result return result
end end
end end
if itemstack:take_item() ~= nil then if itemstack:take_item() ~= nil then
user:set_hp(user:get_hp() + hp_change) user:set_hp(user:get_hp() + hp_change)
end end
return itemstack return itemstack
end end
}) })
{% endhighlight %} {% endhighlight %}
@ -133,10 +133,10 @@ definition table; however, you need to set the textures for the faces of the cub
{% highlight lua %} {% highlight lua %}
minetest.register_node("mymod:diamond", { minetest.register_node("mymod:diamond", {
description = "Alien Diamond", description = "Alien Diamond",
tiles = {"mymod_diamond.png"}, tiles = {"mymod_diamond.png"},
is_ground_content = true, is_ground_content = true,
groups = {cracky=3, stone=1} groups = {cracky=3, stone=1}
}) })
{% endhighlight %} {% endhighlight %}
@ -155,19 +155,19 @@ a negative direction means that it is facing negative co-ordinates.
{% highlight lua %} {% highlight lua %}
minetest.register_node("mymod:diamond", { minetest.register_node("mymod:diamond", {
description = "Alien Diamond", description = "Alien Diamond",
tiles = { tiles = {
"mymod_diamond_up.png", "mymod_diamond_up.png",
"mymod_diamond_down.png", "mymod_diamond_down.png",
"mymod_diamond_right.png", "mymod_diamond_right.png",
"mymod_diamond_left.png", "mymod_diamond_left.png",
"mymod_diamond_back.png", "mymod_diamond_back.png",
"mymod_diamond_front.png" "mymod_diamond_front.png"
}, },
is_ground_content = true, is_ground_content = true,
groups = {cracky = 3}, groups = {cracky = 3},
drop = "mymod:diamond_fragments" drop = "mymod:diamond_fragments"
-- ^ Rather than dropping diamond, drop mymod:diamond_fragments -- ^ Rather than dropping diamond, drop mymod:diamond_fragments
}) })
{% endhighlight %} {% endhighlight %}
@ -182,7 +182,7 @@ identified by the ``type`` property.
* shapeless - It doesn't matter where the ingredients are, * shapeless - It doesn't matter where the ingredients are,
just that there is the right amount. just that there is the right amount.
* cooking - Recipes for the furnace to use. * cooking - Recipes for the furnace to use.
* fuel - Defines items which can be burned in furnaces. * fuel - Defines items which can be burned in furnaces.
* tool_repair - Used to allow the repairing of tools. * tool_repair - Used to allow the repairing of tools.
Craft recipes do not use Item Strings to uniquely identify themselves. Craft recipes do not use Item Strings to uniquely identify themselves.
@ -196,12 +196,12 @@ right place for it to work.
{% highlight lua %} {% highlight lua %}
minetest.register_craft({ minetest.register_craft({
output = "mymod:diamond_chair 99", output = "mymod:diamond_chair 99",
recipe = { recipe = {
{"mymod:diamond_fragments", "", ""}, {"mymod:diamond_fragments", "", ""},
{"mymod:diamond_fragments", "mymod:diamond_fragments", ""}, {"mymod:diamond_fragments", "mymod:diamond_fragments", ""},
{"mymod:diamond_fragments", "mymod:diamond_fragments", ""} {"mymod:diamond_fragments", "mymod:diamond_fragments", ""}
} }
}) })
{% endhighlight %} {% endhighlight %}
@ -219,12 +219,12 @@ allows the recipe to be crafted if it was all moved one place to the right.
{% highlight lua %} {% highlight lua %}
minetest.register_craft({ minetest.register_craft({
output = "mymod:diamond_chair", output = "mymod:diamond_chair",
recipe = { recipe = {
{"mymod:diamond_fragments", ""}, {"mymod:diamond_fragments", ""},
{"mymod:diamond_fragments", "mymod:diamond_fragments"}, {"mymod:diamond_fragments", "mymod:diamond_fragments"},
{"mymod:diamond_fragments", "mymod:diamond_fragments"} {"mymod:diamond_fragments", "mymod:diamond_fragments"}
} }
}) })
{% endhighlight %} {% endhighlight %}
@ -237,9 +237,9 @@ need to be in any specific place for it to work.
{% highlight lua %} {% highlight lua %}
minetest.register_craft({ minetest.register_craft({
type = "shapeless", type = "shapeless",
output = "mymod:diamond", output = "mymod:diamond",
recipe = {"mymod:diamond_fragments", "mymod:diamond_fragments", "mymod:diamond_fragments"} recipe = {"mymod:diamond_fragments", "mymod:diamond_fragments", "mymod:diamond_fragments"}
}) })
{% endhighlight %} {% endhighlight %}
@ -256,10 +256,10 @@ For example, you use a cooking recipe to turn ores into bars.
{% highlight lua %} {% highlight lua %}
minetest.register_craft({ minetest.register_craft({
type = "cooking", type = "cooking",
output = "mymod:diamond_fragments", output = "mymod:diamond_fragments",
recipe = "default:coalblock", recipe = "default:coalblock",
cooktime = 10, cooktime = 10,
}) })
{% endhighlight %} {% endhighlight %}
@ -279,9 +279,9 @@ what can be burned in furnaces and other cooking tools from mods.
{% highlight lua %} {% highlight lua %}
minetest.register_craft({ minetest.register_craft({
type = "fuel", type = "fuel",
recipe = "mymod:diamond", recipe = "mymod:diamond",
burntime = 300, burntime = 300,
}) })
{% endhighlight %} {% endhighlight %}

View File

@ -21,13 +21,13 @@ puts the caller in low G:
{% highlight lua %} {% highlight lua %}
minetest.register_chatcommand("antigravity", { minetest.register_chatcommand("antigravity", {
func = function(name, param) func = function(name, param)
local player = minetest.get_player_by_name(name) local player = minetest.get_player_by_name(name)
player:set_physics_override({ player:set_physics_override({
gravity = 0.1 -- set gravity to 10% of its original value gravity = 0.1 -- set gravity to 10% of its original value
-- (0.1 * 9.81) -- (0.1 * 9.81)
}) })
end end
}) })
{% endhighlight %} {% endhighlight %}

View File

@ -44,8 +44,8 @@ given to them.
{% highlight lua %} {% highlight lua %}
minetest.register_privilege("vote", { minetest.register_privilege("vote", {
description = "Can vote on issues", description = "Can vote on issues",
give_to_singleplayer = true give_to_singleplayer = true
}) })
{% endhighlight %} {% endhighlight %}
@ -54,7 +54,7 @@ value when not specified:
{% highlight lua %} {% highlight lua %}
minetest.register_privilege("vote", { minetest.register_privilege("vote", {
description = "Can vote on issues" description = "Can vote on issues"
}) })
{% endhighlight %} {% endhighlight %}
@ -64,8 +64,8 @@ There is a quicker way of checking that a player has all the required privileges
{% highlight lua %} {% highlight lua %}
local has, missing = minetest.check_player_privs(player_or_name, { local has, missing = minetest.check_player_privs(player_or_name, {
interact = true, interact = true,
vote = true }) vote = true })
{% endhighlight %} {% endhighlight %}
`has` is true if the player has all the privileges needed.\\ `has` is true if the player has all the privileges needed.\\
@ -74,18 +74,18 @@ of missing privileges<sup>[checking needed]</sup>.
{% highlight lua %} {% highlight lua %}
if minetest.check_player_privs(name, {interact=true, vote=true}) then if minetest.check_player_privs(name, {interact=true, vote=true}) then
print("Player has all privs!") print("Player has all privs!")
else else
print("Player is missing some privs!") print("Player is missing some privs!")
end end
local has, missing = minetest.check_player_privs(name, { local has, missing = minetest.check_player_privs(name, {
interact = true, interact = true,
vote = true }) vote = true })
if has then if has then
print("Player has all privs!") print("Player has all privs!")
else else
print("Player is missing privs: " .. dump(missing)) print("Player is missing privs: " .. dump(missing))
end end
{% endhighlight %} {% endhighlight %}
@ -103,9 +103,9 @@ Running that example may give the following:
{% highlight lua %} {% highlight lua %}
{ {
fly = true, fly = true,
interact = true, interact = true,
shout = true shout = true
} }
{% endhighlight %} {% endhighlight %}
@ -113,8 +113,8 @@ To set a player's privs, you use `minetest.set_player_privs`:
{% highlight lua %} {% highlight lua %}
minetest.set_player_privs(name, { minetest.set_player_privs(name, {
interact = true, interact = true,
shout = true }) shout = true })
{% endhighlight %} {% endhighlight %}
To grant a player some privs, you would use a mixture of those two: To grant a player some privs, you would use a mixture of those two:
@ -128,12 +128,12 @@ minetest.set_player_privs(name, privs)
## Adding privileges to basic_privs ## Adding privileges to basic_privs
<div class="notice"> <div class="notice">
<h2>Workaround / PR pending</h2> <h2>Workaround / PR pending</h2>
This is a workaround for a missing feature. This is a workaround for a missing feature.
I have submitted a I have submitted a
<a href="https://github.com/minetest/minetest/pull/3976">pull request / patch</a> <a href="https://github.com/minetest/minetest/pull/3976">pull request / patch</a>
to make it so you don't need to edit builtin to add a priv to basic_privs. to make it so you don't need to edit builtin to add a priv to basic_privs.
</div> </div>
To allow people with basic_privs to grant and revoke your priv, you'll To allow people with basic_privs to grant and revoke your priv, you'll
@ -143,8 +143,8 @@ In both grant and revoke, change the following if statement:
{% highlight lua %} {% highlight lua %}
if priv ~= "interact" and priv ~= "shout" and if priv ~= "interact" and priv ~= "shout" and
not core.check_player_privs(name, {privs=true}) then not core.check_player_privs(name, {privs=true}) then
return false, "Your privileges are insufficient." return false, "Your privileges are insufficient."
end end
{% endhighlight %} {% endhighlight %}
@ -152,7 +152,7 @@ For example, to add vote:
{% highlight lua %} {% highlight lua %}
if priv ~= "interact" and priv ~= "shout" and priv ~= "vote" and if priv ~= "interact" and priv ~= "shout" and priv ~= "vote" and
not core.check_player_privs(name, {privs=true}) then not core.check_player_privs(name, {privs=true}) then
return false, "Your privileges are insufficient." return false, "Your privileges are insufficient."
end end
{% endhighlight %} {% endhighlight %}

View File

@ -42,29 +42,29 @@ You license your code under LGPL 2.1 and your art under CC-BY-SA.
Add this copyright notice to your README.txt, or as a new file called LICENSE.txt Add this copyright notice to your README.txt, or as a new file called LICENSE.txt
License for Code License for Code
---------------- ----------------
Copyright (C) 2010-2013 Your Name <emailaddress> Copyright (C) 2010-2013 Your Name <emailaddress>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc., with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
License for Textures, Models and Sounds License for Textures, Models and Sounds
--------------------------------------- ---------------------------------------
CC-BY-SA 3.0 UNPORTED. Created by Your Name CC-BY-SA 3.0 UNPORTED. Created by Your Name
### WTFPL or CC0 ### WTFPL or CC0
@ -97,8 +97,8 @@ Be concise without being too vague. This is displayed in the mod store.
For example: For example:
GOOD: Adds soups, cakes, bakes and juices. The food mod which supports the most ingredients. GOOD: Adds soups, cakes, bakes and juices. The food mod which supports the most ingredients.
BAD: The food mod for Minetest. BAD: The food mod for Minetest.
### screenshot.png ### screenshot.png
@ -152,10 +152,10 @@ On the create a topic page, see below, go to the "Upload Attachment" tab at the
Click browse and select the zipped file. I suggest that you enter the version of your mod in the comment field. Click browse and select the zipped file. I suggest that you enter the version of your mod in the comment field.
<figure> <figure>
<img src="{{ page.root }}/static/releasing_attachments.png" alt="Upload Attachment"> <img src="{{ page.root }}/static/releasing_attachments.png" alt="Upload Attachment">
<figcaption> <figcaption>
Upload Attachment tab. Upload Attachment tab.
</figcaption> </figcaption>
</figure> </figure>
## Forum Topic ## Forum Topic
@ -184,30 +184,30 @@ You should also include screenshots of your mod in action, if relevant.
Here is an example. The Minetest forum uses bbcode for formating. Here is an example. The Minetest forum uses bbcode for formating.
Adds magic, rainbows and other special things. Adds magic, rainbows and other special things.
See download attached. See download attached.
[b]Version:[/b] 1.1 [b]Version:[/b] 1.1
[b]License:[/b] LGPL 2.1 or later [b]License:[/b] LGPL 2.1 or later
Dependencies: default mod (found in minetest_game) Dependencies: default mod (found in minetest_game)
Report bugs or request help on the forum topic. Report bugs or request help on the forum topic.
[h]Installation[/h] [h]Installation[/h]
Unzip the archive, rename the folder to to modfoldername and Unzip the archive, rename the folder to to modfoldername and
place it in minetest/mods/minetest/ place it in minetest/mods/minetest/
( GNU/Linux: If you use a system-wide installation place ( GNU/Linux: If you use a system-wide installation place
it in ~/.minetest/mods/minetest/. ) it in ~/.minetest/mods/minetest/. )
( If you only want this to be used in a single world, place ( If you only want this to be used in a single world, place
the folder in worldmods/ in your worlddirectory. ) the folder in worldmods/ in your worlddirectory. )
For further information or help see: For further information or help see:
[url]http://wiki.minetest.com/wiki/Installing_Mods[/url] [url]http://wiki.minetest.com/wiki/Installing_Mods[/url]
If you modify the above example for your mod topic, remember to If you modify the above example for your mod topic, remember to
change "modfldername" to the name of the folder your mod should be change "modfldername" to the name of the folder your mod should be
@ -224,16 +224,16 @@ Subject of topic must be in one of these formats:
### Profit ### Profit
<figure> <figure>
<img src="{{ page.root }}/static/releasing_profit.png" alt="Profit"> <img src="{{ page.root }}/static/releasing_profit.png" alt="Profit">
<figcaption style="display:none;"> <figcaption style="display:none;">
Profit Profit
</figcaption> </figcaption>
</figure> </figure>
## Appendix: Readme and Forum Generator ## Appendix: Readme and Forum Generator
<noscript> <noscript>
<p>Javascript is required for this section!</p> <p>Javascript is required for this section!</p>
</noscript> </noscript>
Title: <input id="t_title" value="My Super Special Mod"><br /> Title: <input id="t_title" value="My Super Special Mod"><br />
@ -264,10 +264,10 @@ Unzip the archive, rename the folder to mysuperspecial and
place it in minetest/mods/ place it in minetest/mods/
( GNU/Linux: If you use a system-wide installation place ( GNU/Linux: If you use a system-wide installation place
it in ~/.minetest/mods/. ) it in ~/.minetest/mods/. )
( If you only want this to be used in a single world, place ( If you only want this to be used in a single world, place
the folder in worldmods/ in your worlddirectory. ) the folder in worldmods/ in your worlddirectory. )
For further information or help see: For further information or help see:
http://wiki.minetest.com/wiki/Installing_Mods</code></pre> http://wiki.minetest.com/wiki/Installing_Mods</code></pre>
@ -287,92 +287,92 @@ Unzip the archive, rename the folder to mysuperspecial and
place it in minetest/mods/ place it in minetest/mods/
( GNU/Linux: If you use a system-wide installation place ( GNU/Linux: If you use a system-wide installation place
it in ~/.minetest/mods/. ) it in ~/.minetest/mods/. )
( If you only want this to be used in a single world, place ( If you only want this to be used in a single world, place
the folder in worldmods/ in your worlddirectory. ) the folder in worldmods/ in your worlddirectory. )
For further information or help see: For further information or help see:
http://wiki.minetest.com/wiki/Installing_Mods</code></pre> http://wiki.minetest.com/wiki/Installing_Mods</code></pre>
<script src="http://blog.rubenwardy.com/static/jquery.min.js"></script> <script src="http://blog.rubenwardy.com/static/jquery.min.js"></script>
<script>function regen() { <script>function regen() {
var title = $("#t_title").val(); var title = $("#t_title").val();
var name = $("#t_name").val(); var name = $("#t_name").val();
var desc = $("#t_desc").val(); var desc = $("#t_desc").val();
var version = $("#t_version").val(); var version = $("#t_version").val();
var license = $("#t_license").val(); var license = $("#t_license").val();
var dep = $("#t_dep").val(); var dep = $("#t_dep").val();
var add = $("#t_add").val(); var add = $("#t_add").val();
var download = $("#t_download").val(); var download = $("#t_download").val();
{ {
var res = ((title.length > 0) ? title : name) + "\n"; var res = ((title.length > 0) ? title : name) + "\n";
var header_count = res.length - 1; var header_count = res.length - 1;
for (var i = 0; i < header_count; i++) { for (var i = 0; i < header_count; i++) {
res += "="; res += "=";
} }
res += "\n\n"; res += "\n\n";
res += desc + "\n\n"; res += desc + "\n\n";
if (version != "") { if (version != "") {
res += "Version: " + version + "\n"; res += "Version: " + version + "\n";
} }
res += "License: " + license + "\n"; res += "License: " + license + "\n";
res += "Dependencies: " + dep + "\n\n"; res += "Dependencies: " + dep + "\n\n";
if (add != "") { if (add != "") {
res += add + "\n\n"; res += add + "\n\n";
} }
res += "Installation\n------------\n\nUnzip the archive, rename the folder to "; res += "Installation\n------------\n\nUnzip the archive, rename the folder to ";
res += name + " and\nplace it in minetest/mods/\n\n"; res += name + " and\nplace it in minetest/mods/\n\n";
res += "( GNU/Linux: If you use a system-wide installation place\n" + res += "( GNU/Linux: If you use a system-wide installation place\n" +
"\tit in ~/.minetest/mods/. )\n\n" + "\tit in ~/.minetest/mods/. )\n\n" +
"( If you only want this to be used in a single world, place\n" + "( If you only want this to be used in a single world, place\n" +
"\tthe folder in worldmods/ in your worlddirectory. )\n\n" + "\tthe folder in worldmods/ in your worlddirectory. )\n\n" +
"For further information or help see:\n" + "For further information or help see:\n" +
"http://wiki.minetest.com/wiki/Installing_Mods\n"; "http://wiki.minetest.com/wiki/Installing_Mods\n";
$("#readme").text(res); $("#readme").text(res);
} }
{ {
var res = desc + "\n\n"; var res = desc + "\n\n";
if (version != "") { if (version != "") {
res += "[b]Version:[/b] " + version + "\n"; res += "[b]Version:[/b] " + version + "\n";
} }
res += "[b]License:[/b] " + license + "\n"; res += "[b]License:[/b] " + license + "\n";
res += "[b]Dependencies:[/b] " + dep + "\n"; res += "[b]Dependencies:[/b] " + dep + "\n";
res += "[b]Download:[/b] " + download + "\n\n"; res += "[b]Download:[/b] " + download + "\n\n";
if (add != "") { if (add != "") {
res += add + "\n\n"; res += add + "\n\n";
} }
res += "[h]Installation[/h]\n\nUnzip the archive, rename the folder to "; res += "[h]Installation[/h]\n\nUnzip the archive, rename the folder to ";
res += name + " and\nplace it in minetest/mods/\n\n"; res += name + " and\nplace it in minetest/mods/\n\n";
res += "( GNU/Linux: If you use a system-wide installation place\n" + res += "( GNU/Linux: If you use a system-wide installation place\n" +
"\tit in ~/.minetest/mods/. )\n\n" + "\tit in ~/.minetest/mods/. )\n\n" +
"( If you only want this to be used in a single world, place\n" + "( If you only want this to be used in a single world, place\n" +
"\tthe folder in worldmods/ in your worlddirectory. )\n\n" + "\tthe folder in worldmods/ in your worlddirectory. )\n\n" +
"For further information or help see:\n" + "For further information or help see:\n" +
"http://wiki.minetest.com/wiki/Installing_Mods\n"; "http://wiki.minetest.com/wiki/Installing_Mods\n";
$("#forum").text(res); $("#forum").text(res);
} }
} }
$(function() { $(function() {
jQuery('input').on('input propertychange paste', regen); jQuery('input').on('input propertychange paste', regen);
jQuery('textarea').on('input propertychange paste', regen); jQuery('textarea').on('input propertychange paste', regen);
}); });
</script> </script>

View File

@ -45,12 +45,12 @@ Written by rubenwardy.\\
License: [CC-BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/) License: [CC-BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/)
<!--<form class="leave_comment" action="http://pooleapp.com/stash/74bf2dfb-4c01-423c-b48a-e002ed70bbc1/" method="post"> <!--<form class="leave_comment" action="http://pooleapp.com/stash/74bf2dfb-4c01-423c-b48a-e002ed70bbc1/" method="post">
<input type="hidden" name="redirect_to" <input type="hidden" name="redirect_to"
value="http://rubenwardy.com/minetest_modding_book/thank_you.html" /> value="http://rubenwardy.com/minetest_modding_book/thank_you.html" />
Nickname (optional): <input class="name" name="name" placeholder="Your Name" type="text"><br /> Nickname (optional): <input class="name" name="name" placeholder="Your Name" type="text"><br />
Contact method (email or forum name, optional): <input name="contact" type="text"><br /> Contact method (email or forum name, optional): <input name="contact" type="text"><br />
Feedback: Feedback:
<textarea name="comment" required="" style="display:block;min-width: 90%;min-height:100px;"></textarea> <textarea name="comment" required="" style="display:block;min-width: 90%;min-height:100px;"></textarea>
<input value="Leave Feedback" type="submit"> <input value="Leave Feedback" type="submit">
</form>--> </form>-->