Lua is a quite simple and yet powerful scripting language. It was chosen for it's simplicity and has a lot to offer. If you're familiar with programming it shouldn't be hard to follow along.

See the official Lua documentation to learn about all aspects of the language. The Lua version used in TheoTown is 5.2.x.

To test small Lua code snippets I recommend to use services like the online Lua demo for testing in a separate environment. You can output text there by using the print function.


A variable is a named place in memory that can contain data. To assign data to a variable, you can use the asignment operator =. This looks like:

-- This is a comment

local a = 42       -- variable a has a value of 42 now
local b = 'Text'   -- assign a text to a variable b
local c = 7.5 + a    -- calculate 7.5 + a and store it into c
local d = {}       -- create a table and store it into d
d.x = b            -- put value of b into the table d using name x

Don't mind the local statement. It's important when it comes to scoping in the next chapter.

Comments are prefixed by -- and won't be interpreted by the compiler.

Lua supports a wide range of numbers as a single data type. Internally a 64 bit floating point representation is used for all of them. For example in Java this data type is referred to as double.

Text is handled by a data type called string. Such strings are prefixed and postfixed by either single or double quotes (which won't be part of the string itself).


The scope of a variable describes from where is can be accessed/where it's located. In Lua there are basically three types of scopes for variables:

  1. Global variables
  2. Local variables (includes the parameters of a function)
  3. Variables inside a table

Whenever you assign a value to or try to read a variable that hasn't been defined with local before it will be global:

local x = 42 -- Local
y = 42       -- Global since it wasn't defined as local (before)
x = 32       -- Still local since x was already defined

function foo(z)
  z = 7      -- local since parameter variables are always local
  x = 32     -- Still local; nested scope

This distinction is important when it comes to isolation. While local variables can only be accessed within the context in which they have been defined global variables can be accessed from everywhere (including other scripts). To avoid hard to debug errors in your code I suggest to always use local variables if possible.

Sidenote: Global variables are actually just syntactic sugar for variables in a special table.


The main data type in Lua are tables. A table can by created like that:

local t = {}

You can just put values into it:

t[42] = 7
t['xyz'] = 'ok'

And then also retrieve them:

print(t[42])  --Prints 7
print(t['xyz'])  --Prints ok

A more readable syntax for string valued keys allows us to write:

print(  --Prints ok

So a table is basically what's called a dictionary in other languages. However, thanks to it's syntactic sugar it allows us to use them like classes in other languages:

local complex = {}
complex.real = 7
complex.imag = 2


Work in progress.

Control structures

Work in progress.

Garbage collection

To motivate this topic have a look at this short example:

for i = 1, 10000000 do
  local t = { x = i }  -- Let's create a table that takes up some space

It basically creates a new table 10,00,000 times without cleaning anything up. So it will eventually run out of memory, right? Actually not, because Lua is a memory managed language. This means that memory is freed up when it's not in use anymore/cannot be accessed anymore. Here the tables created in previous iterations of the loop aren't accessible anymore and therefore can be freed up by the so called garbage collector.

In conclusion you usually don't have to worry about when the garbage collector will free up memory and you especially don't have to clear it up yourself. However, for the garbage collector to work properly you have to ensure that you don't keep references to objects that you don't use anymore.


A language gains it's true power from the libraries that are available for it. Regarding TheoTown scripting you'll find all of the relevant libraries listed in the left sidebar (they are called Modules there).

However, when it comes to more basic features Lua has it's own set of standard libraries that are available in any Lua environment. For a full list of all available modules and their function see the Lua documentation index. Here are some examples that use the standard libraries:

print(math.sin(math.pi))  -- Really close to 0
print(os.clock())         -- Used CPU time in seconds (should be close to 0 right here)
print(          -- Formatted date
print(os.time())          -- Unix timestamp (a big number)
print(string.upper('hello')) -- HELLO
print(table.concat({'a', 'b', 'c'})) -- abc

generated by LDoc 1.4.3 Last updated 2022-07-01 21:38:40