Values and variables
Lesson 3.1
Every piece of data in Lua is a value, and a variable is a name you give to a value so you can use it later.
Values and their types
Each value has a type. Lua has eight:
| Type | Examples | Used for |
|---|---|---|
nil |
nil |
“nothing here” |
boolean |
true, false |
yes/no answers |
number |
64, 0.5, -3 |
counts, health, coordinates |
string |
"Diamond", 'Steve' |
text |
table |
{ 1, 2, 3 } |
lists, records, objects |
function |
print |
code you can call |
userdata |
(made by the host) | game objects such as players |
thread |
(made by coroutine.create) |
coroutines |
The type function tells you the type of any value, as a string:
print(type(64)) --> number
print(type("Torch")) --> string
print(type(true)) --> boolean
print(type(nil)) --> nil
print(type({})) --> table
print(type(print)) --> function
You will meet every type in this course. Userdata is the only one you never create yourself: in Celestial, things like players and entities are userdata that the game hands to you.
Variables
A variable stores a value under a name. Create one with local:
local health = 20
local name = "Steve"
print(name, health) --> Steve 20
The = sign means “store the value on the right in the name on the left”. It is not a maths equation. You can store a new value any time:
local health = 20
health = health - 4 -- take 4 damage
print(health) --> 16
A variable has no fixed type. The same variable can hold a number now and a string later, although that usually makes code confusing.
Names
Names may contain letters, digits and underscores, and must not start with a digit. Case matters: score, Score and SCORE are three different variables.
local max_stack = 64 -- good
local playerName = "Alex" -- also fine
local _unused = 0 -- a leading underscore often means "not used"
You can’t use the 22 keywords as names: and, break, do, else, elseif, end, false, for, function, goto, if, in, local, nil, not, or, repeat, return, then, true, until, while.
Most Lua code, including the Celestial API, uses snake_case: lowercase words joined by underscores.
nil: the missing value
A variable that was never given a value holds nil:
local pickaxe
print(pickaxe) --> nil
nil means “no value”. Setting a variable to nil throws its value away.
Local and global variables
Without local, you create a global variable, which every part of the program can see:
coins = 10 -- global
local gems = 2 -- local
print(coins, gems) --> 10 2
This looks harmless, but globals cause bugs: two files that both use a global called count silently overwrite each other. Reading a global you never set also gives nil instead of an error, so a typo goes unnoticed:
local score = 5
print(scroe) --> nil
Always write local
Use local for every variable. It is faster, and it keeps each part of your code separate. In Celestial, each mod runs in its own sandbox, but inside your mod the same rule applies.
A local variable exists from the line where it is declared to the end of its block. Blocks are the bodies of if, loops and functions, or a do ... end pair:
local x = 1
do
local x = 2 -- a new x, only inside this block
print(x) --> 2
end
print(x) --> 1
The inner x shadows the outer one. Both exist; inside the block the name means the inner one.
Several variables at once
You can assign several values in one statement. The values are matched up left to right:
local x, y, z = 10, 64, -5
print(x, y, z) --> 10 64 -5
Extra names get nil, extra values are dropped:
local a, b = 1
print(a, b) --> 1 nil
This makes swapping two values easy:
local first, second = "Stone", "Dirt"
first, second = second, first
print(first, second) --> Dirt Stone
Constants
Lua 5.4 lets you mark a local as <const>. Assigning to it again is an error that Lua reports before running anything:
local MAX_HEALTH <const> = 20
print(MAX_HEALTH) --> 20
-- MAX_HEALTH = 30 would be an error: attempt to assign to const variable
Many programmers simply write constants in UPPER_CASE and don’t change them.
Try it
Create local variables for a player called "Alex" with 20 health and 3 arrows. The player shoots one arrow and takes 6 damage. Update the variables and print the name, health and arrows on one line. Then print the type of each variable.
Show a solution
local name = "Alex"
local health = 20
local arrows = 3
arrows = arrows - 1
health = health - 6
print(name, health, arrows) --> Alex 14 2
print(type(name), type(health), type(arrows)) --> string number number
Recap: values have types, local name = value stores them, and a missing value is nil.