336 lines
11 KiB
Markdown
Raw Normal View History

2014-12-30 18:50:46 +00:00
---
2018-09-14 15:00:44 +01:00
title: Lua Scripting
2014-12-30 18:50:46 +00:00
layout: default
2018-07-15 19:36:35 +01:00
root: ../..
2018-07-15 15:28:10 +01:00
idx: 1.2
description: A basic introduction to Lua, including a guide on global/local scope.
2018-07-15 19:13:16 +01:00
redirect_from: /en/chapters/lua.html
2014-12-30 18:50:46 +00:00
---
2015-02-22 10:28:37 +00:00
## Introduction
2014-12-30 18:50:46 +00:00
2018-10-16 21:44:20 +01:00
In this chapter will talk about scripting in Lua, the tools required
to assist with this, and some techniques which you may find useful.
2014-12-30 18:50:46 +00:00
2018-09-14 15:00:44 +01:00
* [Code Editors](#code-editors)
* [Integrated Programming Environments](#integrated-programming-environments)
* [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
A code editor with code highlighting is sufficient for writing scripts in Lua.
2018-10-16 21:44:20 +01:00
Code highlighting uses different colours for words and characters
depending on what they represent. This allows you to more easily notice
mistakes and inconsistencies.
For example:
2014-12-30 18:50:46 +00:00
```lua
2014-12-30 18:50:46 +00: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 18:50:46 +00:00
table.insert(ctf.team(team).log,1,msg)
ctf.save()
2014-12-30 18:50:46 +00:00
return true
2014-12-30 18:50:46 +00:00
end
```
2014-12-30 18:50:46 +00:00
2018-10-16 21:44:20 +01:00
Keywords in this code are highlighted including `if`, `then`, `end`, and `return`.
Functions which comes with Lua by default, such as `table.insert` are also highlighted.
2014-12-30 18:50:46 +00:00
2018-10-16 21:44:20 +01:00
Commonly used editors which are well-suited for Lua include:
2014-12-31 17:23:15 +00:00
2018-09-14 15:00:44 +01:00
* Windows: [Notepad++](http://notepad-plus-plus.org/), [Atom](http://atom.io/), [VS Code](https://code.visualstudio.com/)
* Linux: Kate, Gedit, [Atom](http://atom.io/), [VS Code](https://code.visualstudio.com/)
* OSX: [Atom](http://atom.io/), [VS Code](https://code.visualstudio.com/)
2014-12-31 17:23:15 +00:00
2018-10-16 21:44:20 +01:00
Other suitable editors are also available.
2014-12-30 18:50:46 +00:00
### Integrated Programming Environments
2018-10-16 21:44:20 +01:00
Integrated development environments (IDEs) allow you to more easily debug code,
but are often more difficult to set up than a simple text editor.
2014-12-30 18:50:46 +00:00
2018-10-16 21:44:20 +01:00
One such IDE is Eclipse, which can be used with the Koneki Lua plugin.
To use this:
2014-12-30 18:50:46 +00:00
2018-10-16 21:44:20 +01:00
* Install Eclipse and Koneki.
2014-12-30 18:50:46 +00:00
* Create a new Lua project from existing source (specify Minetest's base directory).
2018-10-16 21:44:20 +01:00
* Follow instructions from Koneki wiki on how to "Attach to remote Application" debugging.
* It is suggested to add those lines from wiki at the beginning of builtin.lua.
* Start the debugger. (Set "Break on first line" in debugger configuration to see if it is working).
2014-12-30 18:50:46 +00:00
* Start Minetest.
* Enter the game to startup Lua.
2015-02-22 11:43:58 +00:00
## Coding in Lua
2018-09-14 15:00:44 +01:00
### Program Flow
2015-02-22 11:43:58 +00:00
Programs are a series of commands that run one after another.
We call these commands "statements."
2018-10-16 21:44:20 +01:00
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 15:00:44 +01:00
There are three main types of flow:
2015-02-22 11:43:58 +00:00
2018-10-16 21:44:20 +01:00
* Sequence: This runs one statement after another, with no skipping.
* Selection: This skips over sequences depending on conditions.
* Iteration: Repeating, looping. This runs the same
2015-02-22 11:43:58 +00:00
statements until a condition is met.
So, what do statements in Lua look like?
```lua
2015-02-22 11:43:58 +00: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 11:43:58 +00:00
2018-10-16 21:44:20 +01: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 15:00:44 +01:00
*scope*.
2015-02-22 11:43:58 +00:00
2018-10-16 21:44:20 +01: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 Lua is *case-sensitive*; `A` is a different
variable to `a`.
2015-02-22 11:43:58 +00:00
### Variable Types
2018-09-14 15:00:44 +01: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 15:27:07 +01:00
| Type | Description | Example |
|----------|---------------------------------|----------------|
2018-09-14 15:00:44 +01:00
| Nil | Not initialised. The variable is empty, it has no value | `local A`, `D = nil` |
2018-09-27 15:27:07 +01:00
| Number | A whole or decimal number. | `local A = 4` |
2018-10-16 21:44:20 +01: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. |
2018-09-14 15:00:44 +01:00
| Function | Can run. May require inputs and may return a value | `local result = func(1, 2, 3)` |
2015-02-22 11:43:58 +00:00
### Arithmetic Operators
2018-10-16 21:44:20 +01:00
Arithmetic operators in Lua include:
2018-09-14 15:00:44 +01:00
2015-02-22 11:43:58 +00: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" |
2018-10-16 21:44:20 +01:00
Please note that this is not an exhaustive list; it doesn't contain every possible operator.
2015-02-22 11:43:58 +00:00
### Selection
2018-10-16 21:44:20 +01:00
The most basic method of selection is the if statement. For example:
2015-02-22 11:43:58 +00:00
```lua
2015-02-22 11:43:58 +00:00
local random_number = math.random(1, 100) -- Between 1 and 100.
if random_number > 50 then
print("Woohoo!")
2015-02-22 11:43:58 +00:00
else
print("No!")
2015-02-22 11:43:58 +00:00
end
```
2015-02-22 11:43:58 +00:00
2018-10-16 21:44:20 +01: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 11:43:58 +00:00
### Logical Operators
2018-10-16 21:44:20 +01:00
Logical operators in Lua include:
2015-02-22 11:43:58 +00: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) |
2018-10-16 21:44:20 +01:00
Please note that this doesn't contain every possible operator.
It is also possible to combine operators. For example:
2015-02-22 11:43:58 +00:00
```lua
2015-02-22 11:43:58 +00:00
if not A and B then
print("Yay!")
2015-02-22 11:43:58 +00:00
end
```
2015-02-22 11:43:58 +00:00
2018-10-16 21:44:20 +01:00
This prints "Yay!" if A is false and B is true.
2015-02-22 11:43:58 +00:00
2018-10-16 21:44:20 +01: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 11:43:58 +00:00
```lua
2015-02-22 11:43:58 +00:00
local A = 5
local is_equal = (A == 5)
if is_equal then
print("Is equal!")
2015-02-22 11:43:58 +00:00
end
```
2015-02-22 11:43:58 +00:00
## Programming
2018-10-06 16:56:42 +01:00
Programming is the action of taking a problem, such as sorting a list
2018-10-16 21:44:20 +01:00
of items, and turning it into steps that a computer can understand.
2015-02-22 11:43:58 +00:00
2015-11-08 10:57:40 -05:00
Teaching you the logical process of programming is beyond the scope of this book;
however, the following websites are quite useful in developing this:
2015-02-22 11:43:58 +00:00
2018-09-14 15:00:44 +01:00
* [Codecademy](http://www.codecademy.com/) is one of the best resources for
2018-10-16 21:44:20 +01:00
learning to write code. It provides an interactive tutorial experience.
* [Scratch](https://scratch.mit.edu) is a good resource, when starting from
absolute basics, to learn the problem solving techniques required to program.\\
2018-10-06 16:56:42 +01:00
Scratch is **designed to teach children** how to program, and isn't a serious
2018-09-14 15:00:44 +01:00
programming language.
2015-02-22 11:43:58 +00:00
2018-09-14 15:00:44 +01:00
## Local and Global Scope
2014-12-30 18:50:46 +00:00
2018-10-16 21:44:20 +01:00
Whether a variable is local or global determines where it can be written to or read from.
2014-12-30 19:24:41 +00:00
A local variable is only accessible from where it is defined. Here are some examples:
```lua
2014-12-30 19:24:41 +00:00
-- Accessible from within this script file
local one = 1
function myfunc()
-- Accessible from within this function
local two = one + one
2014-12-30 19:24:41 +00:00
if two == one then
-- Accessible from within this if statement
local three = one + two
end
2014-12-30 19:24:41 +00:00
end
```
2014-12-30 19:24:41 +00:00
2018-10-16 21:44:20 +01:00
In contrast, global variables can be accessed from anywhere in the script file, and from any other mod.
2014-12-30 19:24:41 +00:00
```lua
2014-12-30 19:24:41 +00:00
my_global_variable = "blah"
function one()
my_global_variable = "three"
2014-12-30 19:24:41 +00:00
end
print(my_global_variable) -- Output: "blah"
one()
print(my_global_variable) -- Output: "three"
```
2014-12-30 19:24:41 +00:00
2018-10-16 21:44:20 +01:00
Local variables should be used whenever possible.
2014-12-30 19:24:41 +00:00
2018-10-16 21:44:20 +01:00
Lua is global by default (unlike most other programming languages), so
local variables must be identified as such.
2014-12-30 19:24:41 +00:00
2018-10-16 21:44:20 +01:00
For example:
2014-12-30 18:50:46 +00:00
```lua
2014-12-30 18:50:46 +00:00
function one()
foo = "bar"
2014-12-30 18:50:46 +00:00
end
function two()
print(dump(foo)) -- Output: "bar"
2014-12-30 18:50:46 +00:00
end
one()
two()
```
2014-12-30 18:50:46 +00:00
2018-10-16 21:44:20 +01:00
The dump() function can turn any variable into a string so the programmer can
see what it is. In this example, the foo variable will be printed as "bar", including the quotes
which show it is a string. This reveals that the foo variable was global, because it could be
accessed from another function than the one in which it was declared.
2018-10-16 21:44:20 +01:00
This is sloppy coding, and Minetest will in warn about this:
2014-12-30 19:24:41 +00:00
2018-09-24 17:16:00 +01:00
Assignment to undeclared global 'foo' inside function at init.lua:2
2014-12-30 19:24:41 +00:00
2014-12-30 18:50:46 +00:00
To correct this, use "local":
```lua
2014-12-30 18:50:46 +00:00
function one()
local foo = "bar"
2014-12-30 18:50:46 +00:00
end
function two()
print(dump(foo)) -- Output: nil
2014-12-30 18:50:46 +00:00
end
one()
two()
```
2014-12-30 18:50:46 +00:00
2018-09-14 15:00:44 +01:00
Remember that nil means **not initialised**.
The variable hasn't been assigned a value yet,
2018-10-16 21:44:20 +01:00
doesn't exist, or has been uninitialised (meaning set to nil).
2014-12-30 18:50:46 +00:00
2018-10-16 21:44:20 +01:00
The same applies to functions. Functions are variables of a special type, and
should be made local, because other mods could have functions with the same names.
2014-12-30 18:50:46 +00:00
2018-10-16 21:44:20 +01:00
API tables should be used to allow other mods to call the functions:
2014-12-30 18:50:46 +00:00
```lua
2014-12-30 18:50:46 +00:00
mymod = {}
function mymod.foo(bar)
return "foo" .. bar
2014-12-30 18:50:46 +00:00
end
-- In another mod, or script:
mymod.foo("foobar")
```
2014-12-30 18:50:46 +00:00
2015-02-22 10:28:37 +00:00
## Including other Lua Scripts
2014-12-30 18:50:46 +00:00
2018-09-14 15:00:44 +01:00
The recommended way to include other Lua scripts in a mod is to use *dofile*.
2014-12-30 18:50:46 +00:00
```lua
2014-12-30 18:50:46 +00:00
dofile(minetest.get_modpath("modname") .. "/script.lua")
```
2014-12-30 18:50:46 +00:00
2018-10-16 21:44:20 +01:00
"local" variables declared outside any functions in a script file will be local to that script.
2018-09-14 15:00:44 +01:00
A script can return a value, which is useful for sharing private locals:
```lua
2018-09-14 15:00:44 +01:00
-- script.lua
return "Hello world!"
-- init.lua
local ret = dofile(minetest.get_modpath("modname") .. "/script.lua")
print(ret) -- Hello world!
```
2014-12-30 18:50:46 +00:00
2018-10-16 21:44:20 +01:00
Later chapters will discuss how to split the code for a mod in a lot more detail;
however, the most simple approach is to have different files for different
types of things, for example nodes.lua, crafts.lua, craftitems.lua, and so on.