minetest_modding_book/_en/basics/lua.md

311 lines
9.5 KiB
Markdown
Raw Normal View History

2014-12-30 21:50:46 +03:00
---
2018-09-14 17:00:44 +03:00
title: Lua Scripting
2014-12-30 21:50:46 +03:00
layout: default
2018-07-15 21:36:35 +03:00
root: ../..
2018-07-15 17:28:10 +03:00
idx: 1.2
description: A basic introduction to Lua, including a guide on global/local scope.
2018-07-15 21:13:16 +03:00
redirect_from: /en/chapters/lua.html
2014-12-30 21:50:46 +03:00
---
## Introduction <!-- omit in toc -->
2014-12-30 21:50:46 +03:00
2021-01-25 11:35:55 +03:00
In this chapter we'll talk about scripting in Lua, the tools required
to assist with this, and some techniques which you may find useful.
2014-12-30 21:50:46 +03:00
2022-03-22 15:25:47 +03:00
- [Programming](#programming)
- [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)
- [Local and Global Scope](#local-and-global-scope)
- [Including other Lua Scripts](#including-other-lua-scripts)
2018-09-14 17:00:44 +03:00
2022-03-22 15:25:47 +03:00
## Programming
Programming is the action of taking a problem, such as sorting a list
of items, and turning it into steps that a computer can understand.
Teaching you the logical process of programming is beyond the scope of this book;
however, the following websites are quite useful in developing this:
* [Codecademy](http://www.codecademy.com/) is one of the best resources for
learning to write code. It provides an interactive tutorial experience.
* [Scratch](https://scratch.mit.edu) is a good resource for starting from
absolute basics, and learning the problem-solving techniques required to program.\\
Scratch is *designed to teach children* how to program and isn't a serious
programming language.
* [Programming with Mosh](https://www.youtube.com/user/programmingwithmosh) is
a good YouTube series to learn programming.
2018-09-14 17:00:44 +03:00
## Code Editors
A code editor with code highlighting is sufficient for writing scripts in Lua.
2021-01-25 11:35:55 +03:00
Code highlighting uses different colours for words and characters
depending on what they represent. This allows you to easily notice
mistakes and inconsistencies.
For example:
2014-12-30 21:50:46 +03:00
```lua
2014-12-30 21:50:46 +03:00
function ctf.post(team,msg)
if not ctf.team(team) then
return false
end
if not ctf.team(team).log then
ctf.team(team).log = {}
end
2014-12-30 21:50:46 +03:00
table.insert(ctf.team(team).log,1,msg)
ctf.save()
2014-12-30 21:50:46 +03:00
return true
2014-12-30 21:50:46 +03:00
end
```
2014-12-30 21:50:46 +03:00
2021-01-25 11:35:55 +03:00
Keywords in this example are highlighted, including `if`, `then`, `end`, and `return`.
Functions which come with Lua by default, such as `table.insert`, are also highlighted.
Commonly used editors which are well-suited for Lua include:
2014-12-30 21:50:46 +03:00
2021-01-25 11:35:55 +03:00
* [VSCode](https://code.visualstudio.com/) -
open source (as Code-OSS or VSCodium), popular, and has
[plugins for Minetest modding](https://marketplace.visualstudio.com/items?itemName=GreenXenith.minetest-tools).
* [Notepad++](http://notepad-plus-plus.org/) - Windows-only
* [Atom](http://atom.io/)
2014-12-31 20:23:15 +03:00
2021-01-25 11:35:55 +03:00
Other suitable editors are also available.
2014-12-31 20:23:15 +03:00
2015-02-22 14:43:58 +03:00
## Coding in Lua
2018-09-14 17:00:44 +03:00
### Program Flow
2021-01-25 11:35:55 +03:00
Programs are a series of commands that run one after another. We call these
commands "statements." Program flow is how these statements are executed, and
different types of flow allow you to skip or jump over sets of commands.
2018-09-14 17:00:44 +03:00
There are three main types of flow:
2015-02-22 14:43:58 +03:00
2021-01-25 11:35:55 +03:00
* Sequence: runs one statement after another, with no skipping.
* Selection: skips over sequences depending on conditions.
* Iteration: repeats the same statements until a condition is met.
2015-02-22 14:43:58 +03:00
So, what do statements in Lua look like?
```lua
2015-02-22 14:43:58 +03:00
local a = 2 -- Set 'a' to 2
local b = 2 -- Set 'b' to 2
local result = a + b -- Set 'result' to a + b, which is 4
a = a + 10
print("Sum is "..result)
```
2015-02-22 14:43:58 +03:00
2021-01-25 11:35:55 +03:00
In this example, `a`, `b`, and `result` are *variables*. Local variables are
declared by using the `local` keyword, and then given an initial value. Local
will be discussed later, because it's part of a very important concept called
2018-09-14 17:00:44 +03:00
*scope*.
2015-02-22 14:43:58 +03:00
2021-01-25 11:35:55 +03:00
The `=` sign means *assignment*, so `result = a + b` means set the value of
`result` to the value of `a + b`. Variable names can be longer than one
character, as seen with the `result` variable. It's also worth noting that, like
most languages, Lua is *case-sensitive*; `A` is a different variable to `a`.
2015-02-22 14:43:58 +03:00
### Variable Types
2018-09-14 17:00:44 +03:00
A variable will be only one of the following types and can change type after an
assignment.
It's good practice to make sure a variable is only ever nil or a single non-nil type.
2018-09-27 17:27:07 +03:00
| Type | Description | Example |
|----------|---------------------------------|----------------|
2018-09-14 17:00:44 +03:00
| Nil | Not initialised. The variable is empty, it has no value | `local A`, `D = nil` |
2018-09-27 17:27:07 +03:00
| Number | A whole or decimal number. | `local A = 4` |
2021-01-25 11:35:55 +03:00
| String | A piece of text. | `local D = "one two three"` |
| Boolean | True or False. | `local is_true = false`, `local E = (1 == 1)` |
| Table | Lists. | Explained below. |
| Function | Can run. May require inputs and may return a value. | `local result = func(1, 2, 3)` |
2015-02-22 14:43:58 +03:00
### Arithmetic Operators
2021-01-25 11:35:55 +03:00
Operators in Lua include:
2018-09-14 17:00:44 +03:00
2015-02-22 14:43:58 +03:00
| Symbol | Purpose | Example |
|--------|----------------|---------------------------|
| A + B | Addition | 2 + 2 = 4 |
| A - B | Subtraction | 2 - 10 = -8 |
| A * B | Multiplication | 2 * 2 = 4 |
| A / B | Division | 100 / 50 = 2 |
| A ^ B | Powers | 2 ^ 2 = 2<sup>2</sup> = 4 |
| A .. B | Join strings | "foo" .. "bar" = "foobar" |
2021-01-25 11:35:55 +03:00
Please note that this is not an exhaustive list; it doesn't contain every
possible operator.
2015-02-22 14:43:58 +03:00
### Selection
2021-01-25 11:35:55 +03:00
The most basic method of selection is the if statement. For example:
2015-02-22 14:43:58 +03:00
```lua
2015-02-22 14:43:58 +03:00
local random_number = math.random(1, 100) -- Between 1 and 100.
if random_number > 50 then
print("Woohoo!")
2015-02-22 14:43:58 +03:00
else
print("No!")
2015-02-22 14:43:58 +03:00
end
```
2015-02-22 14:43:58 +03:00
2021-01-25 11:35:55 +03:00
This generates a random number between 1 and 100. It then prints "Woohoo!" if
that number is bigger than 50, and otherwise prints "No!".
2015-02-22 14:43:58 +03:00
### Logical Operators
2021-01-25 11:35:55 +03:00
Logical operators in Lua include:
2015-02-22 14:43:58 +03:00
| Symbol | Purpose | Example |
|---------|--------------------------------------|-------------------------------------------------------------|
| A == B | Equals | 1 == 1 (true), 1 == 2 (false) |
| A ~= B | Doesn't equal | 1 ~= 1 (false), 1 ~= 2 (true) |
| A > B | Greater than | 5 > 2 (true), 1 > 2 (false), 1 > 1 (false) |
| A < B | Less than | 1 < 3 (true), 3 < 1 (false), 1 < 1 (false) |
| A >= B | Greater than or equals | 5 >= 5 (true), 5 >= 3 (true), 5 >= 6 (false) |
| A <= B | Less than or equals | 3 <= 6 (true), 3 <= 3 (true) |
| A and B | And (both must be correct) | (2 > 1) and (1 == 1) (true), (2 > 3) and (1 == 1) (false) |
| A or B | either or. One or both must be true. | (2 > 1) or (1 == 2) (true), (2 > 4) or (1 == 3) (false) |
| not A | not true | not (1 == 2) (true), not (1 == 1) (false) |
2021-01-25 11:35:55 +03:00
Please note that this doesn't contain every possible operator.
It is also possible to combine operators. For example:
2015-02-22 14:43:58 +03:00
```lua
2015-02-22 14:43:58 +03:00
if not A and B then
print("Yay!")
2015-02-22 14:43:58 +03:00
end
```
2015-02-22 14:43:58 +03:00
2021-01-25 11:35:55 +03:00
This prints "Yay!" if A is false and B is true.
2015-02-22 14:43:58 +03:00
2021-01-25 11:35:55 +03:00
Logical and arithmetic operators work the same way; they both accept inputs and
return a value which can be stored. For example:
2015-02-22 14:43:58 +03:00
```lua
2015-02-22 14:43:58 +03:00
local A = 5
local is_equal = (A == 5)
if is_equal then
print("Is equal!")
2015-02-22 14:43:58 +03:00
end
```
2015-02-22 14:43:58 +03:00
2018-09-14 17:00:44 +03:00
## Local and Global Scope
2014-12-30 21:50:46 +03:00
2021-01-25 11:35:55 +03:00
Whether a variable is local or global determines where it can be written to or
read from. A local variable is only accessible from where it is defined. Here
are some examples:
2014-12-30 22:24:41 +03:00
```lua
2014-12-30 22:24:41 +03:00
-- Accessible from within this script file
local one = 1
function myfunc()
-- Accessible from within this function
local two = one + one
2014-12-30 22:24:41 +03:00
if two == one then
-- Accessible from within this if statement
local three = one + two
end
2014-12-30 22:24:41 +03:00
end
```
2014-12-30 22:24:41 +03:00
2021-01-25 11:35:55 +03:00
In contrast, global variables can be accessed from anywhere in the script file, and
from any other mod.
2014-12-30 21:50:46 +03:00
```lua
2014-12-30 21:50:46 +03:00
function one()
foo = "bar"
2014-12-30 21:50:46 +03:00
end
function two()
print(dump(foo)) -- Output: "bar"
2014-12-30 21:50:46 +03:00
end
one()
two()
```
2014-12-30 21:50:46 +03:00
2021-01-25 11:35:55 +03:00
Local variables should be used whenever possible. Mods should only create one
global at most, with the same name as the mod. Creating other globals is sloppy
coding, and Minetest will warn about this:
2014-12-30 22:24:41 +03:00
2018-09-24 19:16:00 +03:00
Assignment to undeclared global 'foo' inside function at init.lua:2
2014-12-30 22:24:41 +03:00
2014-12-30 21:50:46 +03:00
To correct this, use "local":
```lua
2014-12-30 21:50:46 +03:00
function one()
local foo = "bar"
2014-12-30 21:50:46 +03:00
end
function two()
print(dump(foo)) -- Output: nil
2014-12-30 21:50:46 +03:00
end
one()
two()
```
2014-12-30 21:50:46 +03:00
2021-01-25 11:35:55 +03:00
Remember that nil means **not initialised**. The variable hasn't been assigned a
value yet, doesn't exist, or has been uninitialised (meaning set to nil).
2021-01-25 11:35:55 +03:00
Functions are variables of a special type, but should also be made local,
because other mods could have functions with the same names.
2014-12-30 21:50:46 +03:00
```lua
2014-12-30 21:50:46 +03:00
local function foo(bar)
return bar * 2
2014-12-30 21:50:46 +03:00
end
```
2014-12-30 21:50:46 +03:00
2021-01-27 19:37:21 +03:00
To allow mods to call your functions, you should create a table with the same
2021-01-25 11:35:55 +03:00
name as the mod and add your function to it. This table is often called an API
table or namespace.
2014-12-30 21:50:46 +03:00
```lua
2014-12-30 21:50:46 +03:00
mymod = {}
function mymod.foo(bar)
return "foo" .. bar
2014-12-30 21:50:46 +03:00
end
-- In another mod, or script:
mymod.foo("foobar")
```
2014-12-30 21:50:46 +03:00
2015-02-22 13:28:37 +03:00
## Including other Lua Scripts
2014-12-30 21:50:46 +03:00
2018-09-14 17:00:44 +03:00
The recommended way to include other Lua scripts in a mod is to use *dofile*.
2014-12-30 21:50:46 +03:00
```lua
2014-12-30 21:50:46 +03:00
dofile(minetest.get_modpath("modname") .. "/script.lua")
```
2014-12-30 21:50:46 +03:00
2018-09-14 17:00:44 +03:00
A script can return a value, which is useful for sharing private locals:
```lua
2018-09-14 17:00:44 +03:00
-- script.lua
return "Hello world!"
-- init.lua
local ret = dofile(minetest.get_modpath("modname") .. "/script.lua")
print(ret) -- Hello world!
```
2014-12-30 21:50:46 +03:00
2021-01-25 11:35:55 +03:00
[Later chapters](../quality/clean_arch.html) will discuss how best to split up
code for a mod.