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
---
## Introduction
## Introduction <!-- omit in toc -->
Understanding the basic structure of a mod's folder is an essential skill when
creating mods.
* [What are Games and Mods?](#what-are-games-and-mods)
* [Where are mods stored?](#where-are-mods-stored)
* [Mod Directory](#mod-directory)
* [Dependencies](#dependencies)
* [Mod Packs](#mod-packs)
* [Example](#example)
- [What are Games and Mods?](#what-are-games-and-mods)
- [Where are mods stored?](#where-are-mods-stored)
- [Mod Directory](#mod-directory)
- [Dependencies](#dependencies)
- [mod.conf](#modconf)
- [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?

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
---
## Introduction
## Introduction <!-- omit in toc -->
In this chapter we will talk about scripting in Lua, the tools required,
and go over some techniques which you will probably find useful.
* [Code Editors](#code-editors)
* [Coding in Lua](#coding-in-lua)
* [Program Flow](#program-flow)
* [Variable Types](#variable-types)
* [Arithmetic Operators](#arithmetic-operators)
* [Selection](#selection)
* [Logical Operators](#logical-operators)
* [Programming](#programming)
* [Local and Global Scope](#local-and-global-scope)
* [Including other Lua Scripts](#including-other-lua-scripts)
- [Code Editors](#code-editors)
- [Coding in Lua](#coding-in-lua)
- [Program Flow](#program-flow)
- [Variable Types](#variable-types)
- [Arithmetic Operators](#arithmetic-operators)
- [Selection](#selection)
- [Logical Operators](#logical-operators)
- [Programming](#programming)
- [Local and Global Scope](#local-and-global-scope)
- [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
@ -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
learning to 'code', it provides an interactive tutorial experience.
* [Scratch](https://scratch.mit.edu) is a good resource when starting from
absolute basics, learning the problem solving techniques required to program.\\
Scratch is **designed to teach children** how to program, and isn't a serious
absolute basics, learning the problem-solving techniques required to program.\\
Scratch is **designed to teach children** how to program and isn't a serious
programming language.
## 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
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

View File

@ -5,26 +5,26 @@ root: ../..
idx: 6.1
---
## Introduction
## Introduction <!-- omit in toc -->
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.
* [What is a Game?](#what-is-a-game)
* [Game Directory](#game-directory)
* [Inter-game Compatibility](#inter-game-compatibility)
* [API Compatibility](#api-compatibility)
* [Groups and Aliases](#groups-and-aliases)
* [Your Turn](#your-turn)
- [What is a Game?](#what-is-a-game)
- [Game Directory](#game-directory)
- [Inter-game Compatibility](#inter-game-compatibility)
- [API Compatibility](#api-compatibility)
- [Groups and Aliases](#groups-and-aliases)
- [Your Turn](#your-turn)
## What is a 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 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.
## Game Directory
@ -90,4 +90,4 @@ good idea to provide aliases from default nodes to any direct replacements.
## 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
---
## Introduction
## Introduction <!-- omit in toc -->
Being able to create and optimise textures is a very useful skill when
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)
available, which cover pixel art in much more detail.
* [Learning to Draw](#learning-to-draw)
* [Techniques](#techniques)
* [Editors](#editors)
- [Techniques](#techniques)
- [Using the Pencil](#using-the-pencil)
- [Tiling](#tiling)
- [Transparency](#transparency)
- [Editors](#editors)
- [MS Paint](#ms-paint)
- [GIMP](#gimp)
## Techniques

View File

@ -11,23 +11,23 @@ redirect_from:
- /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.
* [What are Item Stacks and Inventories?](#what-are-item-stacks-and-inventories)
* [ItemStacks](#itemstacks)
* [Inventory Locations](#inventory-locations)
* [Lists](#lists)
* [Size and Width](#size-and-width)
* [Checking Contents](#checking-contents)
* [Modifying Inventories and ItemStacks](#modifying-inventories-and-itemstacks)
* [Adding to a List](#adding-to-a-list)
* [Taking Items](#taking-items)
* [Manipulating Stacks](#manipulating-stacks)
* [Wear](#wear)
* [Lua Tables](#lua-tables)
- [What are ItemStacks and Inventories?](#what-are-itemstacks-and-inventories)
- [ItemStacks](#itemstacks)
- [Inventory Locations](#inventory-locations)
- [Lists](#lists)
- [Size and Width](#size-and-width)
- [Checking Contents](#checking-contents)
- [Modifying Inventories and ItemStacks](#modifying-inventories-and-itemstacks)
- [Adding to a List](#adding-to-a-list)
- [Taking Items](#taking-items)
- [Manipulating Stacks](#manipulating-stacks)
- [Wear](#wear)
- [Lua Tables](#lua-tables)
## 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.
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
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,
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.
```lua
@ -222,7 +222,7 @@ print("Could not add" .. leftover:get_count() .. " of the items.")
-- ^ will be 51
print("Have " .. stack:get_count() .. " items")
-- ^ will be 80
-- ^ will be 80
-- min(50+100, stack_max) - 19 = 80
-- where stack_max = 99
```
@ -252,7 +252,7 @@ local max_uses = 10
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.
## 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
---
## Introduction
## Introduction <!-- omit in toc -->
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
@ -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
`param2` depends on the `paramtype2` property of the node type definition.
* [Cubic Nodes: Normal and Allfaces](#cubic-nodes-normal-and-allfaces)
* [Glasslike Nodes](#glasslike-nodes)
* [Glasslike_Framed](#glasslike_framed)
* [Airlike Nodes](#airlike-nodes)
* [Lighting and Sunlight Propagation](#lighting-and-sunlight-propagation)
* [Liquid Nodes](#liquid-nodes)
* [Node Boxes](#node-boxes)
* [Wallmounted Node Boxes](#wallmounted-node-boxes)
* [Mesh Nodes](#mesh-nodes)
* [Signlike Nodes](#signlike-nodes)
* [Plantlike Nodes](#plantlike-Nodes)
* [Firelike Nodes](#firelike-nodes)
* [More Drawtypes](#more-drawtypes)
- [Cubic Nodes: Normal and Allfaces](#cubic-nodes-normal-and-allfaces)
- [Glasslike Nodes](#glasslike-nodes)
- [Glasslike_Framed](#glasslikeframed)
- [Airlike Nodes](#airlike-nodes)
- [Lighting and Sunlight Propagation](#lighting-and-sunlight-propagation)
- [Liquid Nodes](#liquid-nodes)
- [Node Boxes](#node-boxes)
- [Wallmounted Node Boxes](#wallmounted-node-boxes)
- [Mesh Nodes](#mesh-nodes)
- [Signlike Nodes](#signlike-nodes)
- [Plantlike Nodes](#plantlike-nodes)
- [Firelike Nodes](#firelike-nodes)
- [More Drawtypes](#more-drawtypes)
## Cubic Nodes: Normal and Allfaces
@ -135,7 +135,7 @@ minetest.register_node("default:glass", {
## Airlike Nodes
These nodes are not rendered, and thus have no textures.
These nodes are not rendered and thus have no textures.
```lua
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
{-0.5, -0.5, -0.5, 0.5, 0, 0.5},
@ -350,12 +350,12 @@ minetest.register_node("mymod:meshy", {
},
-- Path to the mesh
mesh = "mymod_meshy.b3d",
mesh = "mymod_meshy.b3d",
})
```
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
adds more types of furniture may want to share the model provided by a basic
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.
```lua
minetest.register_node("default:ladder_wood", {
minetest.register_node("default:ladder_wood", {
drawtype = "signlike",
tiles = {"default_ladder_wood.png"},
@ -433,7 +433,7 @@ minetest.register_node("mymod:clingere", {
## 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
* 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
---
## Introduction
## Introduction <!-- omit in toc -->
Registering new nodes and craftitems, and creating craft recipes, are
basic requirements for many mods.
* [What are Nodes and Items?](#what-are-nodes-and-items)
* [Registering Items](#registering-items)
* [Item Names and Aliases](#item-names-and-aliases)
* [Textures](#textures)
* [Registering a Basic Node](#registering-a-basic-node)
* [Actions and Callbacks](#actions-and-callbacks)
* [on_use](#on_use)
* [Crafting](#crafting)
* [Fuel](#fuel)
* [Groups](#groups)
* [Tools, Capabilities, and Dig Types](#tools-capabilities-and-dig-types)
- [What are Nodes and Items?](#what-are-nodes-and-items)
- [Registering Items](#registering-items)
- [Item Names and Aliases](#item-names-and-aliases)
- [Textures](#textures)
- [Registering a basic node](#registering-a-basic-node)
- [Actions and Callbacks](#actions-and-callbacks)
- [on_use](#onuse)
- [Crafting](#crafting)
- [Shaped](#shaped)
- [Shapeless](#shapeless)
- [Cooking and Fuel](#cooking-and-fuel)
- [Groups](#groups)
- [Tools, Capabilities, and Dig Types](#tools-capabilities-and-dig-types)
## What are Nodes and Items?
Nodes, craftitems, and tools are all Items.
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.
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.
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,
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.
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!
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
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.
```lua
@ -314,7 +316,7 @@ groups = {cracky = 3, wood = 1}
There are several reasons you use groups.
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
any item in group to be used.
any item in the group to be used.
```lua
minetest.register_craft({

View File

@ -7,19 +7,19 @@ description: Basic operations like set_node and get_node
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)
* [Reading](#reading)
* [Reading Nodes](#reading-nodes)
* [Finding Nodes](#finding-nodes)
* [Writing](#writing)
* [Writing Nodes](#writing-nodes)
* [Removing Nodes](#removing-nodes)
* [Loading Blocks](#loading-blocks)
* [Deleting Blocks](#deleting-blocks)
- [Map Structure](#map-structure)
- [Reading](#reading)
- [Reading Nodes](#reading-nodes)
- [Finding Nodes](#finding-nodes)
- [Writing](#writing)
- [Writing Nodes](#writing-nodes)
- [Removing Nodes](#removing-nodes)
- [Loading Blocks](#loading-blocks)
- [Deleting Blocks](#deleting-blocks)
## 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
`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.
```lua
@ -159,7 +159,7 @@ minetest.remove_node(pos)
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
@ -204,7 +204,7 @@ local function emerge_callback(pos, action,
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.
## 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
---
## Introduction
## Introduction <!-- omit in toc -->
The functions outlined in the [Basic Map Operations](environment.html) chapter
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
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.
* [Concepts](#concepts)
* [Reading into the LVM](#reading-into-the-lvm)
* [Reading Nodes](#reading-nodes)
* [Writing Nodes](#writing-nodes)
* [Example](#example)
* [Your Turn](#your-turn)
- [Concepts](#concepts)
- [Reading into the LVM](#reading-into-the-lvm)
- [Reading Nodes](#reading-nodes)
- [Writing Nodes](#writing-nodes)
- [Example](#example)
- [Your Turn](#your-turn)
## Concepts
@ -78,8 +78,8 @@ print(data[idx])
```
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
is slow. Instead, the engine uses an integer called a content ID.
the engine doesn't store nodes using strings, for performance reasons.
Instead, the engine uses an integer called a content ID.
You can find out the content ID for a particular type of node with
`get_content_id()`. For example:
@ -97,7 +97,7 @@ end
```
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.
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
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
for z = min.z, max.z do
@ -172,7 +172,7 @@ local function grass_to_dirt(pos1, pos2)
local a = VoxelArea:new{
MinEdge = emin,
MaxEdge = emax
}
}
local data = vm:get_data()
-- Modify data

View File

@ -6,17 +6,17 @@ idx: 3.4
description: Using an ObjectRef
---
## Introduction
## Introduction <!-- omit in toc -->
In this chapter, you will learn how to manipulate objects and how to define your
own.
* [What are Objects, Players, and Entities?](#objects_players_and_entities)
* [Position and Velocity](#position_and_velocity)
* [Object Properties](#object_properties)
* [Entities](#entities)
* [Attachments](#attachments)
* [Your Turn](#your_turn)
- [What are Objects, Players, and Entities?](#what-are-objects-players-and-entities)
- [Position and Velocity](#position-and-velocity)
- [Object Properties](#object-properties)
- [Entities](#entities)
- [Attachments](#attachments)
- [Your Turn](#your-turn)
## 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
to a bone.
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.
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
---
## 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)
* [What is Metadata?](#what-is-metadata)
* [Obtaining a Metadata Object](#obtaining-a-metadata-object)
* [Reading and Writing](#reading-and-writing)
* [Special Keys](#special-keys)
* [Private Metadata](#private-metadata)
* [Storing Tables](#storing-tables)
* [Lua Tables](#lua-tables)
* [Mod Storage](#mod-storage)
* [Databases](#databases)
* [Deciding Which to Use](#deciding-which-to-use)
* [Your Turn](#your-turn)
- [Metadata](#metadata)
- [What is Metadata?](#what-is-metadata)
- [Obtaining a Metadata Object](#obtaining-a-metadata-object)
- [Reading and Writing](#reading-and-writing)
- [Special Keys](#special-keys)
- [Storing Tables](#storing-tables)
- [Private Metadata](#private-metadata)
- [Lua Tables](#lua-tables)
- [Mod Storage](#mod-storage)
- [Databases](#databases)
- [Deciding Which to Use](#deciding-which-to-use)
- [Your Turn](#your-turn)
## Metadata

View File

@ -9,7 +9,7 @@ redirect_from:
- /en/map/abms.html
---
## Introduction
## Introduction <!-- omit in toc -->
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.
@ -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
of pending timers.
* [Node Timers](#node-timers)
* [Active Block Modifiers](#active-block-modifiers)
* [Your Turn](#your-turn)
- [Node Timers](#node-timers)
- [Active Block Modifiers](#active-block-modifiers)
- [Your Turn](#your-turn)
## 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.
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.

View File

@ -24,16 +24,16 @@ cb_cmdsprivs:
---
## Introduction
## Introduction <!-- omit in toc -->
Mods can interact with player chat, including
sending messages, intercepting messages, and registering chat commands.
* [Sending Messages to All Players](#sending-messages-to-all-players)
* [Sending Messages to Specific Players](#sending-messages-to-specific-players)
* [Chat Commands](#chat-commands)
* [Complex Subcommands](#complex-subcommands)
* [Intercepting Messages](#intercepting-messages)
- [Sending Messages to All Players](#sending-messages-to-all-players)
- [Sending Messages to Specific Players](#sending-messages-to-specific-players)
- [Chat Commands](#chat-commands)
- [Complex Subcommands](#complex-subcommands)
- [Intercepting Messages](#intercepting-messages)
## 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
only visible to the named player, in this case player1.
only visible to the named player, in this case, player1.
## Chat Commands

View File

@ -7,20 +7,20 @@ description: Use ChatCmdBuilder to make a complex chat command
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,
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
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?
* Routes.
* Subcommand functions.
* Installing ChatCmdBuilder.
* Admin complex command.
- [Why ChatCmdBuilder?](#why-chatcmdbuilder)
- [Routes](#routes)
- [Subcommand functions](#subcommand-functions)
- [Installing ChatCmdBuilder](#installing-chatcmdbuilder)
- [Admin complex command](#admin-complex-command)
## Why ChatCmdBuilder?
@ -30,13 +30,13 @@ Traditionally mods implemented these complex commands using Lua patterns.
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.
```lua
ChatCmdBuilder.new("sethp", function(cmd)
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
player:set_hp(hp)
return true, "Killed " .. target
@ -55,10 +55,10 @@ end, {
`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
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
the chat command, the first sub command that matches their input will be run,
A subcommand is a particular response to an input param. When a player runs
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
syntax. For example, in the above code snippet if a player
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,
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.
* `hp` - type of `int`

View File

@ -13,7 +13,7 @@ submit_vuln:
and make sure that they should be allowed to perform the action.
---
## Introduction
## Introduction <!-- omit in toc -->
<figure class="right_image">
<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,
buttons and fields to allow you to enter information.
* [Formspec Syntax](#formspec-syntax)
* [Displaying Forms](#displaying-forms)
* [Callbacks](#callbacks)
* [Contexts](#contexts)
* [Node Meta Formspecs](#node-meta-formspecs)
- [Formspec Syntax](#formspec-syntax)
- [Size[w, h]](#sizew-h)
- [Field[x, y; w, h; name; label; default]](#fieldx-y-w-h-name-label-default)
- [Other Elements](#other-elements)
- [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
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.
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.
```lua
@ -265,7 +270,7 @@ end)
## Node Meta Formspecs
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 -
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
---
## Introduction
## Introduction <!-- omit in toc -->
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).
* [Positioning](#positioning)
* [Position and Offset](#position-and-offset)
* [Alignment](#alignment)
* [Scoreboard](#scoreboard)
* [Text Elements](#text-elements)
* [Parameters](#parameters)
* [Our Example](#our-example)
* [Image Elements](#image-elements)
* [Parameters](#parameters-1)
* [Scale](#scale)
* [Changing an Element](#changing-an-element)
* [Storing IDs](#storing-ids)
* [Other Elements](#other-elements)
- [Positioning](#positioning)
- [Position and Offset](#position-and-offset)
- [Alignment](#alignment)
- [Scoreboard](#scoreboard)
- [Text Elements](#text-elements)
- [Parameters](#parameters)
- [Our Example](#our-example)
- [Image Elements](#image-elements)
- [Parameters](#parameters-1)
- [Scale](#scale)
- [Changing an Element](#changing-an-element)
- [Storing IDs](#storing-ids)
- [Other Elements](#other-elements)
## 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
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.
### Scale

View File

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

View File

@ -7,17 +7,17 @@ description: Registering privs.
redirect_from: /en/chapters/privileges.html
---
## Introduction
## Introduction <!-- omit in toc -->
Privileges, often called privs for short, give players the ability to perform
certain actions. Server owners can grant and revoke privileges to control
which abilities each player has.
* [When to use Privileges](#when-to-use-privileges)
* [Declaring Privileges](#declaring-privileges)
* [Checking for Privileges](#checking-for-privileges)
* [Getting and Setting Privileges](#getting-and-setting-privileges)
* [Adding Privileges to basic_privs](#adding-privileges-to-basic-privs)
- [When to use Privileges](#when-to-use-privileges)
- [Declaring Privileges](#declaring-privileges)
- [Checking for Privileges](#checking-for-privileges)
- [Getting and Setting Privileges](#getting-and-setting-privileges)
- [Adding Privileges to basic_privs](#adding-privileges-to-basicprivs)
## When to use Privileges
@ -120,13 +120,12 @@ the privilege name and the value being a boolean.
## Adding Privileges to basic_privs
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
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.
To do this, you must edit the minetest.conf file.
By default, `basic_privs` has the following value:

View File

@ -6,7 +6,7 @@ idx: 4.7
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
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.
For example, multiple pages could be shown in one formspec.
* [Registering a Page](#registering-a-page)
* [Receiving events](#receiving-events)
* [Conditionally showing to players](#conditionally-showing-to-players)
* [on_enter and on_leave callbacks](#on_enter-and-on_leave-callbacks)
- [Registering a Page](#registering-a-page)
- [Receiving events](#receiving-events)
- [Conditionally showing to players](#conditionally-showing-to-players)
- [on_enter and on_leave callbacks](#onenter-and-onleave-callbacks)
- [Adding to an existing page](#adding-to-an-existing-page)
## Registering a Page
@ -194,7 +195,7 @@ minetest.register_on_priv_revoke(on_grant_revoke)
## 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.
It's possible for multiple pages to be selected if a custom theme is
used.

View File

@ -5,7 +5,7 @@ root: ../..
idx: 7.4
---
## Introduction
## Introduction <!-- omit in toc -->
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
@ -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.
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)
* [Model-View-Controller](#model-view-controller)
* [API-View](#api-view)
* [Observer](#observer)
* [Conclusion](#conclusion)
- [Cohesion, Coupling, and Separation of Concerns](#cohesion-coupling-and-separation-of-concerns)
- [Model-View-Controller](#model-view-controller)
- [API-View](#api-view)
- [Observer](#observer)
- [Conclusion](#conclusion)
## 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
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.
```lua
@ -202,7 +201,7 @@ as it doesn't use any Minetest APIs - as shown in the
## 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.
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
@ -211,7 +210,7 @@ pattern.
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
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 -
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
---
## Introduction
## Introduction <!-- omit in toc -->
This chapter details common mistakes, and how to avoid them.
* [Never Store ObjectRefs (ie: players or entities)](#never-store-objectrefs-ie-players-or-entities)
* [Don't Trust Formspec Submissions](#dont-trust-formspec-submissions)
* [Set ItemStacks After Changing Them](#set-itemstacks-after-changing-them)
- [Never Store ObjectRefs (ie: players or entities)](#never-store-objectrefs-ie-players-or-entities)
- [Don't Trust Formspec Submissions](#dont-trust-formspec-submissions)
- [Set ItemStacks After Changing Them](#set-itemstacks-after-changing-them)
## 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
---
## 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
editor to provide alerts to any mistakes.
* [Installing LuaCheck](#installing-luacheck)
* [Windows](#windows)
* [Linux](#linux)
* [Running LuaCheck](#running-luacheck)
* [Configuring LuaCheck](#configuring-luacheck)
* [Troubleshooting](#troubleshooting)
* [Checking Commits with Travis](#checking-commits-with-travis)
- [Installing LuaCheck](#installing-luacheck)
- [Windows](#windows)
- [Linux](#linux)
- [Running LuaCheck](#running-luacheck)
- [Configuring LuaCheck](#configuring-luacheck)
- [Troubleshooting](#troubleshooting)
- [Using with editor](#using-with-editor)
- [Checking Commits with Travis](#checking-commits-with-travis)
## Installing LuaCheck
@ -30,7 +31,7 @@ Simply download luacheck.exe from
### Linux
First you'll need to install LuaRocks:
First, you'll need to 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
less errors this time. Starting at the first error you get, either modify the
configuration to take it into account, or if there's a bug then fix it - take
a look at the list below.
Next, you'll need to test that it works by running LuaCheck. You should get a lot
fewer errors this time. Starting at the first error you get, modify the code to
remove the issue, or modify the configuration if the code is correct. See the list
below.
### Troubleshooting
@ -93,7 +94,7 @@ a look at the list below.
add it to `globals`. Remove from `read_globals` if present.
Otherwise, add any missing `local`s to the mod.
* **mutating read-only global variable 'foobar'** - Move `foobar` from `read_globals` to
`globals`.
`globals`, or stop writing to foobar.
## Using with editor
@ -102,6 +103,7 @@ to show you errors without running a command. Most editors will likely have a pl
available.
* **Atom** - `linter-luacheck`.
* **VSCode** - Ctrl+P, then paste: `ext install dwenegar.vscode-luacheck`
* **Sublime** - Install using package-control:
[SublimeLinter](https://github.com/SublimeLinter/SublimeLinter),
[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
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,
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
'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
and the output of LuaCheck.

View File

@ -6,15 +6,24 @@ idx: 7.6
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
released it might be used in singleplayer games or on servers, including public servers.
* [License Choices](#license-choices)
* [Packaging](#packaging)
* [Uploading](#uploading)
* [Forum Topic](#forum-topic)
- [License Choices](#license-choices)
- [LGPL and CC-BY-SA](#lgpl-and-cc-by-sa)
- [CC0](#cc0)
- [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

View File

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

View File

@ -5,28 +5,31 @@ root: ../..
idx: 7.5
---
## Introduction
## Introduction <!-- omit in toc -->
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
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)
we discussed how to make your code avoid this.
functions is quite difficult, but luckily [in the previous chapter](clean_arch.html),
we discussed how to structure your code avoid this.
* [Installing Busted](#installing-busted)
* [Your First Test](#your-first-test)
* [Mocking: Using External Functions](#mocking-using-external-functions)
* [Checking Commits with Travis](#checking-commits-with-travis)
* [Conclusion](#conclusion)
- [Installing Busted](#installing-busted)
- [Your First Test](#your-first-test)
- [init.lua](#initlua)
- [api.lua](#apilua)
- [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
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).
* Debian/Ubuntu Linux: `sudo apt install luarocks`
Next you should install Busted globally:
Next, you should install Busted globally:
sudo luarocks install busted
@ -83,7 +86,7 @@ describe("add", function()
end)
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))
end)
end)
@ -110,7 +113,7 @@ passed arguments.
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
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
little harder as you may have to mock the Minetest API.