4. Tables
A table holds several values together. It is the only data structure Lua has, and it does two jobs: a list of things in order, and a record of named things.
A list
Write the values between curly brackets:
The number in square brackets is the position, and # gives how many there are.
Lists start at 1 in Lua. The first item is inventory[1]. In most other languages it would be 0, and this is the mistake people from those languages make most.
A position that has nothing is nil:
Changing a list
Going through a list
ipairs gives each position and its value, in order. When you do not need the position, the habit is to call it _:
A record
A table can also hold values under names:
Read and change a named value with a dot. Assigning to a name that is not there yet adds it:
A name that is not there reads as nil. That is not an error, which is handy and also hides typing mistakes: player.helth is quietly nil.
Going through a record
pairs gives every name and its value:
The order pairs goes in is not fixed. Use a list and ipairs when order matters.
Names in square brackets
player.name is short for player["name"]. The long form is for when the name is in a variable:
That makes a table a lookup: give it a name and get the value back. Removing an entry is assigning nil to it.
Tables inside tables
A value in a table can be another table. A list of records is the shape most game data has:
A variable holds the table, not a copy
This surprises everyone once:
b = a does not copy the table. Both names now refer to the same one, so a change through either shows through the other.
The same goes for passing a table to a function: the function gets the same table and can change it. Numbers, strings and booleans are copied. Tables are shared.
For the same reason, two tables are equal only when they are the same table:
In a game
Functions that find several things return a list of them:
A script's Fields is a record, and so is the script itself:
A saved game is a table too. SaveData.Save("Slot1", { Level = 3, Gold = 250 }) writes it and SaveData.Load("Slot1") gives it back.
One thing differs: a Vec3 is not a table. Reading entity.Position gives you a copy, so changing the copy does not move the entity. Assign it back:
Try it
- Make a list of five scores. Go through it and print the highest.
- Make a record for a weapon with a name, a damage and a range. Write a function that takes a weapon and prints a line describing it.
- Make a list of three weapons like that, and print the name of the one with the most damage.
Next: objects and scripts.