3 -- == DEBUG SETTINGS ==
4 -- If true, item spawner nodes become visible and pointable.
5 local edit_item_spawners
= minetest
.settings
:get_bool("tutorial_debug_edit_item_spawners")
7 -- See tutorial_mapgen/init.lua
8 local map_editing
= minetest
.settings
:get_bool("tutorial_debug_map_editing")
10 minetest
.settings
:set_bool("creative_mode", true)
13 -- == END OF DEBUG SETTINGS ==
17 if (minetest
.get_modpath("intllib")) then
20 S
= function ( s
) return s
end
23 -- Saves tutorial state into file
24 function tutorial
.save_state()
25 local str
= minetest
.serialize(tutorial
.state
)
26 local filepath
= minetest
.get_worldpath().."/tutorialdata.mt"
27 local file
= io
.open(filepath
, "w+")
30 minetest
.log("action", "[tutorial] Tutorial state has been written into "..filepath
..".")
32 minetest
.log("error", "[tutorial] An attempt to save the tutorial state into "..filepath
.." failed.")
38 -- load tutorial state from file
40 local filepath
= minetest
.get_worldpath().."/tutorialdata.mt"
41 local file
= io
.open(filepath
, "r")
44 local string = file
:read()
46 if(string ~= nil) then
47 tutorial
.state
= minetest
.deserialize(string)
48 minetest
.log("action", "[tutorial] Tutorial state has been read from "..filepath
..".")
55 -- Is this the first time the player joins this tutorial? (used for spawn position)
56 tutorial
.state
.first_join
= true
57 -- Has the regular introduction text been shown yet?
58 tutorial
.state
.intro_text
= false
59 -- These variables store wheather a message for those events has been shown yet.
60 tutorial
.state
.first_gold
= false
61 tutorial
.state
.last_gold
= false
62 tutorial
.state
.first_diamond
= false
63 tutorial
.state
.last_diamond
= false
66 function tutorial
.convert_newlines(str
)
67 if(type(str
)~="string") then
68 return "ERROR: No string found!"
71 local function convert(s
)
72 return s
:gsub("\n", function(slash
, what
)
80 function tutorial
.register_infosign(itemstringpart
, caption
, fulltext
)
81 tutorial
.captions
[itemstringpart
] = caption
82 minetest
.register_node("tutorial:sign_"..itemstringpart
, {
83 description
= string.format(S("tutorial sign '%s'"), S(caption
)),
84 drawtype
= "signlike",
85 tiles
= {"default_sign_wall.png"},
86 inventory_image
= "default_sign_wall.png",
87 wield_image
= "default_sign_wall.png",
89 paramtype2
= "wallmounted",
90 sunlight_propagates
= true,
91 is_ground_content
= false,
93 selection_box
= { type = "wallmounted" },
94 groups
= {creative_breakable
=1,attached_node
=1,tutorial_sign
=1},
95 legacy_wallmounted
= true,
96 sounds
= default
.node_sound_defaults(),
97 on_construct
= function(pos
)
98 local meta
= minetest
.get_meta(pos
)
101 "label[-0.15,-0.4;"..minetest
.formspec_escape(S(caption
)).."]"..
102 "tablecolumns[text]"..
103 "tableoptions[background=#000000;highlight=#000000;border=false]"..
104 "table[0,0.25;12,5.2;infosign_text;"..
105 tutorial
.convert_newlines(minetest
.formspec_escape(S(fulltext
)))..
107 "button_exit[4.5,5.5;3,1;close;"..minetest
.formspec_escape(S("Close")).."]"
108 meta
:set_string("formspec", formspec
)
109 meta
:set_string("infotext", string.format(S("%s (Right-click to read)"), S(caption
)))
110 meta
:set_string("id", itemstringpart
)
111 meta
:set_string("caption", caption
)
116 minetest
.register_abm( {
117 nodenames
= {"group:tutorial_sign"},
120 action
= function(pos
, node
, active_object_count
, active_object_count_wider
)
121 local meta
= minetest
.get_meta(pos
)
122 local id
= meta
:get_string("id")
123 local caption
= tutorial
.captions
[id
]
127 local formspec
= ""..
129 "label[-0.15,-0.4;"..minetest
.formspec_escape(S(caption
)).."]"..
130 "tablecolumns[text]"..
131 "tableoptions[background=#000000;highlight=#000000;border=false]"..
132 "table[0,0.25;12,5.2;infosign_text;"..
133 tutorial
.convert_newlines(minetest
.formspec_escape(S(tutorial
.texts
[id
])))..
135 "button_exit[4.5,5.5;3,1;close;"..minetest
.formspec_escape(S("Close")).."]"
136 meta
:set_string("formspec", formspec
)
137 meta
:set_string("infotext", string.format(S("%s (Right-click to read)"), S(caption
)))
143 -- Number of gold ingots/lumps
146 -- Number of hidden diamonds
147 tutorial
.diamonds
= 12
152 tutorial
.texts
.intro
=
153 [[Welcome! This tutorial will teach you the most crucial basics of Minetest.
154 This tutorial assumes that you have not changed the default keybindings yet.
156 Let's start for the most important keybindings right now:
158 Look around: Move the mouse
163 Action: [Right mouse button]
164 Pause menu (you can exit the game here): [Esc]
166 You will find signs with more introductionary texts throughout this tutorial.
167 The "action" key has many uses. For now, let's just say you need it to read
168 the signs. Look at one and right-click it to read it.
170 To look at a sign, make sure you are close enough to it and the crosshair in the
171 center of the screen points directly on the sign.
173 You can exit the tutorial at any time, the world will be automatically saved.
175 Now feel free to walk around a bit and read the other signs to learn more.]]
177 tutorial
.texts
.minetest
=
178 [[Minetest itself is not a game, it is a game engine.
179 To be able to actually play it, you need something called a "game".
181 Don't worry, Minetest comes pre-installed with a rather simple default game,
182 called "Minetest Game".
184 This tutorial teaches you the basics of Minetest (the engine), things which are true for
185 all games. This tutorial does not teach you how to play a particular game, not
186 even the default one.]]
188 tutorial
.texts
.subgame
=
189 [[Now since you probably now the basics, you may want to actually play or build something.
190 Minetest comes bundled with a default game, which you may try out now.
191 Sadly, there is currently no tutorial for the default game.
192 You may want to read the "Getting Started" section of the Community Wiki,
193 which is more specific about the default game.
194 Said document can be found at:
196 <https://wiki.minetest.net/Getting_Started>
198 Alternatively, you may check out one of the games which are shared on the Minetest forums.]]
201 tutorial
.texts
.creative
=
202 [[The creative mode is turned on. If you are here to learn how to play Minetest,
203 you should probably leave now, turn creative mode off and restart the
206 Roughly spoken, creative mode is for messing around with the game without
207 the normal gameplay restraints.
209 You can leave now by pressing "Leave tutorial", or later, by pressing [Esc].]]
211 tutorial
.texts
.notsingleplayer
=
212 [[You are now playing the tutorial in multiplayer mode.
213 But this tutorial is optimized for the singleplayer mode.
214 This tutorial does not work properly with more than 1 player.
216 Unless you are sure no other players will join, you should
217 leave now and start the tutorial in singleplayer mode.]]
220 [=[Minetest has 3 different views which determine the way you see the world.
223 - First-person view (default)
224 - Third-person view from behind
225 - Third-person view from the front
227 You can change the camera mode by pressing [C] (but you have to close this
230 Switch camera mode: [C]]=]
232 tutorial.texts.minimap =
233 [=[Press the [V] key to make a minimap appear on the top right.
234 The minimap helps you to find your way around the world.
235 Press it again to toggle through different minimap modes and zoom levels.
237 There are 2 minimap modes and 3 zoom levels.
239 Surface mode is a top-down view of the world, roughly resembling the
240 colors of the blocks this world is made on. It only shows the topmost
241 blocks, everything below is hidden, like a satellite photo. Surface
242 mode is useful if you got lost.
244 Radar mode is more complicated. It displays the "denseness" of the area
245 around you and changes with your height. Roughly, the more green an
246 area is, the less "dense" it is. Black areas have many blocks. Use
247 the radar to find caverns, hidden areas, walls and more. Currently,
248 radar mode does not work in the tutorial. Sorry, you have to try it
251 There are also two different direction modes. Normally, "up" on the minimap
252 is always pointing to the North. But if you press [Shift]+[V], the minimap
253 will instead rotate with your looking direction, so "up" is always your
256 In some games, the minimap may be disabled.
258 Toggle minimap mode: [V]
259 Toggle minimap rotating: [Shift]+[V]]=]
261 tutorial.texts.blocks =
262 [[The world of Minetest is made entirely out of blocks, or voxels, to be precise.
263 Blocks can be added or removed with the correct tools.
265 In this section, we'll show you a few special but common blocks which behave in unexpected,
268 Of course, games can come up with more special weird blocks.]]
270 tutorial.texts.falling_node =
271 [[Some blocks need to rest on top of another block, otherwise, they fall down.
272 Try it and mine the block below the uppermost block.]]
274 tutorial.texts.attached_node =
275 [[Some blocks have to be attached to another block, otherwise, they drop as an item
276 as if you would have mined it.
278 Attached here is a picture frame. You can't collect or mine it directly, but if you mine
279 the block it is attached to, it will drop as an item which you can collect.]]
281 tutorial.texts.disable_jump =
282 [[These nasty blocks on the floor prevent you from jumping when you stand on them.]]
284 tutorial.texts.bouncy =
285 [[Whee! The blocks will make you bounce if you jump on them. They also can bounce
286 you from the side, if you are fast enough.]]
288 tutorial.texts.runover =
289 [[This abyss behind this sign is so small that you can even walk over it,
290 as long as you don't stop midway. But you can jump over it anyways, just to be,
293 tutorial.texts.jumpup =
294 [[You can't reach this upper block by walking. But luckily, you are able to jump.
295 For our purposes, you can jump just high enough to reach one block above you.
296 But you can't two blocks high.
297 Press the space bar once to jump at a constant height.
301 Now try it to continue.]]
304 tutorial.texts.jumpover =
305 [=[Here is a slightly larger abyss. Luckily, you can also jump just far enough to
306 cross a gap of this width. Don't worry, the abyss is not deep enough to hurt you
307 when you fall down. There are stairs which lead back up here.
311 tutorial.texts.orientation =
312 [[From this point on, there will be branching paths. For orientation, we placed
313 some arrow signs. They just show a short text when you hover them, that's all.
315 You don't have to follow the sections in any particular order, with one exception,
316 for which you will be informed.]]
318 tutorial.texts.sneak =
319 [=[Sneaking is a special move. As long as you sneak, you walk slower, but you are
320 guaranteed to not accidentally fall off the edge of a block. This also allows you to
321 "lean over" in a sense.
322 To sneak, keep the sneak key pressed. As soon as you release the sneak key,
323 you walk at normal speed again. Be careful not releasing the sneak key when you
324 are at a ledge, you might fall!
328 Keep in mind that the [Shift] key is used for a large number of other things in Minetest.
329 Sneaking only works when you are not in a liquid, stand on solid ground and are not at a
332 You may try out sneaking at this little blocky pyramid.]=]
334 tutorial
.texts
.hotbar
=
335 [[At the bottom of the screen you see 8 squares. This is called the 'hotbar'.
336 The hotbar allows you to quickly access some items from your inventory.
337 In our case, the upper 8 slots in your inventory.
338 You can change the selected item with the mouse wheel, if you have one, or with the
341 Select previous item in hotbar: [Mouse wheel up]
342 Select next item in hotbar: [Mouse wheel down]
343 Select item #N in hotbar: the key with the number #N
345 The item you've selected is also the item you wield. This will be important later for
346 tools, mining, building, etc.]]
350 [[In this chest you find some comestibles. Comestibles are items which instantly
351 heal you when eaten. This removes the item from your inventory.
352 To eat one, select the comestible in your hotbar, then click the left mouse button.
353 Unlike other items, you cannot punch or attack while holding a comestible. To be able
354 to attack, you have to select something else.
355 Of course, this does not have to be the only way to heal you.
357 Eat comestible: [Left mouse button]
359 Don't forget to take the gold ingot.]]
361 tutorial
.texts
.chest
=
362 [[Treasure chests are a common sight in Minetest. They are actually not built-in
365 tutorial
.texts
.damageblock
=
366 [[Careful! These spikes hurt you when you stand inside, so don't walk into them.
367 Try to walk around and get the gold ingot.
369 They damage you every second you stand in them.
371 This is one of the many ways you can get hurt in Minetest.]]
373 tutorial
.texts
.ladder
=
374 [[This is a ladder. Ladders help you to climb up great heights or to climb down safely.
375 To climb a ladder, go into the block occupied by the ladder and hold one of the
378 Climb up ladder: [Space]
379 Climb down ladder: [Shift]
381 Note that sneaking and jumping do not work when you are at a ladder.]]
383 tutorial
.texts
.swim
=
384 [[What you see here is a small swimming pool. You are able to swim and dive.
385 Diving usually costs you breath. While diving, 10 bubbles appear in the heads-up display.
386 These bubbles disappear over time while diving and when you are out of bubbles,
387 you slowly lose some health points. You have to back up to the surface from time to
388 time to restore the bubbles.
390 Movement in a liquid is slightly different than on solid ground:
396 Swim upwards: [Space]
397 Swim downwards: [Shift]
399 At the bottom of the pool lies a gold ingot. Try to get it!]]
402 tutorial
.texts
.dive
=
403 [=[To get to the other side, you have to dive here. Don't worry, the tunnel is not
404 long. But don't stay too long in the water, or else you take damage.
405 At the bottom of the pool lies a gold ingot. Try to get it!
411 Swim upwards: [Space]
412 Swim downwards: [Shift]]=]
414 tutorial.texts.waterfall = ""..
415 [=[You can easily swim up this waterfall. Go into the water and hold the space bar until you're
422 Swim upwards: [Space]
423 Swim downwards: [Shift]]=]
425 tutorial.texts.liquidtypes =
426 [=[Liquids behave somewhat weirdly in Minetest. Actually, there are 2 kinds of liquids.
427 If you watched the waterfall closely, you may have noticed that there is a slight difference
428 between the water blocks that make the waterfall, and those up here in the basin.
430 Minetest distinguishes between liquid source and flowing liquid.
432 A liquid source block is always a full cube.
433 A flowing liquid block looks slightly different. Often, it is not a full cube, but has a more or less
434 triangular shape. Also, flowing liquids usually have an unique "flowing" animation, but this may
435 not be the case for all liquids.
437 Up in the basin, you see four rows of liquid sources, followed by one row of flowing
438 liquids, followed by the waterfall itself. The waterfall itself is solely made of flowing liquids.
440 Liquid sources generate flowing liquids around them. Liquid sources can also exist on their own.
441 Flowing liquids are not able to exist on their own. They have to originate from a liquid source.
442 If the liquid source is gone, or the way to one is blocked, the flowing liquid will slowly dry
445 To the right of this sign is a special block. When used, it will block the liquid flow.
446 Use that block, being close enough and looking at it, and watch the waterfall dry out.
448 Use something: [Right mouse button]]=]
450 tutorial.texts.viscosity =
451 [[Minetest mods can introduce various liquids which differ in their properties.
452 Probably the most important property is their viscosity. Here you have some
453 pools which differ in their viscosity. Feel free to try them out.]]
455 tutorial.texts.pointing1 =
456 [[An important general concept in Minetest is pointing. As mentioned earlier,
457 there is a crosshair in the center of the screen.
459 You can point several things in Minetest:
466 You can only point one thing at once, or nothing at all.
467 When you're pointing a block, it is surrounded by a thin wireframe or it will
468 be highlighted (you can change the style in your settings).
469 When you're pointing an object, animal or another player, your crosshair will
472 To point something, three conditions have to be met:
473 1. The thing in question must be pointable at all
474 2. Your crosshair must be exactly over the thing in question
475 3. You must be close enough to the thing
477 When a thing is pointed, you can do different stuff with it; e.g. collecting it,
478 punching it, building to it, etc. We come to all that later.
480 Now collect that apple from the small tree in front of this sign, and the gold bar.
481 To do that, you must point it and click with the left mouse button.]]
484 tutorial.texts.pointing2 =
485 [[The distance you need to point to things solely depends on the tool you carry.
486 Most tools share a default value but some tools may have a longer or shorter distance.
488 At the moment, your only "tool" is the hand. It was good enough to collect the apple
491 Above this sign hang some apples, but you cannot reach them by normal means. At the
492 wall in front of this sign lies a special example tool which you can use to retrieve the apple
495 To take the tool, point to it and click the left mouse button. Then select it with the
496 mouse wheel or the number keys. You will learn more about tools in a different section.]]
498 tutorial.texts.health =
499 [[Unless you have damage disabled, all players start with 20 hit points (HP), represented
500 by ten hearts in the heads-up display. One HP is represented by half a heart in this
501 tutorial, but the actual representation can vary from game to game.
503 You can take damage for the following reasons (including, but not limited to):
505 - Standing in a block which hurts you
506 - Attacks from other players
507 - Staying too long in a liquid
509 In this tutorial, you can regain health by eating a comestible. This is only an example,
510 mods and games may come with other mechanisms to heal you.
512 When you lose all your hit points, you die. Death is normally not really that bad in Minetest.
513 When you die, you will usually lose all your possessions. You are able to put yourself
514 into the world immediately again. This is called "respawning". Normally you appear at a
515 more or less random location.
516 In the tutorial you can die, too, but don't worry about that. You will
517 respawn at a special location you can't normally reach and keep all your posessions.
518 Games may introduce special events on a player's death.]]
520 tutorial.texts.death =
521 [[Oops! So it seems you just have died. Don't worry, you don't have lost any of your
522 possessions and you have been revived. You are still in Tutorial World at a different
525 You have arrived at the so-called respawn location of Tutorial World. You will
526 always appear here after you died. This is called "respawning". In most worlds,
527 however, you will respawn in a slightly randomized location.
529 The tutorial uses a so-called fixed spawn point, so you respawn always at the same
530 spot. This is unusual for singleplayer worlds, but in online play, some servers
531 use fixed spawn points, too.
533 Under normal conditions you would have lost all or a part of your possessions or some
534 other bad thing would have happened to you. But not here, this is a tutorial.
536 To continue, just drop out at the end of that gangway. The drop is safe.]]
541 tutorial.texts.items =
542 [[Throughout your journey, you will probably collect many items. Once you collected
543 them, blocks are considered to be items, too.
545 Items can be stored in your inventory and selected with the hotbar (see the other signs).
546 You can wield any items; you can even punch with almost any item to hurt enemies.
547 Usually, you will deal a minimal default damage with most items. Even if you do not hold,
549 If you don't want to have an item anymore, you can always throw it away. Likewise,
550 you can collect items which lie around by pointing and leftclicking them.
552 Collect item: [Left mouse button]
553 Drop carried item stack: [Q]
554 Drop single item from carried item stack: [Shift] + [Q]
556 On the table at the right to this sign lies an item stack of 50 rocks so you have some items,
557 to test out the inventory.]]
559 tutorial.texts.tools =
560 [[A tool is a special kind of item.
561 Tools can be used for many things, such as:
566 The number of tools which are possible in Minetest is innumberable and are
567 too many to cover in this tutorial.
568 But at least we will look at a very common and important tool type: mining tools,
569 We will come to that in the mining section.
571 Many tools wear off and get destroyed after you used them for a while. In an
572 inventory the tool's "health" is indicated by a colored bar
574 Tools may be able to be repaired, see the sign about repairing.]]
576 tutorial.texts.inventory =
577 [[The inventory menu usually contains the player inventory. This allows you
578 to carry along items throughout the world.
580 Every inventory is made out of slots where you can store items in. You can store one
581 entire stack of items per slot, the only condition is that the items are of the same
582 type. In this tutorial all items except for tools stack up to 99 items, but this number
583 can vary in actual games.
585 Here are the controls which explain how to move around the items within the inventory:
588 Open inventory menu: [I]
590 When the inventory is opened and you don't hold any items:
591 Take item stack: [Left mouse button]
592 Take 10 items from item stack: [Middle mouse button]
593 Take half item stack: [Right mouse button]
595 When you took an item stack in the inventory:
596 Put item stack: [Left mouse button]
597 Put 10 items from item stack: [Middle mouse button]
598 Put single item from item stack: [Right mouse button]
600 You can also drop an item stack by holding it in the inventory, then clicking anywhere
601 outside of the window.]]
603 tutorial.texts.listrings =
604 [=[By the way, if you are tired of clicking, there is a little convenience
606 Hold [Shift] while you left-click on an item stack in a menu to
607 move it instantly to another relevant section. For example, in this tutorial
608 you can use it to move an item stack from the chest into your inventory (and
609 vice-versa) with a single click.
611 [Shift]+[Left click]: Move full item stack to other section in menu]=]
613 tutorial
.texts
.chest
=
614 [[This is a chest. You can view its contents by right-clicking it. In the menu you will see
615 two inventories, on the upper part the chest inventory and on the lower part the player
616 inventory. Exchanging items works exactly the same as in the inventory menu.]]
619 tutorial
.texts
.build
=
620 [[Another important task in Minetest is building blocks.
621 "Building" here refers to the task of placing one block in your possession onto
622 another block in the world.
623 Unlike mining, building a block happens instantanous. To build, select a block in your
624 hotbar, point to any block in the world and press the right mouse button.
625 Your block will be immediately placed on the pointed side.
626 It is important that the block you want to build to is pointable. This means you cannot build
627 next to or on liquids by normal means.
629 Build on ordinary block: [Right mouse button]
631 Try to get up to that little hole by using the wood blocks in the chest. There is another
632 gold ingot waiting for you.]]
634 tutorial
.texts
.build_special
=
635 [=[You may have wondered how you can build on a block which you can use, like a chest.
636 For this, you have to hold the sneak key and then use the build key.
638 Build on usable block: [Shift] + [Right mouse button]]=]
640 tutorial.texts.mine =
641 [[Mining is a method to remove a single block with a mining tool. It is a very important
642 task in Minetest which you will use often.
644 (It is recommended that you go to the crafting and items house first. It is right in front of
647 To be able to mine a block, you need
649 1. to have minable block, after all,
650 2. to point on the block and
651 3. to carry an appropriate tool.
653 Mine: [Left mouse button]
655 When you are ready, hold the left mouse button while pointing the block. Depending on
656 the block type and the tool properties, this can take some time. Some tools are fast with
657 some particular block types, some other tools may be slower to mine other block types.
658 If you do not carry an appropriate tool, you are not able to mine the block at all.
659 You can tell that you are actually mining when you see cracks or some other animation
660 on the block in question.
662 When done mining, blocks will often add one or more items to your inventory. This is called
663 the "drop" of a block and depends on the block type. Now try to mine those large cubes in
664 this area, using different tools. Note that all blocks here are just examples to show you
665 different kinds of drops.]]
667 tutorial.texts.mine_cobble =
668 [[This is cobblestone. You can mine it with a pickaxe.
669 This cobblestone will always drop itself, that means, cobblestone. Dropping itself is the
670 usual dropping behaviour of a block, throughout many games.]]
672 tutorial.texts.mine_wood =
673 [[These are wooden planks. In the tutorial, you can only mine those blocks with an axe.
674 Wooden planks drop themselves.
676 In Minetest, we use the term "mining" in a general sense, regardless of the material.]]
678 tutorial.texts.mine_conglomerate =
679 [[This is a cube of conglomerate. You need a pickaxe to mine it.
680 Conglomerate drops something based on probability. Conglomerate randomly drops between 1
681 and 5 rocks, when mined.]]
683 tutorial.texts.mine_glass =
684 [[This is some weak glass. You can break it with your bare hands. Or you can use your pickaxe,
685 which is faster. Note that it looks slightly different than the other glass in this world.
686 These glass blocks don't drop anything.]]
688 tutorial.texts.mine_stone =
689 [[This is stone. You need a pickaxe to mine it. When mined, stone will drop cobblestone.]]
691 tutorial.texts.mine_immortal =
692 [[There can always be some blocks which are not minable by any tool. In our tutorial, all
693 those castle walls can't me mined, for example.]]
695 tutorial.texts.craft1 =
696 [[Crafting is the task of taking several items and combining them to form a new item.
697 Crafting is another important task in Minetest.
699 To craft something, you need a few items and a so-called crafting grid.
701 In this tutorial, you have a grid of size 3 times 3 in your inventory.
702 Let's get right into crafting:
704 1. Take 3 sheets of paper from the chest next to this sign.
705 2. Open the inventory menu with [I].
706 3. Place the paper in the crafting grid so that they form a 1×3 vertical line.
707 4. A book should appear in the output slot. Click on it to take it,
708 then put it in your player inventory.
710 This process consumes the paper.
711 When you have the book in your inventory, go on with the next sign.]]
713 tutorial.texts.craft2 =
714 [[To craft the book you have used a so-called crafting recipe. You must know the crafting
715 recipes as well so you can craft.
717 The crafting recipe you used in particular is a so-called shaped recipe. This means the
718 pattern you place in the crafting grid matters, but you can move the entire pattern
721 There is another kind of crafting recipe: Shapeless.
722 Shapeless recipes only care about which items you place in the crafting grid, but not in
723 which pattern. In the next chest you find some wheat. Let's make dough from it! For this,
724 you have to place at least 1 wheat in 4 different slots, but the other slots must be empty.
725 What is special about this recipe is that you can place them anywhere in the grid.
727 When you got your dough, go on with the next sign.]]
729 tutorial.texts.craft3 =
730 [[Do you got your dough? Good.
732 You may have noticed that crafting always consumes one item from each occupied slot
733 of the crafting grid. This is true for all crafting recipes.
734 You can speed crafting up a bit when you click with the middle mouse button on the
735 item in the output slot. Doing so will attempt to do the same craft up to 10 times,
736 instead of just once.
738 Feel free to try it with the remaining wheat or just go on with the next sign.]]
740 tutorial.texts.craft4 =
741 [[Another important thing to know about crafting are so-called groups. Crafting recipes do
742 not always require you to use the exactly same items every time.
743 This tutorial has a special recipe for books. In the chest, you will find paper in 4
744 different colors. You can also make a book by placing 3 paper sheets of any color
746 The paper color does not matter here, you can use only white paper, only orange paper
747 or even mix it. What is important here are the occupied slots.
748 This is possible because all 4 types of (example) paper belong to the same group and
749 our book recipe accepts not only white paper, but any paper of that group.
751 Feel free to experiment a bit around with this.]]
753 tutorial.texts.smelt =
754 [[This is a furnace. Furnaces can be used to turn a smeltable item with help of a fuel
755 to a new item. Many items can be furnace fuels, but not all. A few items are smeltable.
757 In order to operate a furnace, you have to put the smeltable item into the 'Source' slot
758 and the fuel into the 'Fuel' slot.
759 As soon as the items have been placed, the furnace automatically starts to smelt the
760 items. The furnace becomes active and consumes an item in the fuel slot. The flame
761 goes on and will continue burning for a given time. The time depends on the fuel type.
762 Some fuels burn very short, and others burn longer. In the furnace menu, the burn time
763 is indicated by the flame symbol. As soon as the flame goes out, the furnace may
764 continue burning if there is still fuel and smeltable material in the furnace,
765 otherwise, the furnace becomes inactive again.
766 The smeltable material has to be exposed to the flame for a given time as well. This
767 time depends on the type of the material, too. Some material smelt faster than others.
768 You can see the smelting progress of a single item on the progress arrow. If one item
769 has been smelt, the result goes to one of the output slots, where you can take it.
771 In the left chest you find some fuels and in the right chest you find some materials to
772 smelt. Feel free to experiment with the furnace a bit. Smelt the gold lump to receive
773 this station's gold bar.
775 Again, this furnace is just an example; the exact operation may differ slightly from
778 tutorial.texts.repair =
779 [[Some games may come with a special recipe which allows you to repair your tools.
780 In those, repairing works always the same way:
781 Place two more or less worn out tools of the same kind into the crafting crid and
782 take the result. The result is a new tool which is slightly repaired by a fixed percentage.
784 Of course, this tutorial comes with such a recipe. The chest next to this sign stores
785 some damaged tools which you may try to repair now.]]
789 [=[You will often meet some blocks you can use. Something special happens when you
790 right-click while pointing on them.
791 In fact, you already used such blocks: All the signs you read are "usable" blocks.
793 There is a strange device next to this sign. Use it and see what happens.
795 Use usable block: [Right mouse button]]=]
798 tutorial.texts.basic_end =
799 [[If you think you have enough of this tutorial, you can leave at any time. There are
800 13 gold ingots at the stations to be found, to help you keep track.
802 You can find the gold ingots at the following stations:
809 - Comestibles and Eating
817 If you've got 13 gold ingots (in total), you probably know now everything which can be
818 learned from this tutorial. Collecting the gold ingots is optional.
820 After you closed this dialog, you can press [Esc] to open the pause menu and return
821 to the main menu or quit Minetest.
823 In the next room there are some further signs with information, but it is entirely optional
824 and not related to gameplay.]]
826 tutorial.texts.first_gold =
827 [[You have collected your first gold ingot. Those will help you to keep track in this tutorial.
828 There are 13 gold ingots in this tutorial.
830 There is a gold ingot at every important station. If you collected all ingots, you are
831 done with the tutorial, but collecting the gold ingots is not mandatory.]]
833 tutorial.texts.last_gold =
834 [[You have collected all the gold ingots in this tutorial.
836 This means you have now travelled to each station. If you read and understood everything,
837 you have learned everything which can be learned from this tutorial.
839 If this is the case, you are finished with this tutorial and can leave now. But feel
840 free to stay in this world to explore the area a bit further.
842 You may also want to visit the Good-Bye room, which has a few more informational
843 signs with supplemental information, but nothing of is is essential or gameplay-relevant.
845 If you want to stay, you leave later by pressing [Esc] to open the pause menu and then
846 return to the main menu or quit Minetest.]]
848 tutorial.texts.first_diamond =
849 [[Great, you have found and collected a hidden diamond! In Tutorial World, there are 12 hidden
850 diamonds. Can you find them all? The first diamond may have been easy to collect, but the
851 remaining 11 diamonds probably won't be that easy.
853 If you manage to find them all, you will be awarded a symbolic prize.]]
855 tutorial.texts.last_diamond =
857 You have collected all the diamonds of Tutorial World!
859 To recognize this achievement, you have been awarded with a diamond cup. It has been placed in
860 the Good-Bye Room for you.]]
863 tutorial.texts.controls =
864 [[To recap, here is an overview over the most important default controls:
872 Move upwards (ladder/liquid): [Space]
873 Move downwards (ladder/liquid): [Shift]
875 Toggle camera mode: [C]
876 Toggle minimap mode: [V]
878 Select item in hotbar: [Mouse wheel]
879 Select item in hotbar: [0] - [9]
882 Collect pointed item: [Left mouse button]
884 Drop single item: [Shift] + [Q]
886 Punch: [Left mouse button]
887 Mine: [Left mouse button]
888 Build/use: [Right mouse button]
889 Build: [Shift] + [Right mouse button]
891 Abort/open pause menu: [Esc]
893 You can review a shorter version of the controls in the pause menu.]]
896 tutorial.texts.online =
897 [[You may want to check out these online resources related to Minetest:
899 Official homepage of Minetest: <https://minetest.net/>
900 The main place to find the most recent version of Minetest.
902 Community wiki: <https://wiki.minetest.net/>
903 A community-based documentation website for Minetest. Anyone with an account can edit
904 it! It also features a documentation of the default game, which was NOT covered by
907 Webforums: <https://forum.minetest.net/>
908 A web-based discussion platform where you can discuss everything related to Minetest.
909 This is also a place where player-made mods and games are published and
910 discussed. The discussions are mainly in English, but there is also space for
911 discussion in other languages.
913 Chat: <irc://irc.freenode.net#minetest>
914 A generic Internet Relay Chat channel for everything related to Minetest where people can
915 meet to discuss in real-time.
916 If you do not understand IRC, see the Community Wiki for help.]]
918 tutorial.captions = {}
920 tutorial.locations = {
921 intro = { { x = 42, y = 0.5, z = 28 }, math.pi * 0.5 },
922 jumpup = { { x = 64, y = 0.5, z = 30 }, math.pi * 1.5, math.pi * 0.2 },
923 ladder = { { x = 70, y = 0.5, z = 37 }, math.pi * 0.5 },
924 swim = { { x = 85, y = 0.5 , z = 50 }, math.pi * 0.5 },
925 dive = { { x = 59, y = 0.5 , z = 62 }, math.pi * 0.5 },
926 sneak = { { x = 33, y = 0.5, z = 41 }, math.pi * 0.5 },
927 eat = { { x = 67, y = -3.5, z = 60}, 0 },
928 health = { { x = 50, y = 0.5, z = 58 }, 0 },
929 viscosity = { { x = 44, y = 0.5, z = 53 }, 0, math.pi * 0.2 },
930 waterfall = { { x = 40, y = 0.5 , z = 81 }, 0 },
931 pointing1 = { { x = 89, y = 0.5, z = 62 }, math.pi * 0.5 },
932 items = { { x = 70, y = 0.5, z = 65 }, math.pi },
933 craft1 = { { x = 74, y = 0.5, z = 59 }, math.pi * 1.5 },
934 repair = { { x = 80, y = 0.5, z = 59 }, math.pi },
935 smelt = { { x = 78, y = 4.5, z = 63 }, math.pi * 1.5 },
936 mine = { { x = 79, y = 0.5, z = 75 }, 0, math.pi * 0.2 },
937 build = { { x = 66, y = 0.5, z = 83 }, math.pi },
938 goodbye = { { x = 22.5, y = 0.5, z = 73 }, math.pi * 0.5 },
941 tutorial.locations_order = {
942 "intro", "jumpup", "pointing1", "items", "eat", "craft1", "repair", "smelt", "mine", "build", "swim", "dive", "viscosity", "waterfall", "health", "sneak", "goodbye"
945 tutorial.register_infosign("intro", "Introduction", tutorial.texts.intro)
946 tutorial.register_infosign("minetest", "Minetest", tutorial.texts.minetest)
947 tutorial.register_infosign("cam", "Player Camera", tutorial.texts.cam)
948 tutorial.register_infosign("minimap", "Minimap", tutorial.texts.minimap)
949 tutorial.register_infosign("runover", "Small Abysses", tutorial.texts.runover)
950 tutorial.register_infosign("jumpup", "Jumping (1)", tutorial.texts.jumpup)
951 tutorial.register_infosign("jumpover", "Jumping (2)", tutorial.texts.jumpover)
952 tutorial.register_infosign("sneak", "Sneaking", tutorial.texts.sneak)
953 tutorial.register_infosign("orientation", "Information about the following tutorial sections", tutorial.texts.orientation)
954 tutorial.register_infosign("hotbar", "Hotbar", tutorial.texts.hotbar)
955 tutorial.register_infosign("eat", "Comestibles and Eating", tutorial.texts.eat)
956 tutorial.register_infosign("chest", "Chests", tutorial.texts.chest)
957 tutorial.register_infosign("damageblock", "Blocks Which Hurt You", tutorial.texts.damageblock)
958 tutorial.register_infosign("ladder", "Climbing Ladders", tutorial.texts.ladder)
959 tutorial.register_infosign("swim", "Swimming", tutorial.texts.swim)
960 tutorial.register_infosign("dive", "Diving", tutorial.texts.dive)
961 tutorial.register_infosign("waterfall", "Swimming up a Waterfall", tutorial.texts.waterfall)
962 tutorial.register_infosign("viscosity", "Viscosity", tutorial.texts.viscosity)
963 tutorial.register_infosign("liquidtypes", "Liquid sources and flowing liquids", tutorial.texts.liquidtypes)
964 tutorial.register_infosign("pointing1", "Pointing (1)", tutorial.texts.pointing1)
965 tutorial.register_infosign("pointing2", "Pointing (2)", tutorial.texts.pointing2)
966 tutorial.register_infosign("health", "Health and Damage", tutorial.texts.health)
967 tutorial.register_infosign("death", "Death and Respawning", tutorial.texts.death)
968 tutorial.register_infosign("items", "Items", tutorial.texts.items)
969 tutorial.register_infosign("tools", "Tools", tutorial.texts.tools)
970 tutorial.register_infosign("inventory", "Using the Inventory", tutorial.texts.inventory)
971 tutorial.register_infosign("listrings", "Inventory shortcut", tutorial.texts.listrings)
972 tutorial.register_infosign("chest", "Comment About Chests", tutorial.texts.chest)
973 tutorial.register_infosign("build", "Building Some Blocks", tutorial.texts.build)
974 tutorial.register_infosign("build_special", "Building at Usable Blocks", tutorial.texts.build_special)
975 tutorial.register_infosign("mine", "Mining blocks", tutorial.texts.mine)
976 tutorial.register_infosign("mine_cobble", "Mining example: Cobblestone", tutorial.texts.mine_cobble)
977 tutorial.register_infosign("mine_stone", "Mining example: Stone", tutorial.texts.mine_stone)
978 tutorial.register_infosign("mine_conglomerate", "Mining example: Conglomerate", tutorial.texts.mine_conglomerate)
979 tutorial.register_infosign("mine_wood", "Mining example: Wooden Planks", tutorial.texts.mine_wood)
980 tutorial.register_infosign("mine_glass", "Mining example: Weak glass", tutorial.texts.mine_glass)
981 tutorial.register_infosign("mine_immortal", "Unminable blocks", tutorial.texts.mine_immortal)
982 tutorial.register_infosign("blocks", "Special blocks", tutorial.texts.blocks)
983 tutorial.register_infosign("disable_jump", "No-jumping blocks", tutorial.texts.disable_jump)
984 tutorial.register_infosign("bouncy", "Bouncy blocks", tutorial.texts.bouncy)
985 tutorial.register_infosign("falling_node", "Falling blocks", tutorial.texts.falling_node)
986 tutorial.register_infosign("attached_node", "Attached blocks", tutorial.texts.attached_node)
987 tutorial.register_infosign("use", "Using blocks", tutorial.texts.use)
988 tutorial.register_infosign("craft1", "Crafting Basics", tutorial.texts.craft1)
989 tutorial.register_infosign("craft2", "Crafting using Shapeless Recipes", tutorial.texts.craft2)
990 tutorial.register_infosign("craft3", "Crafting Faster", tutorial.texts.craft3)
991 tutorial.register_infosign("craft4", "Crafting Groups", tutorial.texts.craft4)
992 tutorial.register_infosign("smelt", "Furnace Operation Instructions", tutorial.texts.smelt)
993 tutorial.register_infosign("repair", "Repairing Tools", tutorial.texts.repair)
994 tutorial.register_infosign("basic_end", "End of the Basic Tutorial", tutorial.texts.basic_end)
995 tutorial.register_infosign("controls", "Controls Overview", tutorial.texts.controls)
996 tutorial.register_infosign("online", "Online Resources", tutorial.texts.online)
997 tutorial.register_infosign("subgame", "Games", tutorial.texts.subgame)
999 minetest.register_node("tutorial:wall", {
1000 description = S("reinforced wall"),
1001 tiles = {"default_stone_brick.png"},
1002 is_ground_content = true,
1003 groups = {creative_breakable=1},
1004 sounds = default.node_sound_stone_defaults(),
1007 minetest.register_node("tutorial:wood", {
1008 description = S("reinforced wood"),
1009 tiles = {"default_wood.png"},
1010 groups = {creative_breakable=1},
1011 sounds = default.node_sound_wood_defaults(),
1014 minetest.register_node("tutorial:reinforced_glass", {
1015 description = S("reinforced glass"),
1016 drawtype = "glasslike",
1017 tiles = {"tutorial_reinforced_glass.png"},
1018 inventory_image = minetest.inventorycube("tutorial_reinforced_glass.png"),
1019 paramtype = "light",
1020 sunlight_propagates = true,
1021 groups = { creative_breakable=1 },
1022 sounds = default.node_sound_glass_defaults(),
1025 minetest.register_node("tutorial:weak_glass", {
1026 description = S("weak glass"),
1027 drawtype = "glasslike",
1028 tiles = {"tutorial_weak_glass.png"},
1029 inventory_image = minetest.inventorycube("tutorial_weak_glass.png"),
1030 paramtype = "light",
1031 sunlight_propagates = true,
1032 groups = { cracky=3, oddly_breakable_by_hand=1 },
1034 sounds = default.node_sound_glass_defaults(),
1038 minetest.register_tool("tutorial:snatcher", {
1039 description = S("apple snatcher"),
1040 inventory_image = "tutorial_snatcher.png",
1041 wield_image = "tutorial_snatcher.png",
1042 wield_scale = { x = 1, y = 1, z = 1 },
1044 tool_capabilities = {},
1047 --[[ A special switch which, when flipped, exchanges day for night and vice versa. ]]
1048 minetest.register_node("tutorial:day", {
1049 description = S("day/night switch (day)"),
1050 tiles = { "tutorial_day.png" },
1051 groups = {creative_breakable=1},
1052 on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
1053 minetest.set_timeofday(0)
1054 minetest.set_node(pos, {name="tutorial:night"})
1057 minetest.register_node("tutorial:night", {
1058 description = S("day/night switch (night)"),
1059 tiles = { "tutorial_night.png" },
1060 groups = {creative_breakable=1},
1061 on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
1062 minetest.set_timeofday(0.5)
1063 minetest.set_node(pos, {name="tutorial:day"})
1067 --[[ A special switch which "activates" and "deactivates" the waterfall in Tutorial World.
1068 It only works on a prepared map! ]]
1069 minetest.register_node("tutorial:waterfall_on", {
1070 description = S("waterfall switch (on)"),
1071 tiles = { "tutorial_waterfall_on.png" },
1072 groups = {creative_breakable=1},
1073 on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
1074 local wpos = { y = 5, z = 86 }
1077 minetest.set_node(wpos, {name="tutorial:wall"})
1079 minetest.set_node({x=30,y=7,z=91}, {name="tutorial:waterfall_off"})
1080 minetest.set_node({x=40,y=2,z=86}, {name="tutorial:waterfall_off"})
1083 minetest.register_node("tutorial:waterfall_off", {
1084 description = S("waterfall switch (off)"),
1085 tiles = { "tutorial_waterfall_off.png" },
1086 groups = {creative_breakable=1},
1087 on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
1088 local wpos = { y = 5, z = 86 }
1091 minetest.remove_node(wpos)
1093 minetest.set_node({x=30,y=7,z=91}, {name="tutorial:waterfall_on"})
1094 minetest.set_node({x=40,y=2,z=86}, {name="tutorial:waterfall_on"})
1098 -- Ruler (used in sneaking section)
1099 minetest.register_node("tutorial:ruler", {
1100 description = S("ruler"),
1101 drawtype = "signlike",
1103 type = "wallmounted",
1104 wall_side = { -0.5, -0.5, 1/16, -0.4, 0.5, 0.5 },
1107 tiles = { "tutorial_ruler.png" },
1108 inventory_image = "tutorial_ruler.png",
1109 wield_image = "tutorial_ruler.png",
1110 paramtype = "light",
1111 paramtype2 = "wallmounted",
1112 sunlight_propagates = true,
1113 groups = {creative_breakable=1, attached_node=1},
1116 local is_drawtype, is_pointable, is_diggable, is_air_equivalent, is_tiles
1117 -- Make some changes to item spawner node if debug setting is active
1118 if edit_item_spawners then
1119 -- This makes the item spawner visible and clickable
1120 is_drawtype = "glasslike"
1123 is_air_equivalent = false
1124 is_tiles = { "tutorial_item_spawner.png" }
1126 -- Normal invisible non-pointable non-editable item spawner
1127 is_drawtype = "airlike"
1128 is_pointable = false
1130 is_air_equivalent = true
1135 minetest.register_node("tutorial:itemspawner", {
1136 description = S("item spawner"),
1137 paramtype = "light",
1140 drawtype = is_drawtype,
1141 pointable = is_pointable,
1142 diggable = is_diggable,
1143 air_equivalent = is_air_equivalent,
1146 inventory_image = "tutorial_item_spawner.png",
1147 wield_image = "tutorial_item_spawner.png",
1148 buildable_to = false,
1149 sunlight_propagates = true,
1150 groups = {creative_breakable=1},
1151 on_construct = function(pos)
1152 local meta = minetest.get_meta(pos)
1153 meta:set_int("configged", 0)
1154 local formspec = ""..
1156 "label[-0.15,-0.4;"..minetest.formspec_escape(S("Item spawner")).."]"..
1157 "field[0,1;10,1;offset;"..minetest.formspec_escape(S("Offset"))..";(0,0,0)]"..
1158 "field[0,2;10,1;itemstring;"..minetest.formspec_escape(S("Itemstring"))..";]"..
1159 "button_exit[4.5,5.5;3,1;close;"..minetest.formspec_escape(S("OK")).."]"
1160 meta:set_string("formspec", formspec)
1161 meta:set_string("infotext", S("Item spawner (inactive)"))
1163 on_receive_fields = function(pos, formname, fields, sender)
1164 if not fields.offset or fields.offset == "" then
1165 fields.offset = "(0,0,0)"
1167 if fields.offset and fields.itemstring then
1168 local meta = minetest.get_meta(pos)
1169 meta:set_string("offset", fields.offset)
1170 meta:set_int("configged", 1)
1171 meta:set_string("itemstring", fields.itemstring)
1172 meta:set_string("formspec", "")
1173 meta:set_string("infotext", "")
1176 on_timer = function(pos, elapsed)
1177 local meta = minetest.get_meta(pos)
1178 if meta:get_int("configged") == 0 or edit_item_spawners then
1182 local offset = minetest.string_to_pos(meta:get_string("offset"))
1183 local itemstring = meta:get_string("itemstring")
1184 local x, y, z = offset.x, offset.y, offset.z
1185 local spawnpos = {x=pos.x+x, y=pos.y+y, z=pos.z+z}
1186 local objs = minetest.get_objects_inside_radius(spawnpos, 1)
1188 local ent = objs[o]:get_luaentity()
1190 if ent.name == "__builtin:item" and ent.itemstring == itemstring then
1191 -- Remove node when item was spawned successfully.
1192 -- So it doesn't get in the way.
1193 minetest.remove_node(pos)
1198 if itemstring ~= nil and itemstring ~= "" then
1199 minetest.add_item(spawnpos, itemstring)
1200 local timer = minetest.get_node_timer(pos)
1205 local timer = minetest.get_node_timer(pos)
1210 -- Crafting guides (example crafting images at crafting section)
1211 function tutorial.craftguideinfo(pos)
1212 local meta = minetest.get_meta(pos)
1213 meta:set_string("infotext", S("This is a crafting example."))
1216 function tutorial.register_craftguide(subId, desc, imageStatic, imageAnim, animFrames)
1217 local id = "tutorial:craftguide_"..subId
1220 if imageAnim ~= nil then
1225 type = "vertical_frames",
1228 length = animFrames * 4.0,
1233 tiles = { imageStatic }
1236 minetest.register_node(id, {
1238 drawtype = "signlike",
1240 type = "wallmounted",
1241 wall_side = { -0.5, -0.5, -0.5, -0.4, 0.5, 0.5 },
1245 inventory_image = imageStatic,
1246 wield_image = imageStatic,
1247 paramtype = "light",
1248 paramtype2 = "wallmounted",
1249 sunlight_propagates = true,
1250 groups = {creative_breakable=1, attached_node=1},
1251 on_construct = tutorial.craftguideinfo,
1254 minetest.register_abm({
1258 action = tutorial.craftguideinfo,
1262 tutorial.register_craftguide("paper", S("crafting example: white paper"), "tutorial_craftguide_paper_white.png")
1263 tutorial.register_craftguide("wheat", S("crafting example: wheat"), "tutorial_craftguide_wheat.png", "tutorial_craftguide_wheat_anim.png", 3)
1264 tutorial.register_craftguide("paper_color", S("crafting example: colored paper"), "tutorial_craftguide_paper_color.png", "tutorial_craftguide_paper_color_anim.png", 4)
1265 tutorial.register_craftguide("repair", S("crafting example: tool repair"), "tutorial_craftguide_repair.png", "tutorial_craftguide_repair_anim.png", 3)
1267 --[[ Tutorial cups, awarded for achievements ]]
1268 tutorial.cupnodebox = {
1271 {-0.3,-0.5,-0.3,0.3,-0.4,0.3}, -- stand
1272 {-0.1,-0.4,-0.1,0.1,0,0.1}, -- handle
1273 {-0.3,0,-0.3,0.3,0.1,0.3}, -- cup (lower part)
1274 -- the 4 sides of the upper part
1275 {-0.2,0.1,-0.3,0.2,0.5,-0.2},
1276 {-0.2,0.1,0.2,0.2,0.5,0.3},
1277 {-0.3,0.1,-0.3,-0.2,0.5,0.3},
1278 {0.2,0.1,-0.3,0.3,0.5,0.3},
1282 tutorial.cupselbox = {
1285 {-0.3,-0.5,-0.3,0.3,-0.4,0.3}, -- stand
1286 {-0.1,-0.4,-0.1,0.1,0,0.1}, -- handle
1287 {-0.3,0,-0.3,0.3,0.5,0.3}, -- upper part
1291 function tutorial.goldinfo(pos)
1292 local meta = minetest.get_meta(pos)
1293 meta:set_string("infotext", S("This golden cup has been awarded for finishing the tutorial."))
1296 function tutorial.diamondinfo(pos)
1297 local meta = minetest.get_meta(pos)
1298 meta:set_string("infotext", S("This diamond cup has been awarded for collecting all hidden diamonds."))
1302 --[[ awarded for collecting all gold ingots ]]
1303 minetest.register_node("tutorial:cup_gold", {
1304 description = S("golden cup"),
1305 tiles = { "default_gold_block.png" },
1306 paramtype = "light",
1307 drawtype = "nodebox",
1308 node_box = tutorial.cupnodebox,
1309 selection_box = tutorial.cupselbox,
1310 groups = { creative_breakable = 1 },
1311 on_construct = tutorial.goldinfo,
1314 --[[ awarded for collecting all diamonds ]]
1315 minetest.register_node("tutorial:cup_diamond", {
1316 description = S("diamond cup"),
1317 tiles = { "default_diamond_block.png" },
1318 paramtype = "light",
1319 drawtype = "nodebox",
1320 node_box = tutorial.cupnodebox,
1321 selection_box = tutorial.cupselbox,
1322 groups = { creative_breakable = 1 },
1323 on_construct = tutorial.diamondinfo,
1326 minetest.register_abm({
1327 nodenames = {"tutorial:cup_gold"},
1330 action = tutorial.goldinfo,
1333 minetest.register_abm({
1334 nodenames = {"tutorial:cup_diamond"},
1337 action = tutorial.diamondinfo,
1340 --[[ This function shows a simple dialog window with scrollable text
1341 name: name of the player to show the formspec to
1342 caption: Caption of the dialog window (not escaped)
1343 text: The text to be shown. Must be escaped manually for formspec, an unescaped
1344 comma generates a line break.
1346 function tutorial.show_default_dialog(name, caption, text)
1347 local formspec = "size[12,6]"..
1348 "label[-0.15,-0.4;"..minetest.formspec_escape(caption).."]"..
1349 "tablecolumns[text]"..
1350 "tableoptions[background=#000000;highlight=#000000;border=false]"..
1351 "table[0,0.25;12,5.2;text_table;"..
1352 tutorial.convert_newlines(minetest.formspec_escape(S(text)))..
1354 "button_exit[4.5,5.5;3,1;close;"..S("Close").."]"
1355 minetest.show_formspec(name, "tutorial_dialog", formspec)
1358 minetest.register_on_joinplayer(function(player)
1359 local formspec = nil
1360 if(minetest.is_singleplayer() == false) then
1361 formspec = "size[12,6]"..
1362 "label[-0.15,-0.4;"..minetest.formspec_escape(S("Warning: You're not playing in singleplayer mode")).."]"..
1363 "tablecolumns[text]"..
1364 "tableoptions[background=#000000;highlight=#000000;border=false]"..
1365 "table[0,0.25;12,5.2;creative_text;"..
1366 tutorial.convert_newlines(minetest.formspec_escape(S(tutorial.texts.notsingleplayer)))..
1368 "button_exit[2.5,5.5;3,1;close;"..minetest.formspec_escape(S("Continue anyways")).."]"..
1369 "button_exit[6.5,5.5;3,1;leave;"..minetest.formspec_escape(S("Leave tutorial")).."]"
1370 elseif(not map_editing and minetest.settings:get_bool("creative_mode")) then
1371 formspec = "size[12,6]"..
1372 "label[-0.15,-0.4;"..(minetest.formspec_escape(S("Warning: Creative mode is active"))).."]"..
1373 "tablecolumns[text]"..
1374 "tableoptions[background=#000000;highlight=#000000;border=false]"..
1375 "table[0,0.25;12,5.2;creative_text;"..
1376 tutorial.convert_newlines(minetest.formspec_escape(S(tutorial.texts.creative)))..
1378 "button_exit[2.5,5.5;3,1;close;"..minetest.formspec_escape(S("Continue anyways")).."]"..
1379 "button_exit[6.5,5.5;3,1;leave;"..minetest.formspec_escape(S("Leave tutorial")).."]"
1381 elseif(not map_editing and tutorial.state.intro_text == false) then
1382 formspec = "size[12,6]"..
1383 "label[-0.15,-0.4;"..minetest.formspec_escape(S("Introduction")).."]"..
1384 "tablecolumns[text]"..
1385 "tableoptions[background=#000000;highlight=#000000;border=false]"..
1386 "table[0,0.25;12,5.2;intro_text;"..
1387 tutorial.convert_newlines(minetest.formspec_escape(S(tutorial.texts.intro)))..
1389 "button_exit[4.5,5.5;3,1;close;"..minetest.formspec_escape(S("Close")).."]"
1390 tutorial.state.intro_text = true
1392 if tutorial.state.first_join==true and tutorial.first_spawn then
1393 player:set_pos(tutorial.first_spawn.pos)
1394 player:set_look_horizontal(tutorial.first_spawn.yaw)
1395 tutorial.state.first_join = false
1397 tutorial.save_state()
1398 if(formspec~=nil) then
1399 minetest.show_formspec(player:get_player_name(), "intro", formspec)
1404 local teleport_dialog = function(player)
1405 local formspec = "size[10,10]" ..
1406 "label[0,0;"..minetest.formspec_escape(S("Select teleport destination:")).."]"
1410 for i = 1, #tutorial.locations_order do
1411 local id = tutorial.locations_order[i]
1412 local data = tutorial.locations[id]
1414 if id == "goodbye" then
1415 caption = S("Good-Bye room")
1417 caption = S(tutorial.captions[id])
1419 formspec = formspec .. "button_exit["..x..","..y..";5,1;".."teleport_"..id..";"..minetest.formspec_escape(caption).."]"
1426 minetest.show_formspec(player:get_player_name(), "tutorial_teleport", formspec)
1429 minetest.register_on_player_receive_fields(function(player, formname, fields)
1430 if(fields.leave) then
1431 local name = player:get_player_name()
1432 local reason = S("You have voluntarily exited the tutorial.")
1433 if minetest.disconnect_player then
1434 minetest.disconnect_player(name, reason)
1436 minetest.kick_player(name, reason)
1439 elseif(fields.teleport) then
1440 teleport_dialog(player)
1442 elseif(fields.gotoend) then
1443 tutorial.go_to_end(player)
1446 if formname == "tutorial_teleport" then
1447 for id, data in pairs(tutorial.locations) do
1448 if(fields["teleport_"..id]) then
1449 tutorial.teleport(player, data[1], data[2], data[3])
1456 tutorial.steptimer = 0
1457 minetest.register_globalstep(function(dtime)
1458 tutorial.steptimer = tutorial.steptimer + dtime
1459 local players = minetest.get_connected_players()
1460 if(tutorial.steptimer > 2) then
1462 local player = players[p]
1463 local name = player:get_player_name()
1465 local inv = player:get_inventory()
1466 local state_changed = false
1468 if(tutorial.state.first_gold ~= true) then
1469 local gold_stack = ItemStack("default:gold_ingot 1")
1470 if(inv:contains_item("main", gold_stack)) then
1471 tutorial.show_default_dialog(
1473 S("Gold ingots in the tutorial"),
1474 tutorial.texts.first_gold
1476 tutorial.state.first_gold = true
1477 state_changed = true
1480 if(tutorial.state.last_gold ~= true) then
1481 local gold_stack = ItemStack("default:gold_ingot "..tostring(tutorial.gold))
1482 if(inv:contains_item("main", gold_stack)) then
1483 local formspec = "size[12,6]"..
1484 "label[-0.15,-0.4;"..minetest.formspec_escape(S("You've finished the tutorial!")).."]"..
1485 "tablecolumns[text]"..
1486 "tableoptions[background=#000000;highlight=#000000;border=false]"..
1487 "table[0,0.25;12,5.2;creative_text;"..
1488 tutorial.convert_newlines(minetest.formspec_escape(S(tutorial.texts.last_gold)))..
1490 "button_exit[0.5,5.5;3,1;close;"..minetest.formspec_escape(S("Continue")).."]"..
1491 "button_exit[4.5,5.5;3,1;leave;"..minetest.formspec_escape(S("Leave tutorial")).."]"..
1492 "button_exit[8.5,5.5;3,1;gotoend;"..minetest.formspec_escape(S("Go to Good-Bye room")).."]"
1494 minetest.show_formspec(name, "tutorial_last_gold", formspec)
1496 minetest.set_node({x=19,y=2,z=72}, {name="tutorial:cup_gold"})
1497 tutorial.state.last_gold = true
1498 state_changed = true
1502 if(tutorial.state.first_diamond ~= true) then
1503 local diamond_stack = ItemStack("default:diamond 1")
1504 if(inv:contains_item("main", diamond_stack)) then
1505 tutorial.show_default_dialog(
1507 S("You found a hidden diamond!"),
1508 tutorial.texts.first_diamond
1510 tutorial.state.first_diamond = true
1511 state_changed = true
1514 if(tutorial.state.last_diamond ~= true) then
1515 local diamond_stack = ItemStack("default:diamond "..tostring(tutorial.diamonds))
1516 if(inv:contains_item("main", diamond_stack)) then
1517 local formspec = "size[12,6]"..
1518 "label[-0.15,-0.4;"..minetest.formspec_escape(S("You have collected all hidden diamonds!")).."]"..
1519 "tablecolumns[text]"..
1520 "tableoptions[background=#000000;highlight=#000000;border=false]"..
1521 "table[0,0.25;12,5.2;last_diamond_text;"..
1522 tutorial.convert_newlines(minetest.formspec_escape(S(tutorial.texts.last_diamond)))..
1524 "button_exit[2.5,5.5;3,1;close;"..minetest.formspec_escape(S("Continue")).."]"..
1525 "button_exit[6.5,5.5;3,1;gotoend;"..minetest.formspec_escape(S("Go to Good-Bye room")).."]"
1526 minetest.show_formspec(name, "tutorial_last_diamond", formspec)
1528 minetest.set_node({x=19,y=2,z=74}, {name="tutorial:cup_diamond"})
1529 tutorial.state.last_diamond = true
1530 state_changed = true
1534 if(state_changed) then
1535 tutorial.save_state()
1539 tutorial.steptimer = 0
1543 function tutorial.teleport(player, pos, look_horizontal, look_vertical)
1545 player:set_look_horizontal(look_horizontal)
1546 if not look_vertical then
1549 player:set_look_vertical(look_vertical)
1552 function tutorial.back_to_start(player)
1553 tutorial.teleport(player, tutorial.locations.intro[1], tutorial.locations.intro[2])
1556 function tutorial.go_to_end(player)
1557 tutorial.teleport(player, tutorial.locations.goodbye[1], tutorial.locations.goodbye[2])
1561 Helper tools for sign text extracting
1562 must be called with /lua from luacmd
1563 An ugly, quick and dirty hack.
1564 TODO: Toss away intllib in favor of gettext as soon as possible
1567 function tutorial.convert_newlines_for_intllib(str)
1568 local function convert(s)
1569 return s:gsub("\n", function(slash, what)
1577 function tutorial.extract_texts()
1578 local filepath = minetest.get_modpath("tutorial").."/locale/template_texts.txt"
1579 local file = io.open(filepath, "w+")
1581 for k,v in pairs(tutorial.texts) do
1582 file:write("# Tutorial text: "..k.."\n")
1583 file:write(tutorial.convert_newlines_for_intllib(v).."\n\n")
1586 minetest.log("error", "[tutorial] An attempt to write into "..filepath.." failed.")