Luawe the Wayfarer Engine's scripting language All pages

Values and variables

Everything a script works with is a value: a number, a piece of text, a yes or a no. This page is about the kinds there are and how to keep them.

The kinds of value

KindLooks likeWhat it is
number7, -2.5, 1_000_000A number, whole or not
string"door", 'door'Text
booleantrue, falseYes or no
nilnilNothing at all
table{ 1, 2, 3 }Many values kept together: see lists and tables
functionfunction() ... endSomething to do: see functions

The game adds kinds of its own, such as a thing of the level or an event. type(value) tells which kind a value is:

print(type(7), type("door"), type(true), type(nil), type({}), type(print))

It prints

number string boolean nil table function

Variables

A variable is a name for a value. local makes one:

local lives = 3
local name = "Sky"
print(name, lives)

lives = lives - 1 -- a variable can be given a new value
print(name, lives)

It prints

Sky 3
Sky 2

A variable lasts until the end of the block it was made in (a function, a loop, an if), and code outside that block cannot see it. Made at the top of a script, it lasts for the whole script.

Several can be made at once, and two can swap in one line:

local x, y = 1, 2
x, y = y, x
print(x, y)

It prints

2 1

Variables that never change

const makes a variable that keeps its first value. Giving it another one is a mistake the editor marks before the level even runs.

const SPEED = 4
const COLUMNS, ROWS = 9, 5
print(SPEED * COLUMNS, ROWS)

It prints

36 5

Use it for the numbers that set a script up. Whoever reads the script sees at once that they are settings, and nobody changes one by accident.

Without local

A name given a value without local or const is a global: every function of the script can see it, from anywhere. Globals are easy to mix up, so prefer local. A global belongs to its own script; other scripts cannot see it (they share in another way).

Numbers

Numbers do arithmetic:

SignDoesExample
+ - * /Add, subtract, multiply, divide7 / 2 is 3.5
//Divide and round down7 // 2 is 3
%What is left after dividing7 % 3 is 1
^To the power of2 ^ 10 is 1024
-xThe other sign-(3) is -3

Brackets decide what is worked out first, as in maths: (1 + 2) * 3 is 9.

A long number can be written with _ between its digits (1_000_000), and numbers can be written in base 16 (0xff is 255) or base 2 (0b1010 is 10).

There is one kind of number. 7 and 7.0 are the same value, and a whole number prints without a point.

Changing a number in place

lives = lives - 1 is so common that it has a short form:

local score = 10
score += 5 -- the same as score = score + 5
score *= 2
score -= 1
print(score)

It prints

29

There is one for each sign: += -= *= /= //= %= ^=, and ..= for joining text.

The math library has the rest: rounding, the biggest and smallest of several, sines, and helpers such as math.clamp and math.lerp.

Strings

A string is text between quotes. "double" and 'single' quotes do the same; use the kind that the text itself does not contain.

.. joins strings (and numbers) into one string, and # gives a string's length:

local name = "Sky"
print("Hello, " .. name .. "!")
print(#name)

It prints

Hello, Sky!
3

Text with values in it

A string between backticks can have values in it. Whatever stands between { and } is worked out and put into the text:

local coins, total = 3, 10
print(`{coins} of {total} coins, {total - coins} to go`)

It prints

3 of 10 coins, 7 to go

This is the easiest way to build a message. To write a real { in such a string, put a backslash before it: \{.

Signs inside a string

Some signs are written with a backslash:

WrittenMeans
\nA new line
\tA tab
\" \'A quote, inside quotes of the same kind
\\A backslash

A long text over several lines goes between double square brackets, where nothing has a special meaning:

local poem = [[Stay on the floor,
mind the saws.]]
print(poem)

It prints

Stay on the floor,
mind the saws.

Working with text has much more: cutting strings up, changing them, finding things in them.

Numbers and strings are not the same

"10" is text and 10 is a number. Luawe does not turn one into the other behind your back in arithmetic: "10" + 1 is an error. Say what you mean:

print(tonumber("10") + 1) -- text to number
print(tostring(10) .. "!") -- number to text
print(tonumber("ten"))     -- not a number: nil

It prints

11
10!
nil

Joining with .. and the {...} in a backtick string do accept numbers, since there it is clear what is wanted.

True, false and nil

A boolean is true or false. Comparing gives one:

SignAsks
==The same?
~= or !=Not the same?
< <= > >=Smaller, at most, bigger, at least?

Three words combine them:

local lives, hasKey = 2, false
print(lives > 0 and hasKey)
print(lives > 0 or hasKey)
print(not hasKey)

It prints

false
true
true

In an if, only false and nil count as no. Everything else counts as yes, also 0 and the empty string "".

and and or give back one of their two values, which makes a handy way to pick a fallback:

local given = nil
local name = given or "Nobody" -- given if there is one, else "Nobody"
print(name)

It prints

Nobody

nil means that there is no value: a variable nothing was given to, a table's key that is not there, a thing that was not found.

Next: decisions and loops.