Tutorials•November 8, 2026•8 min read

Roblox Tables: Arrays, Dictionaries, Loops, and Copies

Learn Roblox Luau tables with a complete Output exercise. Compare arrays and dictionaries, insert and remove values, choose loops, and understand shallow copies.

Roblox Luau tables hold related values behind keys. Use an array-style table when order matters, such as a route of checkpoint names. Use dictionary-style keys when each value has a named role, such as a round’s configuration. The important design choice is how callers will find and update the data.

An ordered checkpoint array is compared with named configuration keys in a Luau table
Original data-layout diagram for the practice script, not a screenshot of a running game.

Choose an ordered list or named keys

Roblox’s tables guide covers arrays and dictionaries, including one-based array indexing. The first ordinary array entry is at index 1. A dictionary lets you choose meaningful keys instead of relying on a position’s meaning.

Two table designs for two questions
DesignExample lookupQuestion it answers
Ordered routeroute[2]What is the second checkpoint?
Named settingssettings.enabledIs this configuration enabled?
Dynamic named keysettings[key]Which setting does this variable identify?

Write down the lookup your consumer needs before building a large table. A position is useful for an ordered route. A stable name is often clearer for a configuration value that should not change meaning when another field is added.

Run a complete list, dictionary, and reference exercise

Insert a regular Script in ServerScriptService in a practice place. Open Output and run the following code. It changes local tables and prints results; it does not modify actual checkpoint objects, players, or saved progress.

local route = {"Start", "Bridge", "Finish"}
table.insert(route, 2, "Garden")
local removed = table.remove(route, 3)
print("Removed:", removed)
print("Route length:", #route)
for index, name in ipairs(route) do
    print(index, name)
end

local settings = {
    roundName = "Garden Run",
    enabled = false,
}
print("Enabled before:", settings.enabled)
settings.enabled = true
settings.note = "Practice only"
settings.note = nil
local entryCount = 0
for _ in pairs(settings) do
    entryCount += 1
end
print("Enabled after:", settings.enabled)
print("Note removed:", settings.note == nil)
print("Setting entries:", entryCount)

local alias = route
alias[2] = "Tower"
print("Original route changed:", route[2])

local original = {theme = {name = "Blue"}}
local shallow = table.clone(original)
shallow.theme.name = "Green"
print("Shared nested value:", original.theme.name)
shallow.theme = {name = "Orange"}
print("Original nested value remains:", original.theme.name)

The intended result removes Bridge, reports route length 3, and lists Start, Garden, Finish at indices 1 through 3. The settings section changes enabled from false to true, confirms note was removed, and counts two remaining entries.

The reference examples then show Tower through the original route variable, Green through the original nested table, and Green again after the clone receives a replacement nested table. These are predicted values from the code, not captured Studio output. The example has been documentation-reviewed but has not been executed here inside Studio.

Insert and remove without losing the intended order

In the example, inserting Garden at index 2 shifts the following route entries. Removing index 3 then removes Bridge and closes that position. Trace the indices after each operation rather than assuming an object’s old position remains its identity.

A checkpoint name and its current array position are different things. If another system needs a stable identifier, do not silently use the position as that identifier while allowing the list to be reordered. Decide whether consumers should follow the current sequence or retain a particular checkpoint identity.

For a compact list, use intentional array operations rather than deleting a middle entry with nil. A hole changes what a contiguous sequence means and can make a loop or length-based operation do something different from the list you imagined.

Use the right loop for the data shape

The Luau standard library documents ipairs as sequential numeric traversal that stops at the first nil. It is useful for the compact route in this exercise. pairs visits entries without promising the named-key order you might expect from their written appearance.

That is why the dictionary loop counts entries without printing an exact expected key sequence. If a UI needs settings in a chosen order, represent that order deliberately instead of relying on whichever key is visited first.

Modern Luau also supports generalized table iteration, as shown in the Roblox guide. Read unfamiliar examples by checking their actual table shape and ordering requirements rather than assuming every for loop describes an ordered array.

Do not use array length as a dictionary entry count

The route is a compact sequence, so #route is useful here. The settings table has named keys, and this exercise counts them explicitly with a loop. Keep the meaning of “length” tied to your data design rather than treating every table as a numbered list.

For a mixed table, separate questions that may otherwise become confused: how many ordered items are in the sequence, and how many keyed entries exist overall? A clearer representation may be two separate tables instead of one structure with several unrelated responsibilities.

False is stored data; nil removes an entry

The settings table begins with an explicit false value. That is still a configuration entry. The note assignment to nil removes the note entry instead. Check whether you need “disabled” and “not configured” to mean different things.

For example, a defaulting rule that treats every false value as missing can accidentally override an intentional choice. Use explicit checks when the distinction matters. The Boolean guide develops that idea with small conditions you can inspect.

Assignment shares a reference; cloning is shallow

Assigning route to alias does not create a separate route. The later write through alias appears when reading route. The library’s table.clone operation makes a shallow copy: the outer table is copied, while its nested table references still identify the same nested objects.

The final exercise makes that visible in two steps. Changing shallow.theme.name changes the shared nested object. Replacing shallow.theme changes an entry on the cloned outer table, so it leaves original.theme pointing at the earlier nested table.

Do not call this an independent deep copy. If your feature needs one, define the supported value types, nested structure, and handling of shared references before choosing a copying strategy. A small flat configuration may be easier to reason about than a deeply nested structure.

Keep in-memory tables separate from saved or replicated data

A local table in this exercise is temporary program state. It is not automatically an object in Explorer, a shared server/client table, or persistent player progress. Decide which lifetime and communication boundary a feature actually needs.

For reusable APIs and constructor-created instances, continue with the ModuleScript guide. For values attached to Instances, use the attributes exercise. For a controller finding several objects, see CollectionService. For safely selecting an array entry, continue with the math.random and random-choice guide. Documentation checked November 8, 2026.

Frequently Asked Questions

Do Roblox arrays start at zero or one?▾

Ordinary Luau array sequences begin at index 1. The exercise uses route[1] as its first checkpoint.

Does assigning a table to another variable copy it?▾

No. The variables refer to the same table. A write through the alias can be read through the original variable.

Does table.clone make independent nested tables?▾

No. It makes a shallow copy of the outer table. Nested table references remain shared until an entry is deliberately replaced or a suitable copying strategy is used.

Can I rely on pairs to display dictionary fields in a chosen order?▾

Do not rely on that traversal for a chosen display order. Represent the order explicitly when it matters.

Ready to build your Roblox game?

Create, edit, preview, and export your game for free. No credit card required.

Try Obby — 100% Free →