Skip to main content
If you have never written code before, this page is for you. Lua is a small, friendly scripting language designed to be embedded inside other programs — and in RollingQuest it is the language you use to add custom behavior to your levels. You do not need to install anything; the game’s built-in script editor is all you need. Work through each section in order and you will have a solid enough foundation to start writing real game scripts by the end.

What is Lua?

Lua (pronounced LOO-ah) is a lightweight scripting language created in 1993. It is designed to be simple, fast, and easy to embed in other software. In RollingQuest, every script you write is a Lua file. The game reads your file, executes it, and calls specific functions inside it when game events happen. A Lua script is just plain text. Each line is an instruction that tells the game to do something — store a value, make a decision, repeat an action, or call a function. You will learn all of these one by one below.

Comments

Before anything else, learn comments. A comment is a line (or part of a line) the game completely ignores — it is there only for you to read.
Get into the habit of writing comments to explain why your code does something. You will thank yourself later.

Data Types

Every value in Lua has a type. There are six types you will use regularly.

nil — nothing

nil means the absence of a value. A variable that has never been set, or that you deliberately clear, holds nil.

boolean — true or false

A boolean holds exactly one of two values: true or false. You use booleans to make decisions.

number — integers and decimals

Lua uses one number type for both whole numbers and decimal numbers.
You can use standard arithmetic with numbers (covered in the Operators section below).

string — text

A string is a sequence of characters enclosed in double quotes or single quotes. Both styles work identically.
To join two strings together, use the .. concatenation operator:

table — collections of values

Tables are Lua’s only built-in data structure and they are extremely versatile. You use them both as arrays (ordered lists) and as dictionaries (named collections). Array-style table (values indexed by number, starting at 1):
Dictionary-style table (values indexed by name):
You can also mix styles, nest tables inside other tables, and add or remove entries at any time. Tables are covered in more depth in their own section below.

function — reusable blocks of code

Functions are values too. You can store a function in a variable, pass it to another function, or return it. Functions are covered fully in their own section below.

Variables

A variable is a named container that holds a value. In Lua you create a variable with the local keyword.
Always use local unless you have a specific reason not to. Without local a variable becomes global — it is accessible from any script, which can cause hard-to-find bugs when two scripts accidentally use the same name.
You can change (reassign) a variable’s value at any time, even to a different type:

Naming conventions

  • Use descriptive names: remainingLives is clearer than rl.
  • Variable names are case-sensitive: score and Score are two different variables.
  • By convention, local variables use camelCase (first word lowercase, subsequent words capitalized).
  • Constants (values you never intend to change) are often written in ALL_CAPS.

Operators

Arithmetic

Comparison

Comparison operators always produce a boolean result.
In Lua, “not equal” is written ~=, not != as in many other languages.

Logical

String concatenation

Use .. to join strings. Numbers are automatically converted to strings when concatenated.

Control Flow

Control flow lets your script make decisions and repeat actions.

if / elseif / else / end

An if block runs its code only when the condition is true.
Every if must be closed with end. You can have as many elseif branches as you need, and the else branch is optional.

while loop

A while loop keeps running as long as its condition stays true.
Make sure the condition eventually becomes false, or the loop will run forever and freeze the game.

for loop — numeric

A numeric for loop counts from a start value to an end value, one step at a time.

for loop — generic with ipairs and pairs

Use ipairs to iterate over an array-style table in order:
Use pairs to iterate over a dictionary-style table (order is not guaranteed):

Functions

A function is a named block of code you can run (call) as many times as you like.

Defining and calling a function

Parameters and return values

Functions can accept parameters (inputs) and return a value as output.

Multiple return values

Lua lets a function return more than one value at once:

Tables (in depth)

You were introduced to tables in the data types section. Here is a closer look.

Creating tables

Reading and writing values

Nested tables

Tables can hold other tables:

Iterating


Applying Lua to RollingQuest

You now know enough Lua to write real game scripts. Here is how the pieces connect:
  • Hooks are just functions. You define a function with a specific name (OnStart, OnBallRoll, OnDeath, etc.) and the game calls it automatically when that event happens.
  • The entity is passed as self. The first parameter of every hook is the entity the script is attached to — a Level, Block, Ball, etc.
  • API namespaces are global tables. Dialog, Level, Logger, and the rest are just tables with functions in them, available in every script.

Your first complete script

The script below is a Level script. It uses a variable, an if statement, and Dialog.createTemporary to greet the player when the level starts.
When the level starts the engine calls OnStart, passing the level entity as self. The script checks a boolean flag to guard against showing the message twice, builds a greeting string with .., and calls Dialog.createTemporary to display it for four seconds.
Move on to Script Editor to learn how to create a script file, attach it to a level entity, and run it in the game.