TABLE
A table is a way to store and organize sets of data in a flexible and dynamic way.
Think of a table as a collection of related information, like a list of groceries or a directory of phone numbers. You can imagine these tables like data tables: sets of information placed into rows and columns.
You can collect and organize your game information easily into tables. You can't view the tables in PICO-8, so you will have to imagine them, and we will display our examples here as data tables, such as:
Shopping List
Number | Food Item |
---|---|
1 | "apples" |
2 | "bananas" |
3 | "carrots" |
Player Stats
Attribute | Points |
---|---|
health | 10 |
magic | 20 |
defense | 13 |
Tables are a powerful tool for programmers, not just for organizing data for easy use, but also to make more efficient and dynamic code (More on that below). Tables and loops often go hand in hand, so having a good understanding of both is necessary to planning how to organize your data into tables well.
Terms Related to Tables
Key
The first column's data. A number or string used to find the data stored in Column 2.
Value
The second column's data. A number, string, boolean, table, or function that you want to store.
Column 1 (key) |
Column 2 (value) |
---|---|
1 | "A" |
2 | "B" |
3 | "C" |
Index
When a table has numbered keys (like the shopping list above), these numbers are referred to as indexes.
Sorting
The process of arranging the entries of the table in a specific order. A numbered table in Lua and PICO-8 is automatically sorted in ascending order, starting at 1 (note that most programming languages start at 0, so if Lua is not your first language, this may take some getting used to).
Count / Length
The "count" or "length" of a table is the total number of entries in the table. See count function.
Lookup
A table lookup is the process of searching for and getting a specific value or element within a table. The lookup process involves specifying a key or index, which is used to identify the desired element in the table. See "How to get a value from a Table" (coming soon).
Iteration
To iterate means to cycle through something one at a time. We can iterate through the values of a table easily using Loops. This is useful when you want to check or do something for every entry in a table.
Advanced Table Terms
Nested Tables
It is possible to have tables inside of other tables. When multiple things are organized inside of each other, we call them "nested". You can think of these like folders on your computer; you can store files inside of folders and also have folders inside of folders ("nested folders"). You can have as many nested tables (tables inside of other tables) as you want.
Parent & Child
When you have nested tables, we refer to the outer table as the parent and the inner table as the child.
enemies = {}
enemies[1] = {
name="goblin",
health=5,
attack=3
}
enemies[2] = {
name="ogre",
health=10,
attack=6
}
Enemies (Parent Table) | |||||||||
---|---|---|---|---|---|---|---|---|---|
1 |
|
||||||||
2 |
|
Another way to add more child tables and let them be automatically numbered is with add
.
add( enemies, { name="orc", health=8, attack=7 } )
Tables are "Efficienct and Dynamic"
Efficiency refers to how well a program uses system resources (such as memory, processing power, and input/output operations). An efficient program is one that can achieve its goals with minimal resource usage, while avoiding unnecessary operations.
Here is a comparison of code that is organized with and without tables.
Without Tables
--item variables
item_sprite = 1
item_x = 10
item_y = 20
--get value
print(item_sprite) --prints 1
--draw item
spr(item_sprite, item_x, item_y)
--17 tokens
With Tables
--item table
item = { sprite=1, x=10, y=20 }
--get value
print(item.sprite) --prints 1
--draw item
spr(item.sprite, item.x, item.y)
--24 tokens
So far, these don't look too different. And if we compare the tokens, the one without tables looks more efficient. However, this example is only for a single item in the entire game. So imagine if we add just 2 more items.
Well without tables, we have to write 3 new unique variables for every item. But thanks to tables, those variables turn into keys, and you can use the same key in different tables without getting their values confused. This also makes looping through the tables much easier because you can lookup the same exact key name such as sprite
and simply change the table that is being looked up to get the different sprite value for the different items.
Here is how we could have 3 items:
Without Tables
--item variables
item1_sprite = 1
item1_x = 10
item1_y = 20
item2_sprite = 2
item2_x = 30
item2_y = 50
item3_sprite = 3
item3_x = 70
item3_y = 90
--get one value
print(item1_sprite) --prints 1
--draw each item
spr(item1_sprite,item1_x,item1_y)
spr(item2_sprite,item2_x,item2_y)
spr(item3_sprite,item3_x,item3_y)
--45 tokens
With Nested Tables
--items table of tables
items = {
{ sprite=1, x=10, y=20 },
{ sprite=2, x=30, y=50 },
{ sprite=3, x=70, y=90 },
}
--get one value
print(items[1].sprite) --prints 1
--loop and draw each item
for item in all(items) do
spr(item.sprite,item.x,item.y)
end
--50 tokens
Look how fast the tokens of the code without tables caught up to the code with tables; that's just 3 items. Your game is sure to have many more than that! Not just items but your game will probably have many enemies, bullets, particles and more. It would be crazy to write out enemy1_sprite
, enemy1_x
, enemy1_y
for even just 10 enemies! And so, tables are efficient!
But what do we mean by tables being dynamic?
Dynamic refers to the way something can change or adapt while the program is running. Global variables are set one time, and they can be changed any time after that. But if we are talking about items that a player can pick up or enemies that can be killed, how do we handle those variables when the item or enemy should no longer be in the game at all?
Tables are dynamic because they can grow and shrink in size. We can add to and delete from a table at any time. This makes it easy to prepare a function for adding a new item or enemy to the game at certain parts of the game, and remove them from the game just as easily when they should no longer be there.
This dynamic organization of our game objects also makes it very easy for us to count how many of those objects there are by simply counting the table.
2785
28 Apr 2024