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
|
|
|
---
|
|
|
|
|
2019-05-31 20:32:40 +03:00
|
|
|
## Introduction <!-- omit in toc -->
|
2014-12-30 21:50:46 +03:00
|
|
|
|
2022-07-31 19:39:25 +03:00
|
|
|
In this chapter, you'll learn about scripting in Lua, the tools required
|
|
|
|
to help with this, and some techniques that you may find useful.
|
2014-12-30 21:50:46 +03:00
|
|
|
|
2022-03-22 15:25:47 +03:00
|
|
|
- [Programming](#programming)
|
2022-06-14 02:33:55 +03:00
|
|
|
- [Coding in Lua](#coding-in-lua)
|
2019-05-31 20:32:40 +03:00
|
|
|
- [Code Editors](#code-editors)
|
|
|
|
- [Local and Global Scope](#local-and-global-scope)
|
2022-06-14 02:33:55 +03:00
|
|
|
- [Locals should be used as much as possible](#locals-should-be-used-as-much-as-possible)
|
2019-05-31 20:32:40 +03:00
|
|
|
- [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
|
2022-07-31 19:39:25 +03:00
|
|
|
absolute basics, and learning the problem-solving techniques required to program.
|
|
|
|
It's great for children and teenagers.
|
2022-03-22 15:25:47 +03:00
|
|
|
* [Programming with Mosh](https://www.youtube.com/user/programmingwithmosh) is
|
|
|
|
a good YouTube series to learn programming.
|
|
|
|
|
2022-06-14 02:33:55 +03:00
|
|
|
### Coding in Lua
|
|
|
|
|
|
|
|
It's also beyond the scope of this book to teach Lua coding.
|
2022-07-31 19:39:25 +03:00
|
|
|
The [Programming in Lua (PiL)](https://www.lua.org/pil/contents.html) book is an
|
2022-06-14 02:33:55 +03:00
|
|
|
excellent introduction to Lua 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
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2014-12-30 21:50:46 +03:00
|
|
|
function ctf.post(team,msg)
|
2017-08-26 21:01:51 +03:00
|
|
|
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
|
|
|
|
2017-08-26 21:01:51 +03:00
|
|
|
table.insert(ctf.team(team).log,1,msg)
|
|
|
|
ctf.save()
|
2014-12-30 21:50:46 +03:00
|
|
|
|
2017-08-26 21:01:51 +03:00
|
|
|
return true
|
2014-12-30 21:50:46 +03:00
|
|
|
end
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|
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
|
|
|
|
2022-07-31 19:39:25 +03:00
|
|
|
* [VSCode](https://code.visualstudio.com/):
|
2021-01-25 11:35:55 +03:00
|
|
|
open source (as Code-OSS or VSCodium), popular, and has
|
2022-07-31 19:39:25 +03:00
|
|
|
[plugins for Minetest](https://marketplace.visualstudio.com/items?itemName=GreenXenith.minetest-tools).
|
|
|
|
* [Notepad++](http://notepad-plus-plus.org/): simple, Windows-only
|
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
|
|
|
|
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
|
2022-07-31 19:39:25 +03:00
|
|
|
read from. Global variables can be accessed from anywhere in the script file,
|
|
|
|
and from any other mod:
|
|
|
|
|
|
|
|
```lua
|
|
|
|
function one()
|
|
|
|
foo = "bar"
|
|
|
|
end
|
|
|
|
|
|
|
|
function two()
|
|
|
|
print(dump(foo)) -- Output: "bar"
|
|
|
|
end
|
|
|
|
|
|
|
|
one()
|
|
|
|
two()
|
|
|
|
```
|
|
|
|
|
|
|
|
In constrast, a local variable is only accessible from where it is defined.
|
|
|
|
Lua defaults to variables being global, so you need to explicitly use the
|
|
|
|
`local` keyword:
|
2014-12-30 22:24:41 +03:00
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2014-12-30 22:24:41 +03:00
|
|
|
-- Accessible from within this script file
|
|
|
|
local one = 1
|
|
|
|
|
|
|
|
function myfunc()
|
2017-08-26 21:01:51 +03:00
|
|
|
-- Accessible from within this function
|
|
|
|
local two = one + one
|
2014-12-30 22:24:41 +03:00
|
|
|
|
2017-08-26 21:01:51 +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
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|
2014-12-30 22:24:41 +03:00
|
|
|
|
2022-06-14 02:33:55 +03:00
|
|
|
|
|
|
|
### Locals should be used as much as possible
|
|
|
|
|
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":
|
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2014-12-30 21:50:46 +03:00
|
|
|
function one()
|
2017-08-26 21:01:51 +03:00
|
|
|
local foo = "bar"
|
2014-12-30 21:50:46 +03:00
|
|
|
end
|
|
|
|
|
|
|
|
function two()
|
2017-08-26 21:01:51 +03:00
|
|
|
print(dump(foo)) -- Output: nil
|
2014-12-30 21:50:46 +03:00
|
|
|
end
|
2015-02-24 12:53:25 +03:00
|
|
|
|
|
|
|
one()
|
|
|
|
two()
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|
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).
|
2015-02-24 12:53:25 +03:00
|
|
|
|
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
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2014-12-30 21:50:46 +03:00
|
|
|
local function foo(bar)
|
2017-08-26 21:01:51 +03:00
|
|
|
return bar * 2
|
2014-12-30 21:50:46 +03:00
|
|
|
end
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|
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
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2014-12-30 21:50:46 +03:00
|
|
|
mymod = {}
|
|
|
|
|
|
|
|
function mymod.foo(bar)
|
2017-08-26 21:01:51 +03:00
|
|
|
return "foo" .. bar
|
2014-12-30 21:50:46 +03:00
|
|
|
end
|
|
|
|
|
|
|
|
-- In another mod, or script:
|
|
|
|
mymod.foo("foobar")
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|
2014-12-30 21:50:46 +03:00
|
|
|
|
2022-07-31 19:39:25 +03:00
|
|
|
`function mymod.foo()` is equivalent to `mymod.foo = function()`, it's just a
|
|
|
|
nicer way to write it.
|
|
|
|
|
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
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2014-12-30 21:50:46 +03:00
|
|
|
dofile(minetest.get_modpath("modname") .. "/script.lua")
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|
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:
|
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2018-09-14 17:00:44 +03:00
|
|
|
-- script.lua
|
2022-07-31 19:39:25 +03:00
|
|
|
local module = {}
|
|
|
|
module.message = "Hello World!"
|
|
|
|
return module
|
2018-09-14 17:00:44 +03:00
|
|
|
|
|
|
|
-- init.lua
|
|
|
|
local ret = dofile(minetest.get_modpath("modname") .. "/script.lua")
|
2022-07-31 19:39:25 +03:00
|
|
|
print(ret.message) -- Hello world!
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|
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.
|