--- title: Lua Scripting layout: default root: ../.. idx: 1.2 description: A basic introduction to Lua, including a guide on global/local scope. redirect_from: /en/chapters/lua.html --- ## Introduction 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. - [Programming](#programming) - [Coding in Lua](#coding-in-lua) - [Code Editors](#code-editors) - [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) ## 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. ### Coding in Lua It's also beyond the scope of this book to teach Lua coding. The [Programming in Lua](https://www.lua.org/pil/contents.html) book is an excellent introduction to Lua programming. ## Code Editors A code editor with code highlighting is sufficient for writing scripts in Lua. 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: ```lua 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 table.insert(ctf.team(team).log,1,msg) ctf.save() return true end ``` 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: * [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 Other suitable editors are also available. ## Local and Global Scope 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: ```lua -- Accessible from within this script file local one = 1 function myfunc() -- Accessible from within this function local two = one + one if two == one then -- Accessible from within this if statement local three = one + two end end ``` In contrast, 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() ``` ### Locals should be used as much as possible 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: Assignment to undeclared global 'foo' inside function at init.lua:2 To correct this, use "local": ```lua function one() local foo = "bar" end function two() print(dump(foo)) -- Output: nil end one() two() ``` 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). Functions are variables of a special type, but should also be made local, because other mods could have functions with the same names. ```lua local function foo(bar) return bar * 2 end ``` To allow mods to call your functions, you should create a table with the same name as the mod and add your function to it. This table is often called an API table or namespace. ```lua mymod = {} function mymod.foo(bar) return "foo" .. bar end -- In another mod, or script: mymod.foo("foobar") ``` ## Including other Lua Scripts The recommended way to include other Lua scripts in a mod is to use *dofile*. ```lua dofile(minetest.get_modpath("modname") .. "/script.lua") ``` A script can return a value, which is useful for sharing private locals: ```lua -- script.lua return "Hello world!" -- init.lua local ret = dofile(minetest.get_modpath("modname") .. "/script.lua") print(ret) -- Hello world! ``` [Later chapters](../quality/clean_arch.html) will discuss how best to split up code for a mod.