Help Support the Baja Engine! Donate to Breezeway Studios!
Lua Basics


About This Tutorial

This tutorial will introduce you to the basics of Lua. It assumes a little prior programming knowledge or knowledge of logic and mathematics.

More complete documentation of Lua can be found in the Reference Manuel or the much more approachable Programming in Lua

Lua is very simple

Lua is a very simple simple language; indeed, it is programming distilled into its most essential elements. Likewise, this tutorial attempts to distill all of the most basic elements of a program that while simple, can accomplish every scripting task you need to do in the engine.


It is often helpful to add text to your scripts that is ignored by Lua. Programmers call these groups of text 'comments'. You can make a comment in Lua by typing '--' before the text.


--this is a comment
--'hello' is only written to the Script Console once


Variables are where you store data. There is only one 'type' of variable in lua; it can hold either strings, numbers, boolean values, or functions just by assigning one of those things to it.

While variables can hold any type, the engine's libraries often require a certain type of data. Variables in the Baja Engine documentation have all been marked [Number], [String], or [Boolean] to indicate what type of data they need to be set to to function properly.

Unlike languages like C, you never have to define a variable or set its type, you can just use it.


--create a variable called 'x' with the numerical value 0.1

--create a variable called 'y' with the numerical value 0.2

--add x and y, now 'z' holds 0.3

--create a string

--create another string
m=" world"

--now w contains 'hello world'; the '..' operator concatenates strings

--boolean values are either true or false


Everything in Lua is stored in a table. A table is essentially a group of variables. All of the variables we talked about above were stared in the 'global' table, which stores everything. Tables can be hierarchical: you can create tables inside tables! Like variables, tables are created on the fly. A table is made up of a series of 'keys' that access 'values' stored in the table. Think of tables like treasure chests: you can put treasure chests within other treasure chests, and you can only retrieve what you want out of a treasure chest if you have the right key.

While tables can be put laid out in any form, it is sometimes useful to treat a certain table layout as a psudo-variable type. Table layouts that are used very frequently in the engine and documentation are Vector2d, Vector3d, and Vector4d. Note: there is nothing special about these; they are just tables layed out a certain way that the engine is programmed to understand.


--Make a table

--Make a string value 'hello' that is accessed by a numerical key '1'

--Make another entry in the table
t[2]=' world'

--Prints 'hello world'

--keys can also be strings

--prints out 'myvalue'

--key values can also be accessed this way:

--set the x position of an object. Both 'pos' and 'x' are just string keys in a table


Functions contain groups of actions that are performed on your data. Functions can be passed data in variables called 'arguments', and they can return functions to the place where they were called from.


--define a function
function helloworld()
        print("hello world")        --print to the Script Console

--now we call our function. Now 'hello world' will actually be written to the console

--this function takes two numbers and adds them and returns the result
function add(x,y)
        return x+y

--now z equals 50

String Operators

String operators perform functions on strings. The two string operators are .. (concatenate) and #.

--the .. concatenate operator: now s equals 'hello world'
s='hello '..'world'

--now # length operator: now x equals 5

Mathematical Operators

The mathematical operators are the typical algebraic operators: +,-,/,*. More math functions are found in math.


--add: now x equals 10

--subtract: now x equals 5

--multiply: now x equals 25

--divide now x equals 2

Logical Operators

Logical operators result in a Boolean (true/false) value. They are mostly used with control structures (explained later).


The logical operators are ==,~=,<,<=,>,>=, and not.


--equal to: b is false, 5 doesn't equal 6

--equal to: b is true, 5 does equal 5

--not equal to: b is true, 5 does not equal 6

--less than: b is true, 5 is less than 6

--greater than: b is true, 7 is greater than 6

--greater than: b is false, 7 is the same as 7 (not less than it)

--greater than OR EQUAL TO: b is true, 7 is equal to 7

--less than OR EQUAL TO: b is true, 6 is equal to 6

--not: b is FALSE, 6 is equal to 6, but 'not' FLIPS the boolean value to false
b=not (6==6)

--not: b is TRUE, 6 is not equal to 7, but 'not' FLIPS the boolean value to true
b=not (6==7)

Control Structures

Control structures allow you to rig your script to make logical decisions. They allows you to, for example, trigger a light if the player enters a room, or have a monster approch while the player is hiding.

if then else

An 'if then else' conditional runs a series of instructions only if the data in a variable or expression is true. If it's false, it proceeds to take other action or does nothing.


--A simple if then statement
if then        --if the player is in side the room
        obj.light.on=true        then the light is on
else        --if not
        obj.light.on=false--the light is off

--a more complicated example
if obj.room1.insidebb then        --if the player is in the first room
        obj.light1.on=true        then the first light is on
        obj.light2.on=false        then the second light is off
elseif obj.room2.insidebb then        --if the player is in the second room
        obj.light1.on=false        then the first light is off
        obj.light2.on=true        then the second light is on
else        --if the player is in another room
        obj.light1.on=false        then the first light is off
        obj.light2.on=false        then the second light is off

while do

The 'while do' control structure repeatedly does a series of actions while some other expression or variable is still true.


--sets up a counter

--this loop will run 100 times; each time it runs, 'i' is one less
--until i is equal to one and the condition expression is false
--kind of like the song '99 bottles of beer on the wall'!
while i>0 do

for do

The 'for' operator is used to go through all the elements of a table and do something to them. The 'for' operator returns the 'key' and the 'value' of each element.


--print out the keys and values of every element in the table
for k,v in pairs(mytable) do
        print('Key:'..k..' Value:'..v)


Libraries in lua are essentially tables that contain a group of functions and data used to accomplish certain tasks. The Lua Scripting page in the documentation contains all the libraries that are used to interact with and control the engine.


--turns fog on

--loads a level

Putting it All Together

Here is an example script that puts together all of the basics of programming you've learned in this tutorial.


--set up some variables we'll use later

--this function is called every frame by the engine
function perframe()


--this function is called when the engine starts
function main()


Lua Tips

When you're running a development build of the engine, the tab key opens up the Script Console. This lets you interact with your scripts in real time, and if you use it it can cut down on debugging time immensely. A very useful function when doing this is serialize() (see GLOBAL). 'serialize' basically writes all information about a table or variable to the console - this lets you, say, check the position of an object to see if it's in the right place, or write out all of the functions in a library if you forgot the name of one of them.

The tutorial on Cutscenes introduces on of the more advanced topics in Lua, coroutines.

Finally, be sure to read through Lua Pitfalls, which outlines workarounds to a few problems that you will encounter at some point.