Appearance
Tables, Part 1
Written: 2026-10-14
Learning objectives
- You build arrays and read them with 1-based positions.
- You build dictionaries with named keys.
- You nest tables inside tables.
- You measure arrays with
#and grow or shrink them withtable.insertandtable.remove. - You visit every entry with
for k, v in t, change values, and delete keys withnil.
Prerequisites
- Read First Script. You can run a Script and read output.
- Read Variables and Values. You create variables with
local. - Read Operators and Logic. You use
#and comparisons. - Read Conditionals and Loops. You count with numeric
for. - Read Functions and Scope. You call functions with arguments.
Arrays keep an ordered list
A table is a container that holds many values at once. An array is a table used as an ordered list: first item, second item, third item. You build one with curly braces and commas.
Luau counts from one. The first item lives at position 1, not 0. This is called 1-based indexing, and it is the first thing programmers from other languages get wrong.
Run this: put it in a Script in ServerScriptService and press Play.
luau
--!strict
local fruits = { "apple", "pear", "plum" }
print(fruits[1])
print(fruits[2])
print(fruits[3])txt
apple
pear
plumWalkthrough:
- Line 1 turns on strict mode.
- Line 2 builds an array of three strings and stores it in
fruits. - Line 3 prints position
1, the first item,"apple". - Line 4 prints position
2,"pear". - Line 5 prints position
3,"plum".
Square brackets with a position read one slot. You can also write through the same brackets to replace a slot or add a new one at the end.
Run this: put it in a Script in ServerScriptService and press Play.
luau
--!strict
local fruits = { "apple", "pear", "plum" }
fruits[2] = "peach"
print(fruits[2])
print(#fruits)txt
peach
3Walkthrough:
- Line 1 turns on strict mode.
- Line 2 builds the same three-item array.
- Line 3 replaces position
2with"peach". The old"pear"is gone. - Line 4 prints the new position
2,"peach". - Line 5 prints
#fruits. The#operator counts array items, so this prints3.
Dictionaries label each value
A dictionary is a table where each value has a named key instead of a position. You build one with key = value pairs inside the braces. You read values with a dot, as in player.name, or with brackets, as in player["name"].
Run this: put it in a Script in ServerScriptService and press Play.
luau
--!strict
local player = { name = "Maya", level = 7, ready = true }
print(player.name)
print(player.level)
print(player.ready)txt
Maya
7
trueWalkthrough:
- Line 1 turns on strict mode.
- Line 2 builds a dictionary with three labeled values:
name,level, andready. - Line 3 prints the value behind the
namekey,"Maya". - Line 4 prints the value behind
level,7. - Line 5 prints the value behind
ready,true.
Use arrays when order matters, like a lineup of winners. Use dictionaries when labels matter, like the stats of one player. One table can be both at once, but keep your tables one-shaped while you learn.
You add a new key by assigning to it and change a value by assigning to its key. Both use the same = you learned in Variables and Values.
Run this: put it in a Script in ServerScriptService and press Play.
luau
--!strict
local player = { name = "Maya", level = 7 }
player.level = 8
player.team = "Falcons"
print(player.level)
print(player.team)txt
8
FalconsWalkthrough:
- Line 1 turns on strict mode.
- Line 2 builds a dictionary with
nameandlevel. - Line 3 overwrites
levelwith8. - Line 4 creates a brand-new key,
team, holding"Falcons". - Lines 5 and 6 print
8andFalcons.
Tables nest inside tables
Values inside a table can be tables themselves. This is called nesting. A roster holds players, and each player holds stats. You reach inner values by chaining dots and brackets from the outside in.
Run this: put it in a Script in ServerScriptService and press Play.
luau
--!strict
local team = {
name = "Falcons",
members = { "Maya", "Rio", "Sam" },
captain = { name = "Maya", level = 8 },
}
print(team.name)
print(team.members[1])
print(team.captain.level)txt
Falcons
Maya
8Walkthrough:
- Line 1 turns on strict mode.
- Lines 2 to 6 build
team. Itsnameis a string, itsmembersis an array, and itscaptainis a dictionary. - Line 7 prints
team.name, the outer string"Falcons". - Line 8 dives into the inner array and prints position
1,"Maya". - Line 9 dives into the inner dictionary and prints its
level,8.
Read chains left to right. team.captain.level means: start at team, open captain, read level. When a chain prints nil, the break is usually one level up: some middle key is missing or misspelled.
Grow and shrink arrays
Two library functions resize arrays. table.insert adds an item. table.remove takes one away and pulls later items down to close the gap. Both shift positions, so print the array after each change while you learn.
Run this: put it in a Script in ServerScriptService and press Play.
luau
--!strict
local fruits = { "apple", "pear" }
table.insert(fruits, "plum")
print(fruits[3])
print(#fruits)
table.remove(fruits, 1)
print(fruits[1])
print(#fruits)txt
plum
3
pear
2Walkthrough:
- Line 1 turns on strict mode.
- Line 2 builds a two-item array.
- Line 3 appends
"plum"to the end. - Line 4 prints the new position
3,"plum". - Line 5 prints the new length,
3. - Line 6 removes position
1."pear"slides from position2down to position1, and"plum"slides to position2. - Line 7 prints the new position
1,"pear". - Line 8 prints the new length,
2.
Give table.insert a position to wedge an item into the middle, as in table.insert(fruits, 2, "peach"). Everything from that position onward shifts up by one. With no position, table.remove pops the last item.
Visit every entry with a loop
A for k, v in t loop visits each entry once and hands you the key and the value. For arrays the key is the position. For dictionaries the key is the label. Dictionary order is not guaranteed, so never rely on it.
Run this: put it in a Script in ServerScriptService and press Play.
luau
--!strict
local fruits = { "apple", "peach", "plum" }
for index, value in fruits do
print(index)
print(value)
endtxt
1
apple
2
peach
3
plumWalkthrough:
- Line 1 turns on strict mode.
- Line 2 builds a three-item array.
- Line 3 starts the loop. Each round puts the position in
indexand the item invalue. - Line 4 prints the position.
- Line 5 prints the item.
- Line 6 ends the loop body. Arrays visit in order, so the output runs
1apple2peach3plum.
Run this: put it in a Script in ServerScriptService and press Play.
luau
--!strict
local player = { name = "Maya", level = 8 }
for key, value in player do
print(key)
print(value)
endtxt
name
Maya
level
8Walkthrough:
- Line 1 turns on strict mode.
- Line 2 builds a two-key dictionary.
- Line 3 starts the loop. Each round puts the label in
keyand the stored value invalue. - Line 4 prints the key.
- Line 5 prints the value.
- Line 6 ends the loop body. Both entries print. Their order may vary, and that is normal for dictionaries.
You can change values mid-loop through the original table. Below, each round writes back through levels[index].
Run this: put it in a Script in ServerScriptService and press Play.
luau
--!strict
local levels = { 1, 2, 3 }
for index, value in levels do
levels[index] = value * 10
end
print(levels[1])
print(levels[2])
print(levels[3])txt
10
20
30Walkthrough:
- Line 1 turns on strict mode.
- Line 2 builds
{ 1, 2, 3 }. - Line 3 loops with
indexandvalue. - Line 4 multiplies each value by
10and writes it back into the same slot. This changes the table itself, not just the loop variable. - Line 5 ends the loop body.
- Lines 6 to 8 print
10,20,30.
Delete dictionary keys with nil
Setting a dictionary key to nil erases the entry. The key disappears. Reading it afterward gives nil, which means "nothing here". Never store nil inside an array on purpose. It punches a hole that # and loops cannot count reliably.
Run this: put it in a Script in ServerScriptService and press Play.
luau
--!strict
local player = { name = "Maya", title = "Rookie" }
print(player.title)
player.title = nil
print(player.title)txt
Rookie
nilWalkthrough:
- Line 1 turns on strict mode.
- Line 2 builds a dictionary with
nameandtitle. - Line 3 prints
"Rookie". - Line 4 assigns
niltotitle. This deletes the key entirely. - Line 5 prints
nilbecause the key no longer exists.
Common mistakes
Reading position zero.
Run this: put it in a Script in ServerScriptService and press Play.
luau
--!strict
local fruits = { "apple", "pear", "plum" }
print(fruits[0])txt
nilThis prints nil because arrays start at 1. Fix it by reading position 1 for the first item. Run the fix the same way.
luau
--!strict
local fruits = { "apple", "pear", "plum" }
print(fruits[1])txt
appleTrusting # on a table with holes.
Run this: put it in a Script in ServerScriptService and press Play.
luau
--!strict
local scores = { 10, 20, 30 }
scores[2] = nil
print(#scores)txt
Unreliable: Luau may print 1 or 3 here because the hole in the middle breaks #.The length is unreliable now because the middle is missing. Fix it by removing with table.remove, which closes the gap. Run the fix the same way.
luau
--!strict
local scores = { 10, 20, 30 }
table.remove(scores, 2)
print(#scores)
print(scores[2])txt
2
30Forgetting that table.remove shifts positions.
Run this: put it in a Script in ServerScriptService and press Play.
luau
--!strict
local fruits = { "apple", "pear", "plum" }
table.remove(fruits, 1)
print(fruits[3])txt
nilThis prints nil because "plum" slid from position 3 to position 2. Fix it by reading the new positions after removal. Run the fix the same way.
luau
--!strict
local fruits = { "apple", "pear", "plum" }
table.remove(fruits, 1)
print(fruits[1])
print(fruits[2])txt
pear
plumRelying on dictionary order.
Run this: put it in a Script in ServerScriptService and press Play.
luau
--!strict
local player = { name = "Maya", level = 8 }
for key, value in player do
print(key)
print(value)
endtxt
name
Maya
level
8You may see level first instead. Beginners expect name always first, but Luau makes no such promise for dictionaries. Treat dictionary order as random and never build logic on it. Your output above is correct as long as both entries print.
Exercises
Run every solution below in a Script in ServerScriptService and press Play. Try each exercise yourself before you open its solution.
- Build an array of three game names. Print the first and the last with brackets.
Solution 1
luau
--!strict
local games = { "Tag", "Obby", "Tycoon" }
print(games[1])
print(games[3])txt
Tag
Tycoon- Build a dictionary for a sword with keys
nameanddamage. Print both values with dots.
Solution 2
luau
--!strict
local sword = { name = "Ember", damage = 12 }
print(sword.name)
print(sword.damage)txt
Ember
12- Start from
{ "apple", "pear" }. Insert"plum"at the end and remove position1. Print the two remaining items by position and the final length.
Solution 3
luau
--!strict
local fruits = { "apple", "pear" }
table.insert(fruits, "plum")
table.remove(fruits, 1)
print(fruits[1])
print(fruits[2])
print(#fruits)txt
pear
plum
2After removal, "pear" sits at position 1 and "plum" at position 2.
- Build a nested
teamtable with anameand a two-itemmembersarray. Print the team name, then loop overmemberswithfor k, v in tand print each member.
Solution 4
luau
--!strict
local team = { name = "Falcons", members = { "Maya", "Rio" } }
print(team.name)
for index, member in team.members do
print(index)
print(member)
endtxt
Falcons
1
Maya
2
RioLine 3 loops over the inner array team.members, not the outer table.
Summary
You built arrays with 1-based positions and dictionaries with named keys. You nested tables, measured arrays with #, resized them with table.insert and table.remove, visited entries with for k, v in t, changed values in place, and deleted dictionary keys by assigning nil.
Next: Strings, Numbers, and Nil.