Fix grammar issues spotted by grammarly
This commit is contained in:
parent
2934517a5d
commit
79a522f852
@ -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?
|
||||
|
@ -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
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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({
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
||||
|
@ -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`
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user