Fix grammar issues spotted by grammarly

master
rubenwardy 2019-05-31 18:32:40 +01:00
parent 2934517a5d
commit 79a522f852
25 changed files with 297 additions and 265 deletions

View File

@ -9,17 +9,23 @@ redirect_from:
- /en/basics/folders.html - /en/basics/folders.html
--- ---
## Introduction ## Introduction <!-- omit in toc -->
Understanding the basic structure of a mod's folder is an essential skill when Understanding the basic structure of a mod's folder is an essential skill when
creating mods. creating mods.
* [What are Games and Mods?](#what-are-games-and-mods) - [What are Games and Mods?](#what-are-games-and-mods)
* [Where are mods stored?](#where-are-mods-stored) - [Where are mods stored?](#where-are-mods-stored)
* [Mod Directory](#mod-directory) - [Mod Directory](#mod-directory)
* [Dependencies](#dependencies) - [Dependencies](#dependencies)
* [Mod Packs](#mod-packs) - [mod.conf](#modconf)
* [Example](#example) - [depends.txt](#dependstxt)
- [Mod Packs](#mod-packs)
- [Example](#example)
- [Mod Folder](#mod-folder)
- [depends.txt](#dependstxt-1)
- [init.lua](#initlua)
- [mod.conf](#modconf-1)
## What are Games and Mods? ## What are Games and Mods?

View File

@ -7,21 +7,22 @@ description: A basic introduction to Lua, including a guide on global/local scop
redirect_from: /en/chapters/lua.html redirect_from: /en/chapters/lua.html
--- ---
## Introduction ## Introduction <!-- omit in toc -->
In this chapter we will talk about scripting in Lua, the tools required, 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.
* [Code Editors](#code-editors) - [Code Editors](#code-editors)
* [Coding in Lua](#coding-in-lua) - [Coding in Lua](#coding-in-lua)
* [Program Flow](#program-flow) - [Program Flow](#program-flow)
* [Variable Types](#variable-types) - [Variable Types](#variable-types)
* [Arithmetic Operators](#arithmetic-operators) - [Arithmetic Operators](#arithmetic-operators)
* [Selection](#selection) - [Selection](#selection)
* [Logical Operators](#logical-operators) - [Logical Operators](#logical-operators)
* [Programming](#programming) - [Programming](#programming)
* [Local and Global Scope](#local-and-global-scope) - [Local and Global Scope](#local-and-global-scope)
* [Including other Lua Scripts](#including-other-lua-scripts) - [Locals should be used as much as possible](#locals-should-be-used-as-much-as-possible)
- [Including other Lua Scripts](#including-other-lua-scripts)
## Code Editors ## Code Editors
@ -182,8 +183,8 @@ however, the following websites are quite useful in developing this:
* [Codecademy](http://www.codecademy.com/) is one of the best resources for * [Codecademy](http://www.codecademy.com/) is one of the best resources for
learning to 'code', it provides an interactive tutorial experience. learning to 'code', it provides an interactive tutorial experience.
* [Scratch](https://scratch.mit.edu) is a good resource when starting from * [Scratch](https://scratch.mit.edu) is a good resource when starting from
absolute basics, learning the problem solving techniques required to program.\\ absolute basics, learning the problem-solving techniques required to program.\\
Scratch is **designed to teach children** how to program, and isn't a serious Scratch is **designed to teach children** how to program and isn't a serious
programming language. programming language.
## Local and Global Scope ## Local and Global Scope
@ -243,7 +244,7 @@ dump() is a function that can turn any variable into a string so the programmer
see what it is. The foo variable will be printed as "bar", including the quotes see what it is. The foo variable will be printed as "bar", including the quotes
which show it is a string. which show it is a string.
This is sloppy coding, and Minetest will in fact warn about this: This is sloppy coding and Minetest will, in fact, warn about this:
Assignment to undeclared global 'foo' inside function at init.lua:2 Assignment to undeclared global 'foo' inside function at init.lua:2

View File

@ -5,26 +5,26 @@ root: ../..
idx: 6.1 idx: 6.1
--- ---
## Introduction ## Introduction <!-- omit in toc -->
The power of Minetest is the ability to easily develop games without the need The power of Minetest is the ability to easily develop games without the need
to create your own voxel graphics, voxel algorithms, or fancy networking code. to create your own voxel graphics, voxel algorithms, or fancy networking code.
* [What is a Game?](#what-is-a-game) - [What is a Game?](#what-is-a-game)
* [Game Directory](#game-directory) - [Game Directory](#game-directory)
* [Inter-game Compatibility](#inter-game-compatibility) - [Inter-game Compatibility](#inter-game-compatibility)
* [API Compatibility](#api-compatibility) - [API Compatibility](#api-compatibility)
* [Groups and Aliases](#groups-and-aliases) - [Groups and Aliases](#groups-and-aliases)
* [Your Turn](#your-turn) - [Your Turn](#your-turn)
## What is a Game? ## What is a Game?
Games are a collection of mods which work together to make a cohesive game. Games are a collection of mods which work together to make a cohesive game.
A good game has a consistent underlying theme and a direction, for example A good game has a consistent underlying theme and a direction, for example,
it could be a classic crafter miner with hard survival elements, or it could be a classic crafter miner with hard survival elements, or
it could be a space simulation game with a steam punk automation aesthetic. it could be a space simulation game with a steampunk automation aesthetic.
Game design is a complex topic, and is actually a whole field of expertise. Game design is a complex topic and is actually a whole field of expertise.
It's beyond the scope of the book to more than briefly touch on it. It's beyond the scope of the book to more than briefly touch on it.
## Game Directory ## Game Directory
@ -90,4 +90,4 @@ good idea to provide aliases from default nodes to any direct replacements.
## Your Turn ## Your Turn
* Make a game - It can be simple, if you like. * Create a simple game where the player gains points from digging special blocks.

View File

@ -7,7 +7,7 @@ description: An introduction to making textures in your editor of choice, an a g
redirect_from: /en/chapters/creating_textures.html redirect_from: /en/chapters/creating_textures.html
--- ---
## Introduction ## Introduction <!-- omit in toc -->
Being able to create and optimise textures is a very useful skill when Being able to create and optimise textures is a very useful skill when
developing for Minetest. developing for Minetest.
@ -21,9 +21,13 @@ will be covered.
There are many [good online tutorials](http://www.photonstorm.com/art/tutorials-art/16x16-pixel-art-tutorial) There are many [good online tutorials](http://www.photonstorm.com/art/tutorials-art/16x16-pixel-art-tutorial)
available, which cover pixel art in much more detail. available, which cover pixel art in much more detail.
* [Learning to Draw](#learning-to-draw) - [Techniques](#techniques)
* [Techniques](#techniques) - [Using the Pencil](#using-the-pencil)
* [Editors](#editors) - [Tiling](#tiling)
- [Transparency](#transparency)
- [Editors](#editors)
- [MS Paint](#ms-paint)
- [GIMP](#gimp)
## Techniques ## Techniques

View File

@ -11,23 +11,23 @@ redirect_from:
- /en/inventories/itemstacks.html - /en/inventories/itemstacks.html
--- ---
## Introduction ## Introduction <!-- omit in toc -->
In this chapter you will learn how to use and manipulate inventories, whether In this chapter, you will learn how to use and manipulate inventories, whether
that be a player inventory, a node inventory, or a detached inventory. that be a player inventory, a node inventory, or a detached inventory.
* [What are Item Stacks and Inventories?](#what-are-item-stacks-and-inventories) - [What are ItemStacks and Inventories?](#what-are-itemstacks-and-inventories)
* [ItemStacks](#itemstacks) - [ItemStacks](#itemstacks)
* [Inventory Locations](#inventory-locations) - [Inventory Locations](#inventory-locations)
* [Lists](#lists) - [Lists](#lists)
* [Size and Width](#size-and-width) - [Size and Width](#size-and-width)
* [Checking Contents](#checking-contents) - [Checking Contents](#checking-contents)
* [Modifying Inventories and ItemStacks](#modifying-inventories-and-itemstacks) - [Modifying Inventories and ItemStacks](#modifying-inventories-and-itemstacks)
* [Adding to a List](#adding-to-a-list) - [Adding to a List](#adding-to-a-list)
* [Taking Items](#taking-items) - [Taking Items](#taking-items)
* [Manipulating Stacks](#manipulating-stacks) - [Manipulating Stacks](#manipulating-stacks)
* [Wear](#wear) - [Wear](#wear)
* [Lua Tables](#lua-tables) - [Lua Tables](#lua-tables)
## What are ItemStacks and Inventories? ## What are ItemStacks and Inventories?
@ -101,7 +101,7 @@ An inventory is directly tied to one and only one location - updating the invent
will cause it to update immediately. will cause it to update immediately.
Node inventories are related to the position of a specific node, such as a chest. Node inventories are related to the position of a specific node, such as a chest.
The node must be loaded, because it is stored in [node metadata](node_metadata.html). The node must be loaded because it is stored in [node metadata](node_metadata.html).
```lua ```lua
local inv = minetest.get_inventory({ type="node", pos={x=1, y=2, z=3} }) local inv = minetest.get_inventory({ type="node", pos={x=1, y=2, z=3} })
@ -147,7 +147,7 @@ which all games have, such as the *main* inventory and *craft* slots.
Lists have a size, which is the total number of cells in the grid, and a width, Lists have a size, which is the total number of cells in the grid, and a width,
which is only used within the engine. which is only used within the engine.
The list width is not used when drawing the inventory in a window, The width of the list is not used when drawing the inventory in a window,
because the code behind the window determines the width to use. because the code behind the window determines the width to use.
```lua ```lua
@ -222,7 +222,7 @@ print("Could not add" .. leftover:get_count() .. " of the items.")
-- ^ will be 51 -- ^ will be 51
print("Have " .. stack:get_count() .. " items") print("Have " .. stack:get_count() .. " items")
-- ^ will be 80 -- ^ will be 80
-- min(50+100, stack_max) - 19 = 80 -- min(50+100, stack_max) - 19 = 80
-- where stack_max = 99 -- where stack_max = 99
``` ```
@ -252,7 +252,7 @@ local max_uses = 10
stack:add_wear(65535 / (max_uses - 1)) stack:add_wear(65535 / (max_uses - 1))
``` ```
When digging a node, the amount of wear a tool gets may depends on the node When digging a node, the amount of wear a tool gets may depend on the node
being dug. So max_uses varies depending on what is being dug. being dug. So max_uses varies depending on what is being dug.
## Lua Tables ## Lua Tables

View File

@ -7,7 +7,7 @@ description: Guide to all drawtypes, including node boxes/nodeboxes and mesh nod
redirect_from: /en/chapters/node_drawtypes.html redirect_from: /en/chapters/node_drawtypes.html
--- ---
## Introduction ## Introduction <!-- omit in toc -->
The method by which a node is drawn is called a *drawtype*. There are many The method by which a node is drawn is called a *drawtype*. There are many
available drawtypes. The behaviour of a drawtype can be controlled available drawtypes. The behaviour of a drawtype can be controlled
@ -26,19 +26,19 @@ The node params are used to control how a node is individually rendered.
`param1` is used to store the lighting of a node, and the meaning of `param1` is used to store the lighting of a node, and the meaning of
`param2` depends on the `paramtype2` property of the node type definition. `param2` depends on the `paramtype2` property of the node type definition.
* [Cubic Nodes: Normal and Allfaces](#cubic-nodes-normal-and-allfaces) - [Cubic Nodes: Normal and Allfaces](#cubic-nodes-normal-and-allfaces)
* [Glasslike Nodes](#glasslike-nodes) - [Glasslike Nodes](#glasslike-nodes)
* [Glasslike_Framed](#glasslike_framed) - [Glasslike_Framed](#glasslikeframed)
* [Airlike Nodes](#airlike-nodes) - [Airlike Nodes](#airlike-nodes)
* [Lighting and Sunlight Propagation](#lighting-and-sunlight-propagation) - [Lighting and Sunlight Propagation](#lighting-and-sunlight-propagation)
* [Liquid Nodes](#liquid-nodes) - [Liquid Nodes](#liquid-nodes)
* [Node Boxes](#node-boxes) - [Node Boxes](#node-boxes)
* [Wallmounted Node Boxes](#wallmounted-node-boxes) - [Wallmounted Node Boxes](#wallmounted-node-boxes)
* [Mesh Nodes](#mesh-nodes) - [Mesh Nodes](#mesh-nodes)
* [Signlike Nodes](#signlike-nodes) - [Signlike Nodes](#signlike-nodes)
* [Plantlike Nodes](#plantlike-Nodes) - [Plantlike Nodes](#plantlike-nodes)
* [Firelike Nodes](#firelike-nodes) - [Firelike Nodes](#firelike-nodes)
* [More Drawtypes](#more-drawtypes) - [More Drawtypes](#more-drawtypes)
## Cubic Nodes: Normal and Allfaces ## Cubic Nodes: Normal and Allfaces
@ -135,7 +135,7 @@ minetest.register_node("default:glass", {
## Airlike Nodes ## Airlike Nodes
These nodes are not rendered, and thus have no textures. These nodes are not rendered and thus have no textures.
```lua ```lua
minetest.register_node("myair:air", { minetest.register_node("myair:air", {
@ -284,7 +284,7 @@ minetest.register_node("stairs:stair_stone", {
}) })
``` ```
The most important part is the nodebox table: The most important part is the node box table:
```lua ```lua
{-0.5, -0.5, -0.5, 0.5, 0, 0.5}, {-0.5, -0.5, -0.5, 0.5, 0, 0.5},
@ -350,12 +350,12 @@ minetest.register_node("mymod:meshy", {
}, },
-- Path to the mesh -- Path to the mesh
mesh = "mymod_meshy.b3d", mesh = "mymod_meshy.b3d",
}) })
``` ```
Make sure that the mesh is available in a `models` directory. Make sure that the mesh is available in a `models` directory.
Most of the time the mesh should be in your mod's folder, however it's okay to Most of the time the mesh should be in your mod's folder, however, it's okay to
share a mesh provided by another mod you depend on. For example, a mod that share a mesh provided by another mod you depend on. For example, a mod that
adds more types of furniture may want to share the model provided by a basic adds more types of furniture may want to share the model provided by a basic
furniture mod. furniture mod.
@ -370,7 +370,7 @@ instead use the `nodebox` drawtype to provide a 3D effect. The `signlike` drawty
is, however, commonly used by ladders. is, however, commonly used by ladders.
```lua ```lua
minetest.register_node("default:ladder_wood", { minetest.register_node("default:ladder_wood", {
drawtype = "signlike", drawtype = "signlike",
tiles = {"default_ladder_wood.png"}, tiles = {"default_ladder_wood.png"},
@ -433,7 +433,7 @@ minetest.register_node("mymod:clingere", {
## More Drawtypes ## More Drawtypes
This is not a comprehensive list, there's more types including: This is not a comprehensive list, there are more types including:
* Fencelike * Fencelike
* Plantlike rooted - for underwater plants * Plantlike rooted - for underwater plants

View File

@ -7,28 +7,30 @@ description: Learn how to register node, items, and craft recipes using register
redirect_from: /en/chapters/nodes_items_crafting.html redirect_from: /en/chapters/nodes_items_crafting.html
--- ---
## Introduction ## Introduction <!-- omit in toc -->
Registering new nodes and craftitems, and creating craft recipes, are Registering new nodes and craftitems, and creating craft recipes, are
basic requirements for many mods. basic requirements for many mods.
* [What are Nodes and Items?](#what-are-nodes-and-items) - [What are Nodes and Items?](#what-are-nodes-and-items)
* [Registering Items](#registering-items) - [Registering Items](#registering-items)
* [Item Names and Aliases](#item-names-and-aliases) - [Item Names and Aliases](#item-names-and-aliases)
* [Textures](#textures) - [Textures](#textures)
* [Registering a Basic Node](#registering-a-basic-node) - [Registering a basic node](#registering-a-basic-node)
* [Actions and Callbacks](#actions-and-callbacks) - [Actions and Callbacks](#actions-and-callbacks)
* [on_use](#on_use) - [on_use](#onuse)
* [Crafting](#crafting) - [Crafting](#crafting)
* [Fuel](#fuel) - [Shaped](#shaped)
* [Groups](#groups) - [Shapeless](#shapeless)
* [Tools, Capabilities, and Dig Types](#tools-capabilities-and-dig-types) - [Cooking and Fuel](#cooking-and-fuel)
- [Groups](#groups)
- [Tools, Capabilities, and Dig Types](#tools-capabilities-and-dig-types)
## What are Nodes and Items? ## What are Nodes and Items?
Nodes, craftitems, and tools are all Items. Nodes, craftitems, and tools are all Items.
An item is something that could be found in an inventory - An item is something that could be found in an inventory -
even though it may not be possible through normal game play. even though it may not be possible through normal gameplay.
A node is an item which can be placed or be found in the world. A node is an item which can be placed or be found in the world.
Every position in the world must be occupied with one and only one node - Every position in the world must be occupied with one and only one node -
@ -102,7 +104,7 @@ It is often better to use the PNG format.
Textures in Minetest are usually 16 by 16 pixels. Textures in Minetest are usually 16 by 16 pixels.
They can be any resolution, but it is recommended that they are in the order of 2, They can be any resolution, but it is recommended that they are in the order of 2,
for example 16, 32, 64, or 128. for example, 16, 32, 64, or 128.
This is because other resolutions may not be supported correctly on older devices, This is because other resolutions may not be supported correctly on older devices,
resulting in decreased performance. resulting in decreased performance.
@ -283,7 +285,7 @@ defines how long the item takes to cook.
If this is not set, it defaults to 3. If this is not set, it defaults to 3.
The recipe above works when the coal block is in the input slot, The recipe above works when the coal block is in the input slot,
with some form of a fuel below it. with some form of fuel below it.
It creates diamond fragments after 10 seconds! It creates diamond fragments after 10 seconds!
This type is an accompaniment to the cooking type, as it defines This type is an accompaniment to the cooking type, as it defines
@ -304,7 +306,7 @@ So, the diamond is good as fuel for 300 seconds!
## Groups ## Groups
Items can be members of many groups and groups can have many members. Items can be members of many groups and groups can have many members.
Groups are defined using the `groups` property in the definition table, Groups are defined using the `groups` property in the definition table
and have an associated value. and have an associated value.
```lua ```lua
@ -314,7 +316,7 @@ groups = {cracky = 3, wood = 1}
There are several reasons you use groups. There are several reasons you use groups.
Firstly, groups are used to describe properties such as dig types and flammability. Firstly, groups are used to describe properties such as dig types and flammability.
Secondly, groups can be used in a craft recipe instead of an item name to allow Secondly, groups can be used in a craft recipe instead of an item name to allow
any item in group to be used. any item in the group to be used.
```lua ```lua
minetest.register_craft({ minetest.register_craft({

View File

@ -7,19 +7,19 @@ description: Basic operations like set_node and get_node
redirect_from: /en/chapters/environment.html redirect_from: /en/chapters/environment.html
--- ---
## Introduction ## Introduction <!-- omit in toc -->
In this chapter you will learn how to perform basic actions on the map. In this chapter, you will learn how to perform basic actions on the map.
* [Map Structure](#map-structure) - [Map Structure](#map-structure)
* [Reading](#reading) - [Reading](#reading)
* [Reading Nodes](#reading-nodes) - [Reading Nodes](#reading-nodes)
* [Finding Nodes](#finding-nodes) - [Finding Nodes](#finding-nodes)
* [Writing](#writing) - [Writing](#writing)
* [Writing Nodes](#writing-nodes) - [Writing Nodes](#writing-nodes)
* [Removing Nodes](#removing-nodes) - [Removing Nodes](#removing-nodes)
* [Loading Blocks](#loading-blocks) - [Loading Blocks](#loading-blocks)
* [Deleting Blocks](#deleting-blocks) - [Deleting Blocks](#deleting-blocks)
## Map Structure ## Map Structure
@ -95,7 +95,7 @@ local grow_speed = 1 + #pos_list
``` ```
The above code doesn't quite do what we want, as it checks based on area, whereas The above code doesn't quite do what we want, as it checks based on area, whereas
`find_node_near` checks based on range. In order to fix this we will, `find_node_near` checks based on range. In order to fix this, we will,
unfortunately, need to manually check the range ourselves. unfortunately, need to manually check the range ourselves.
```lua ```lua
@ -159,7 +159,7 @@ minetest.remove_node(pos)
minetest.set_node(pos, { name = "air" }) minetest.set_node(pos, { name = "air" })
``` ```
In fact, remove_node will call set_node with name being air. In fact, remove_node will call set_node with the name being air.
## Loading Blocks ## Loading Blocks
@ -204,7 +204,7 @@ local function emerge_callback(pos, action,
end end
``` ```
This is not the only way of loading blocks; using a LVM will also cause the This is not the only way of loading blocks; using an LVM will also cause the
encompassed blocks to be loaded synchronously. encompassed blocks to be loaded synchronously.
## Deleting Blocks ## Deleting Blocks

View File

@ -7,21 +7,21 @@ description: Learn how to use LVMs to speed up map operations.
redirect_from: /en/chapters/lvm.html redirect_from: /en/chapters/lvm.html
--- ---
## Introduction ## Introduction <!-- omit in toc -->
The functions outlined in the [Basic Map Operations](environment.html) chapter The functions outlined in the [Basic Map Operations](environment.html) chapter
are convenient and easy to use, but for large areas they are inefficient. are convenient and easy to use, but for large areas they are inefficient.
Every time you call `set_node` or `get_node`, your mod needs to communicate with Every time you call `set_node` or `get_node`, your mod needs to communicate with
the engine. This results in constant individual copying operations between the the engine. This results in constant individual copying operations between the
engine and your mod, which is slow, and will quickly decrease the performance of engine and your mod, which is slow and will quickly decrease the performance of
your game. Using a Lua Voxel Manipulator (LVM) can be a better alternative. your game. Using a Lua Voxel Manipulator (LVM) can be a better alternative.
* [Concepts](#concepts) - [Concepts](#concepts)
* [Reading into the LVM](#reading-into-the-lvm) - [Reading into the LVM](#reading-into-the-lvm)
* [Reading Nodes](#reading-nodes) - [Reading Nodes](#reading-nodes)
* [Writing Nodes](#writing-nodes) - [Writing Nodes](#writing-nodes)
* [Example](#example) - [Example](#example)
* [Your Turn](#your-turn) - [Your Turn](#your-turn)
## Concepts ## Concepts
@ -78,8 +78,8 @@ print(data[idx])
``` ```
When you run this, you'll notice that `data[vi]` is an integer. This is because When you run this, you'll notice that `data[vi]` is an integer. This is because
the engine doesn't store nodes using their name string, as string comparison the engine doesn't store nodes using strings, for performance reasons.
is slow. Instead, the engine uses an integer called a content ID. Instead, the engine uses an integer called a content ID.
You can find out the content ID for a particular type of node with You can find out the content ID for a particular type of node with
`get_content_id()`. For example: `get_content_id()`. For example:
@ -97,7 +97,7 @@ end
``` ```
It is recommended that you find and store the content IDs of nodes types It is recommended that you find and store the content IDs of nodes types
at load time, because the IDs of a node type will never change. Make sure to store at load time because the IDs of a node type will never change. Make sure to store
the IDs in a local variable for performance reasons. the IDs in a local variable for performance reasons.
Nodes in an LVM data array are stored in reverse co-ordinate order, so you should Nodes in an LVM data array are stored in reverse co-ordinate order, so you should
@ -128,7 +128,7 @@ another, and avoid *cache thrashing*.
## Writing Nodes ## Writing Nodes
First you need to set the new content ID in the data array: First, you need to set the new content ID in the data array:
```lua ```lua
for z = min.z, max.z do for z = min.z, max.z do
@ -172,7 +172,7 @@ local function grass_to_dirt(pos1, pos2)
local a = VoxelArea:new{ local a = VoxelArea:new{
MinEdge = emin, MinEdge = emin,
MaxEdge = emax MaxEdge = emax
} }
local data = vm:get_data() local data = vm:get_data()
-- Modify data -- Modify data

View File

@ -6,17 +6,17 @@ idx: 3.4
description: Using an ObjectRef description: Using an ObjectRef
--- ---
## Introduction ## Introduction <!-- omit in toc -->
In this chapter, you will learn how to manipulate objects and how to define your In this chapter, you will learn how to manipulate objects and how to define your
own. own.
* [What are Objects, Players, and Entities?](#objects_players_and_entities) - [What are Objects, Players, and Entities?](#what-are-objects-players-and-entities)
* [Position and Velocity](#position_and_velocity) - [Position and Velocity](#position-and-velocity)
* [Object Properties](#object_properties) - [Object Properties](#object-properties)
* [Entities](#entities) - [Entities](#entities)
* [Attachments](#attachments) - [Attachments](#attachments)
* [Your Turn](#your_turn) - [Your Turn](#your-turn)
## What are Objects, Players, and Entities? ## What are Objects, Players, and Entities?
@ -230,7 +230,7 @@ So, `0,5,0` would be half a node above the parent's origin.
For 3D models with animations, the bone argument is used to attach the entity For 3D models with animations, the bone argument is used to attach the entity
to a bone. to a bone.
3D animations are based on skeletons - a network of bones in the model where 3D animations are based on skeletons - a network of bones in the model where
each bone can be given a position and rotation to change the model, for example each bone can be given a position and rotation to change the model, for example,
to move the arm. to move the arm.
Attaching to a bone is useful if you want to make a character hold something. Attaching to a bone is useful if you want to make a character hold something.

View File

@ -9,22 +9,22 @@ redirect_from:
- /en/map/node_metadata.html - /en/map/node_metadata.html
--- ---
## Introduction ## Introduction <!-- omit in toc -->
In this chapter you will learn how you can store data. In this chapter, you will learn how you can store data.
* [Metadata](#metadata) - [Metadata](#metadata)
* [What is Metadata?](#what-is-metadata) - [What is Metadata?](#what-is-metadata)
* [Obtaining a Metadata Object](#obtaining-a-metadata-object) - [Obtaining a Metadata Object](#obtaining-a-metadata-object)
* [Reading and Writing](#reading-and-writing) - [Reading and Writing](#reading-and-writing)
* [Special Keys](#special-keys) - [Special Keys](#special-keys)
* [Private Metadata](#private-metadata) - [Storing Tables](#storing-tables)
* [Storing Tables](#storing-tables) - [Private Metadata](#private-metadata)
* [Lua Tables](#lua-tables) - [Lua Tables](#lua-tables)
* [Mod Storage](#mod-storage) - [Mod Storage](#mod-storage)
* [Databases](#databases) - [Databases](#databases)
* [Deciding Which to Use](#deciding-which-to-use) - [Deciding Which to Use](#deciding-which-to-use)
* [Your Turn](#your-turn) - [Your Turn](#your-turn)
## Metadata ## Metadata

View File

@ -9,7 +9,7 @@ redirect_from:
- /en/map/abms.html - /en/map/abms.html
--- ---
## Introduction ## Introduction <!-- omit in toc -->
Periodically running a function on certain nodes is a common task. Periodically running a function on certain nodes is a common task.
Minetest provides two methods of doing this: Active Block Modifiers (ABMs) and node timers. Minetest provides two methods of doing this: Active Block Modifiers (ABMs) and node timers.
@ -27,9 +27,9 @@ This means that timers don't need to search all loaded nodes to find matches,
but instead require slightly more memory and storage for the tracking but instead require slightly more memory and storage for the tracking
of pending timers. of pending timers.
* [Node Timers](#node-timers) - [Node Timers](#node-timers)
* [Active Block Modifiers](#active-block-modifiers) - [Active Block Modifiers](#active-block-modifiers)
* [Your Turn](#your-turn) - [Your Turn](#your-turn)
## Node Timers ## Node Timers
@ -99,7 +99,7 @@ minetest.register_abm({
}) })
``` ```
This ABM runs every ten seconds, and for each matching node there is This ABM runs every ten seconds, and for each matching node, there is
a 1 in 50 chance of it running. a 1 in 50 chance of it running.
If the ABM runs on a node, an alien grass node is placed above it. If the ABM runs on a node, an alien grass node is placed above it.
Please be warned, this will delete any node previously located in that position. Please be warned, this will delete any node previously located in that position.

View File

@ -24,16 +24,16 @@ cb_cmdsprivs:
--- ---
## Introduction ## Introduction <!-- omit in toc -->
Mods can interact with player chat, including Mods can interact with player chat, including
sending messages, intercepting messages, and registering chat commands. sending messages, intercepting messages, and registering chat commands.
* [Sending Messages to All Players](#sending-messages-to-all-players) - [Sending Messages to All Players](#sending-messages-to-all-players)
* [Sending Messages to Specific Players](#sending-messages-to-specific-players) - [Sending Messages to Specific Players](#sending-messages-to-specific-players)
* [Chat Commands](#chat-commands) - [Chat Commands](#chat-commands)
* [Complex Subcommands](#complex-subcommands) - [Complex Subcommands](#complex-subcommands)
* [Intercepting Messages](#intercepting-messages) - [Intercepting Messages](#intercepting-messages)
## Sending Messages to All Players ## Sending Messages to All Players
@ -60,7 +60,7 @@ minetest.chat_send_player("player1", "This is a chat message for player1")
``` ```
This message displays in the same manner as messages to all players, but is This message displays in the same manner as messages to all players, but is
only visible to the named player, in this case player1. only visible to the named player, in this case, player1.
## Chat Commands ## Chat Commands

View File

@ -7,20 +7,20 @@ description: Use ChatCmdBuilder to make a complex chat command
redirect_from: /en/chapters/chat_complex.html redirect_from: /en/chapters/chat_complex.html
--- ---
## Introduction ## Introduction <!-- omit in toc -->
This chapter will show you how to make complex chat commands with ChatCmdBuilder, This chapter will show you how to make complex chat commands with ChatCmdBuilder,
such as `/msg <name> <message>`, `/team join <teamname>` or `/team leave <teamname>`. such as `/msg <name> <message>`, `/team join <teamname>` or `/team leave <teamname>`.
Note that ChatCmdBuilder is a library created by the author of this book, and most Note that ChatCmdBuilder is a library created by the author of this book, and most
modders tend to use the method outlined in the modders tend to use the method outlined in the
[chat commnds](chat.html#complex-subcommands) chapter. [Chat and Commands](chat.html#complex-subcommands) chapter.
* Why ChatCmdBuilder? - [Why ChatCmdBuilder?](#why-chatcmdbuilder)
* Routes. - [Routes](#routes)
* Subcommand functions. - [Subcommand functions](#subcommand-functions)
* Installing ChatCmdBuilder. - [Installing ChatCmdBuilder](#installing-chatcmdbuilder)
* Admin complex command. - [Admin complex command](#admin-complex-command)
## Why ChatCmdBuilder? ## Why ChatCmdBuilder?
@ -30,13 +30,13 @@ Traditionally mods implemented these complex commands using Lua patterns.
local name = string.match(param, "^join ([%a%d_-]+)") local name = string.match(param, "^join ([%a%d_-]+)")
``` ```
I however find Lua patterns annoying to write and unreadable. I, however, find Lua patterns annoying to write and unreadable.
Because of this, I created a library to do this for you. Because of this, I created a library to do this for you.
```lua ```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
@ -55,10 +55,10 @@ end, {
`ChatCmdBuilder.new(name, setup_func, def)` creates a new chat command called `ChatCmdBuilder.new(name, setup_func, def)` creates a new chat command called
`name`. It then calls the function passed to it (`setup_func`), which then creates `name`. It then calls the function passed to it (`setup_func`), which then creates
sub commands. Each `cmd:sub(route, func)` is a sub command. subcommands. Each `cmd:sub(route, func)` is a subcommand.
A sub command is a particular response to an input param. When a player runs A subcommand is a particular response to an input param. When a player runs
the chat command, the first sub command that matches their input will be run, the chat command, the first subcommand that matches their input will be run,
and no others. If no subcommands match, then the user will be told of the invalid and no others. If no subcommands match, then the user will be told of the invalid
syntax. For example, in the above code snippet if a player syntax. For example, in the above code snippet if a player
types something of the form `/sethp username 12` then the function passed types something of the form `/sethp username 12` then the function passed
@ -89,7 +89,7 @@ Valid types are:
* `text` - Any string. There can only ever be one text variable, * `text` - Any string. There can only ever be one text variable,
no variables or terminals can come afterwards. no variables or terminals can come afterwards.
In `:name :hp:int`, there are two variables there: In `:name :hp:int`, there are two variables:
* `name` - type of `word` as no type is specified. Accepts any string without spaces. * `name` - type of `word` as no type is specified. Accepts any string without spaces.
* `hp` - type of `int` * `hp` - type of `int`

View File

@ -13,7 +13,7 @@ submit_vuln:
and make sure that they should be allowed to perform the action. and make sure that they should be allowed to perform the action.
--- ---
## Introduction ## Introduction <!-- omit in toc -->
<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">
@ -27,11 +27,16 @@ A formspec is the specification code for a form.
In Minetest, forms are windows such as the player inventory, which can contain labels, In Minetest, forms are windows such as the player inventory, which can contain labels,
buttons and fields to allow you to enter information. buttons and fields to allow you to enter information.
* [Formspec Syntax](#formspec-syntax) - [Formspec Syntax](#formspec-syntax)
* [Displaying Forms](#displaying-forms) - [Size[w, h]](#sizew-h)
* [Callbacks](#callbacks) - [Field[x, y; w, h; name; label; default]](#fieldx-y-w-h-name-label-default)
* [Contexts](#contexts) - [Other Elements](#other-elements)
* [Node Meta Formspecs](#node-meta-formspecs) - [Displaying Formspecs](#displaying-formspecs)
- [Example](#example)
- [Callbacks](#callbacks)
- [Fields](#fields)
- [Contexts](#contexts)
- [Node Meta Formspecs](#node-meta-formspecs)
Note that if you do not need to get user input, for example when you only need Note that if you do not need to get user input, for example when you only need
to provide information to the player, you should consider using Heads Up Display to provide information to the player, you should consider using Heads Up Display
@ -184,7 +189,7 @@ was clicked. In this case, the button called 'exit' was clicked, so fields.exit
will be true. will be true.
Some elements can submit the form without the user clicking a button, Some elements can submit the form without the user clicking a button,
such as a check box. You can detect these cases by looking such as a checkbox. You can detect these cases by looking
for a clicked button. for a clicked button.
```lua ```lua
@ -265,7 +270,7 @@ end)
## Node Meta Formspecs ## Node Meta Formspecs
minetest.show_formspec is not the only way to show a formspec; you can also minetest.show_formspec is not the only way to show a formspec; you can also
add formspecs to a [node's meta data](node_metadata.html). For example, add formspecs to a [node's metadata](node_metadata.html). For example,
this is used with chests to allow for faster opening times - this is used with chests to allow for faster opening times -
you don't need to wait for the server to send the player the chest formspec. you don't need to wait for the server to send the player the chest formspec.

View File

@ -6,25 +6,25 @@ idx: 4.6
redirect_from: /en/chapters/hud.html redirect_from: /en/chapters/hud.html
--- ---
## Introduction ## Introduction <!-- omit in toc -->
Heads Up Display (HUD) elements allow you to show text, images, and other graphical elements. Heads Up Display (HUD) elements allow you to show text, images, and other graphical elements.
The HUD doesn't accept user input; for that, you should use a [formspec](formspecs.html). The HUD doesn't accept user input; for that, you should use a [formspec](formspecs.html).
* [Positioning](#positioning) - [Positioning](#positioning)
* [Position and Offset](#position-and-offset) - [Position and Offset](#position-and-offset)
* [Alignment](#alignment) - [Alignment](#alignment)
* [Scoreboard](#scoreboard) - [Scoreboard](#scoreboard)
* [Text Elements](#text-elements) - [Text Elements](#text-elements)
* [Parameters](#parameters) - [Parameters](#parameters)
* [Our Example](#our-example) - [Our Example](#our-example)
* [Image Elements](#image-elements) - [Image Elements](#image-elements)
* [Parameters](#parameters-1) - [Parameters](#parameters-1)
* [Scale](#scale) - [Scale](#scale)
* [Changing an Element](#changing-an-element) - [Changing an Element](#changing-an-element)
* [Storing IDs](#storing-ids) - [Storing IDs](#storing-ids)
* [Other Elements](#other-elements) - [Other Elements](#other-elements)
## Positioning ## Positioning
@ -191,7 +191,7 @@ The `text` field is used to provide the image name.
If a co-ordinate is positive, then it is a scale factor with 1 being the If a co-ordinate is positive, then it is a scale factor with 1 being the
original image size, 2 being double the size, and so on. original image size, 2 being double the size, and so on.
However, if a co-ordinate is negative, it is a percentage of the screensize. However, if a co-ordinate is negative, it is a percentage of the screen size.
For example, `x=-100` is 100% of the width. For example, `x=-100` is 100% of the width.
### Scale ### Scale

View File

@ -6,19 +6,20 @@ idx: 4.4
redirect_from: /en/chapters/player_physics.html redirect_from: /en/chapters/player_physics.html
--- ---
## Introduction ## Introduction <!-- omit in toc -->
Player physics can be modified using physics overrides. Player physics can be modified using physics overrides.
Physics overrides can set the walking speed, jump speed, Physics overrides can set the walking speed, jump speed,
and gravity constants. and gravity constants.
Physics overrides are set on a player-by-player basis, Physics overrides are set on a player-by-player basis
and are multipliers. and are multipliers.
For example, a value of 2 for gravity would make gravity twice as strong. For example, a value of 2 for gravity would make gravity twice as strong.
* [Basic Example](#basic_example) - [Basic Example](#basic-example)
* [Available Overrides](#available_overrides) - [Available Overrides](#available-overrides)
* [Mod Incompatibility](#mod_incompatibility) - [Old Movement Behaviour](#old-movement-behaviour)
* [Your Turn](#your_turn) - [Mod Incompatibility](#mod-incompatibility)
- [Your Turn](#your-turn)
## Basic Example ## Basic Example
@ -46,7 +47,7 @@ these can be:
* speed: multiplier to default walking speed value (default: 1) * speed: multiplier to default walking speed value (default: 1)
* jump: multiplier to default jump value (default: 1) * jump: multiplier to default jump value (default: 1)
* gravity: multiplier to default gravity value (default: 1) * gravity: multiplier to default gravity value (default: 1)
* sneak: whether player can sneak (default: true) * sneak: whether the player can sneak (default: true)
### Old Movement Behaviour ### Old Movement Behaviour

View File

@ -7,17 +7,17 @@ description: Registering privs.
redirect_from: /en/chapters/privileges.html redirect_from: /en/chapters/privileges.html
--- ---
## Introduction ## Introduction <!-- omit in toc -->
Privileges, often called privs for short, give players the ability to perform Privileges, often called privs for short, give players the ability to perform
certain actions. Server owners can grant and revoke privileges to control certain actions. Server owners can grant and revoke privileges to control
which abilities each player has. which abilities each player has.
* [When to use Privileges](#when-to-use-privileges) - [When to use Privileges](#when-to-use-privileges)
* [Declaring Privileges](#declaring-privileges) - [Declaring Privileges](#declaring-privileges)
* [Checking for Privileges](#checking-for-privileges) - [Checking for Privileges](#checking-for-privileges)
* [Getting and Setting Privileges](#getting-and-setting-privileges) - [Getting and Setting Privileges](#getting-and-setting-privileges)
* [Adding Privileges to basic_privs](#adding-privileges-to-basic-privs) - [Adding Privileges to basic_privs](#adding-privileges-to-basicprivs)
## When to use Privileges ## When to use Privileges
@ -120,13 +120,12 @@ the privilege name and the value being a boolean.
## Adding Privileges to basic_privs ## Adding Privileges to basic_privs
Players with the `basic_privs` privilege are able to grant and revoke a limited Players with the `basic_privs` privilege are able to grant and revoke a limited
set of privileges. It's common to give this privilege to moderators, so that set of privileges. It's common to give this privilege to moderators so that
they can grant and revoke `interact` and `shout`, but can't grant themselves or other they can grant and revoke `interact` and `shout`, but can't grant themselves or other
players privileges such as `give` and `server`, which have greater potential for abuse. players privileges with greater potential for abuse such as `give` and `server`.
To add a privilege to `basic_privs` and adjust which privileges your moderators can To add a privilege to `basic_privs`, and adjust which privileges your moderators can
grant and revoke from other players, you must change the `basic_privs` setting. grant and revoke from other players, you must change the `basic_privs` setting.
To do this, you must edit the minetest.conf file.
By default, `basic_privs` has the following value: By default, `basic_privs` has the following value:

View File

@ -6,7 +6,7 @@ idx: 4.7
redirect_from: /en/chapters/sfinv.html redirect_from: /en/chapters/sfinv.html
--- ---
## Introduction ## Introduction <!-- omit in toc -->
Simple Fast Inventory (SFINV) is a mod found in Minetest Game that is used to Simple Fast Inventory (SFINV) is a mod found in Minetest Game that is used to
create the player's inventory [formspec](formspecs.html). SFINV comes with create the player's inventory [formspec](formspecs.html). SFINV comes with
@ -17,10 +17,11 @@ because it is entirely possible that a mod or game decides to show them in
some other format instead. some other format instead.
For example, multiple pages could be shown in one formspec. For example, multiple pages could be shown in one formspec.
* [Registering a Page](#registering-a-page) - [Registering a Page](#registering-a-page)
* [Receiving events](#receiving-events) - [Receiving events](#receiving-events)
* [Conditionally showing to players](#conditionally-showing-to-players) - [Conditionally showing to players](#conditionally-showing-to-players)
* [on_enter and on_leave callbacks](#on_enter-and-on_leave-callbacks) - [on_enter and on_leave callbacks](#onenter-and-onleave-callbacks)
- [Adding to an existing page](#adding-to-an-existing-page)
## Registering a Page ## Registering a Page
@ -194,7 +195,7 @@ minetest.register_on_priv_revoke(on_grant_revoke)
## on_enter and on_leave callbacks ## on_enter and on_leave callbacks
A player *enters* a tab when the tab is selected, and *leaves* a A player *enters* a tab when the tab is selected and *leaves* a
tab when another tab is about to be selected. tab when another tab is about to be selected.
It's possible for multiple pages to be selected if a custom theme is It's possible for multiple pages to be selected if a custom theme is
used. used.

View File

@ -5,7 +5,7 @@ root: ../..
idx: 7.4 idx: 7.4
--- ---
## Introduction ## Introduction <!-- omit in toc -->
Once your mod reaches a respectable size, you'll find it harder and harder to Once your mod reaches a respectable size, you'll find it harder and harder to
keep the code clean and free of bugs. This is an especially big problem when using keep the code clean and free of bugs. This is an especially big problem when using
@ -17,12 +17,11 @@ and common design patterns to achieve that. Please note that this chapter isn't
meant to be prescriptive, but to instead give you an idea of the possibilities. meant to be prescriptive, but to instead give you an idea of the possibilities.
There is no one good way of designing a mod, and good mod design is very subjective. There is no one good way of designing a mod, and good mod design is very subjective.
* [Cohesion, Coupling, and Separation of Concerns](#cohesion-coupling-and-separation-of-concerns) - [Cohesion, Coupling, and Separation of Concerns](#cohesion-coupling-and-separation-of-concerns)
* [Model-View-Controller](#model-view-controller) - [Model-View-Controller](#model-view-controller)
* [API-View](#api-view) - [API-View](#api-view)
* [Observer](#observer) - [Observer](#observer)
* [Conclusion](#conclusion) - [Conclusion](#conclusion)
## Cohesion, Coupling, and Separation of Concerns ## Cohesion, Coupling, and Separation of Concerns
@ -116,7 +115,7 @@ end
``` ```
Your event handlers will have to interact with the Minetest API. You should keep Your event handlers will have to interact with the Minetest API. You should keep
the amount of calculations to a minimum, as you won't be able to test this area the number of calculations to a minimum, as you won't be able to test this area
very easily. very easily.
```lua ```lua
@ -202,7 +201,7 @@ as it doesn't use any Minetest APIs - as shown in the
## Observer ## Observer
Reducing coupling may seem hard to do to begin with, but you'll make a lot of Reducing coupling may seem hard to do, to begin with, but you'll make a lot of
progress by splitting your code up using a design like the one given above. progress by splitting your code up using a design like the one given above.
It's not always possible to remove the need for one area to communicate with It's not always possible to remove the need for one area to communicate with
another, but there are ways to decouple anyway - one example being the Observer another, but there are ways to decouple anyway - one example being the Observer
@ -211,7 +210,7 @@ pattern.
Let's take the example of unlocking an achievement when a player first kills a Let's take the example of unlocking an achievement when a player first kills a
rare animal. The naïve approach would be to have achievement code in the mob rare animal. The naïve approach would be to have achievement code in the mob
kill function, checking the mob name and unlocking the award if it matches. kill function, checking the mob name and unlocking the award if it matches.
This is a bad idea however, as it makes the mobs mod coupled to the achievements This is a bad idea, however, as it makes the mobs mod coupled to the achievements
code. If you kept on doing this - for example, adding XP to the mob death code - code. If you kept on doing this - for example, adding XP to the mob death code -
you could end up with a lot of messy dependencies. you could end up with a lot of messy dependencies.

View File

@ -6,13 +6,13 @@ idx: 7.1
redirect_from: /en/chapters/common_mistakes.html redirect_from: /en/chapters/common_mistakes.html
--- ---
## Introduction ## Introduction <!-- omit in toc -->
This chapter details common mistakes, and how to avoid them. This chapter details common mistakes, and how to avoid them.
* [Never Store ObjectRefs (ie: players or entities)](#never-store-objectrefs-ie-players-or-entities) - [Never Store ObjectRefs (ie: players or entities)](#never-store-objectrefs-ie-players-or-entities)
* [Don't Trust Formspec Submissions](#dont-trust-formspec-submissions) - [Don't Trust Formspec Submissions](#dont-trust-formspec-submissions)
* [Set ItemStacks After Changing Them](#set-itemstacks-after-changing-them) - [Set ItemStacks After Changing Them](#set-itemstacks-after-changing-them)
## Never Store ObjectRefs (ie: players or entities) ## Never Store ObjectRefs (ie: players or entities)

View File

@ -7,19 +7,20 @@ description: Use LuaCheck to find errors
redirect_from: /en/chapters/luacheck.html redirect_from: /en/chapters/luacheck.html
--- ---
## Introduction ## Introduction <!-- omit in toc -->
In this chapter you will learn how to use a tool called LuaCheck to automatically In this chapter, you will learn how to use a tool called LuaCheck to automatically
scan your mod for any mistakes. This tool can be used in combination with your scan your mod for any mistakes. This tool can be used in combination with your
editor to provide alerts to any mistakes. editor to provide alerts to any mistakes.
* [Installing LuaCheck](#installing-luacheck) - [Installing LuaCheck](#installing-luacheck)
* [Windows](#windows) - [Windows](#windows)
* [Linux](#linux) - [Linux](#linux)
* [Running LuaCheck](#running-luacheck) - [Running LuaCheck](#running-luacheck)
* [Configuring LuaCheck](#configuring-luacheck) - [Configuring LuaCheck](#configuring-luacheck)
* [Troubleshooting](#troubleshooting) - [Troubleshooting](#troubleshooting)
* [Checking Commits with Travis](#checking-commits-with-travis) - [Using with editor](#using-with-editor)
- [Checking Commits with Travis](#checking-commits-with-travis)
## Installing LuaCheck ## Installing LuaCheck
@ -30,7 +31,7 @@ Simply download luacheck.exe from
### Linux ### Linux
First you'll need to install LuaRocks: First, you'll need to install LuaRocks:
sudo apt install luarocks sudo apt install luarocks
@ -80,10 +81,10 @@ read_globals = {
} }
``` ```
Next you'll need to test that it works by running LuaCheck. You should get a lot Next, you'll need to test that it works by running LuaCheck. You should get a lot
less errors this time. Starting at the first error you get, either modify the fewer errors this time. Starting at the first error you get, modify the code to
configuration to take it into account, or if there's a bug then fix it - take remove the issue, or modify the configuration if the code is correct. See the list
a look at the list below. below.
### Troubleshooting ### Troubleshooting
@ -93,7 +94,7 @@ a look at the list below.
add it to `globals`. Remove from `read_globals` if present. add it to `globals`. Remove from `read_globals` if present.
Otherwise, add any missing `local`s to the mod. Otherwise, add any missing `local`s to the mod.
* **mutating read-only global variable 'foobar'** - Move `foobar` from `read_globals` to * **mutating read-only global variable 'foobar'** - Move `foobar` from `read_globals` to
`globals`. `globals`, or stop writing to foobar.
## Using with editor ## Using with editor
@ -102,6 +103,7 @@ to show you errors without running a command. Most editors will likely have a pl
available. available.
* **Atom** - `linter-luacheck`. * **Atom** - `linter-luacheck`.
* **VSCode** - Ctrl+P, then paste: `ext install dwenegar.vscode-luacheck`
* **Sublime** - Install using package-control: * **Sublime** - Install using package-control:
[SublimeLinter](https://github.com/SublimeLinter/SublimeLinter), [SublimeLinter](https://github.com/SublimeLinter/SublimeLinter),
[SublimeLinter-luacheck](https://github.com/SublimeLinter/SublimeLinter-luacheck). [SublimeLinter-luacheck](https://github.com/SublimeLinter/SublimeLinter-luacheck).
@ -115,7 +117,7 @@ depending on whether LuaCheck finds any mistakes. This is especially helpful for
when your project receives a pull request - you'll be able to see the LuaCheck output when your project receives a pull request - you'll be able to see the LuaCheck output
without downloading the code. without downloading the code.
First you should visit [travis-ci.org](https://travis-ci.org/) and sign in with First, you should visit [travis-ci.org](https://travis-ci.org/) and sign in with
your Github account. Then find your project's repo in your Travis profile, your Github account. Then find your project's repo in your Travis profile,
and enable Travis by flipping the switch. and enable Travis by flipping the switch.
@ -145,6 +147,6 @@ change the line after `script:` to:
Now commit and push to Github. Go to your project's page on Github, and click Now commit and push to Github. Go to your project's page on Github, and click
'commits'. You should see an orange disc next to the commit you just made. 'commits'. You should see an orange disc next to the commit you just made.
After a while it should change either into a green tick or a red cross depending on the After awhile it should change either into a green tick or a red cross depending on the
outcome of LuaCheck. In either case, you can click the icon to see the build logs outcome of LuaCheck. In either case, you can click the icon to see the build logs
and the output of LuaCheck. and the output of LuaCheck.

View File

@ -6,15 +6,24 @@ idx: 7.6
redirect_from: /en/chapters/releasing.html redirect_from: /en/chapters/releasing.html
--- ---
## Introduction ## Introduction <!-- omit in toc -->
Releasing, or publishing, a mod allows other people to make use of it. Once a mod has been Releasing, or publishing, a mod allows other people to make use of it. Once a mod has been
released it might be used in singleplayer games or on servers, including public servers. released it might be used in singleplayer games or on servers, including public servers.
* [License Choices](#license-choices) - [License Choices](#license-choices)
* [Packaging](#packaging) - [LGPL and CC-BY-SA](#lgpl-and-cc-by-sa)
* [Uploading](#uploading) - [CC0](#cc0)
* [Forum Topic](#forum-topic) - [MIT](#mit)
- [Packaging](#packaging)
- [README.txt](#readmetxt)
- [description.txt](#descriptiontxt)
- [screenshot.png](#screenshotpng)
- [Uploading](#uploading)
- [Version Control Systems](#version-control-systems)
- [Forum Attachments](#forum-attachments)
- [Forum Topic](#forum-topic)
- [Subject](#subject)
## License Choices ## License Choices

View File

@ -5,16 +5,16 @@ root: ../..
idx: 7.3 idx: 7.3
--- ---
## Introduction ## Introduction <!-- omit in toc -->
Security is very important in making sure that your mod doesn't cause the server Security is very important in making sure that your mod doesn't cause the server
owner to lose data or control. owner to lose data or control.
* [Core Concepts](#core-concepts) - [Core Concepts](#core-concepts)
* [Formspecs](#formspecs) - [Formspecs](#formspecs)
* [Never Trust Submissions](#never-trust-submissions) - [Never Trust Submissions](#never-trust-submissions)
* [Time of Check isn't Time of Use](#time_of_check_isnt_time_of_use) - [Time of Check isn't Time of Use](#time-of-check-isnt-time-of-use)
* [(Insecure) Environments](#insecure-environments) - [(Insecure) Environments](#insecure-environments)
## Core Concepts ## Core Concepts

View File

@ -5,28 +5,31 @@ root: ../..
idx: 7.5 idx: 7.5
--- ---
## Introduction ## Introduction <!-- omit in toc -->
Unit tests are an essential tool in proving and reassuring yourself that your code Unit tests are an essential tool in proving and reassuring yourself that your code
is correct. This chapter will show you how to write tests for Minetest mods and is correct. This chapter will show you how to write tests for Minetest mods and
games using Busted. Writing unit tests for functions where you call Minetest games using Busted. Writing unit tests for functions where you call Minetest
functions is quite difficult, but luckily [in the previous chapter](clean_arch.html) functions is quite difficult, but luckily [in the previous chapter](clean_arch.html),
we discussed how to make your code avoid this. we discussed how to structure your code avoid this.
* [Installing Busted](#installing-busted) - [Installing Busted](#installing-busted)
* [Your First Test](#your-first-test) - [Your First Test](#your-first-test)
* [Mocking: Using External Functions](#mocking-using-external-functions) - [init.lua](#initlua)
* [Checking Commits with Travis](#checking-commits-with-travis) - [api.lua](#apilua)
* [Conclusion](#conclusion) - [tests/api_spec.lua](#testsapispeclua)
- [Mocking: Using External Functions](#mocking-using-external-functions)
- [Checking Commits with Travis](#checking-commits-with-travis)
- [Conclusion](#conclusion)
## Installing Busted ## Installing Busted
First you'll need to install LuaRocks. First, you'll need to install LuaRocks.
* Windows: Follow the [installation instructions on LuaRock's wiki](https://github.com/luarocks/luarocks/wiki/Installation-instructions-for-Windows). * Windows: Follow the [installation instructions on LuaRock's wiki](https://github.com/luarocks/luarocks/wiki/Installation-instructions-for-Windows).
* Debian/Ubuntu Linux: `sudo apt install luarocks` * Debian/Ubuntu Linux: `sudo apt install luarocks`
Next you should install Busted globally: Next, you should install Busted globally:
sudo luarocks install busted sudo luarocks install busted
@ -83,7 +86,7 @@ describe("add", function()
end) end)
it("supports negatives", function() it("supports negatives", function()
assert.equals(0, mymod.add(-1, 1)) assert.equals(0, mymod.add(-1, 1))
assert.equals(-2, mymod.add(-1, -1)) assert.equals(-2, mymod.add(-1, -1))
end) end)
end) end)
@ -110,7 +113,7 @@ passed arguments.
If you follow the advice in the [Clean Architectures](clean_arch.html) chapter, If you follow the advice in the [Clean Architectures](clean_arch.html) chapter,
you'll already have a pretty clean file to test. You will still have to mock you'll already have a pretty clean file to test. You will still have to mock
things not in your area however - for example, you'll have to mock the view when things not in your area, however - for example, you'll have to mock the view when
testing the controller/API. If you didn't follow the advice, then things are a testing the controller/API. If you didn't follow the advice, then things are a
little harder as you may have to mock the Minetest API. little harder as you may have to mock the Minetest API.