Variables are named values in your scripts that can hold value. If you try to access a variable that wasn't defined yet, you will get the value nil.

print(variable) -- nil

Unlike other languages, Lua isn't strongly typed, and it is instead dynamically typed. This gives you a lot more freedom than strongly typed languages, such as Java, C++ or C. You can assign any value of any type to any variable whether it's defined or not!


Variable Assignment

Data types

Data types are just what the name says, types of data! In Roblox, we have access to multiple data types:

Type Description
Boolean Represents either true or false
Function A function you can call
Nil Nothing, null
Number Used for storing numbers
String Used for storing texts, a string of character Ex: "omg"
Table A group of items
Thread A coroutine
Userdata Values not made in Lua


Normal variables

Normal variables can be accessed from any part of a script (you can't use a variable before you assign it a value tho, then it returns nil), but cannot be shared between scripts. Normal variables should never be used because they are slower than local variables and do not offer any advantage over local variables.[1]

print(pi) -- 3.1415926535898

Local variables

Local variables are scoped and can only be used from inside their scope or as upvalues. You can only have 200 local variables at a time (because Lua has a maximum of 200 registers), but it is almost impossible to ever reach this if you're coding in a normal way.

Local variables can be told apart from global ones because of the word local put before their defined names.

--An example of a local variable
 local pi = math.pi
 print(pi) --3.1415926535898

Normal variables can be used between scopes, while local variables only exist inside the scope. A scope is for example a loop or a function

Foo = "bar" -- Makes a global variable
 function DoStuff()
 local Foo = "not bar"
 function DoOtherStuff()
 Foo = "this is bar"
 DoStuff() -- not bar
 print(Foo) -- bar
 print(Foo) -- this is bar

Global variables

Global variables can be used between scripts. In other words, can you declear a variable in one script and get its value in another script. To be able to make global variables you have to access the global table. _G If you want to make a global variable you just add that value to the global table:

_G["MyVariable"] = "This is the value"

And then you can do this in another script:

print( _G.MyVariable) -- This is the value

You have to make sure that the first script runs first tho, you can do it by adding a "wait()" on the top line of the second script. You can also make global functions.

_G["MyFunction"] = function() print("This is the function") end

And in another script:


More information about how you use tables:

Table fields

Table fields, while they behave differently than normal variables and local variables, are still variables.[2]

Using tables


Tables are groups of fields that can be accessed using the table. To construct a table, start the assignment like normally...

local a =

And then use curly braces to show that it's a table:

local a = {}

To add elements to the table directly in the table constructor, list them in order, like so:

local a = {1,2,3}

To access an item in a table, we use something called an index, which is sort of like a file name on a computer.

To find the variable at a certain index, you use the index operators, [] and the table name, like this:

local tableName = {1,2,3}

Now, that code wouldn't work because you cannot index a table with nil, however you can index it with everything else, like this example:

local tableName = {}
tableName[Workspace] = "Workspace"
 tableName[game] = "game"

Using this method, you could get player chat clients, tools, anything!

For and tables

To iterate through a table, you can use the for loop:

local a = {1,2,3,4,5,6,7,8,9,10}
 for i=1, 10 do

Some output:





However, sometimes, you don't know how large a table is, one method is to go through the table until you hit a nil value:

local a = {2,3,4,2,4,3,4,2,3,43,2,4,3,4,2,3,4,2,3}
 for i=1, math.huge do
 if a[i] == nil then break end

However, this method is very inefficient and could break too early, or not at all, like on this table:

local a = {1,2,3,4,2,5,nil,3,4,2,5}
 for i=1, math.huge do
 if a[i] == nil then break end

To avoid this, we use the length operator, #

local a = {2,3,4,2,5,nil,3,4,2,34,2}
 for i=1, #a do

This skips the manual checking we had to do before, and tells us the length of the table. This could be used for selecting random players, like so:

local PlayerList = game.Players:GetChildren()
 local RandomPlayer = PlayerList[math.random(1,#PlayerList)]

You could also use the length operator to get the number of parts in the top level of the Workspace:


As you might know, the preceding code works because we're getting the length of the returned table, not workspace. Please note, that the length operator doesn't work directly on userdata[roblox objects, instances].

Function variables

Functions are the tables of code, or in other words, groups of code. Functions are the building blocks, and organizers of code the provide use with a way to re-use code over and over without having to actually type it all in. Functions are also used for recursively getting children, setting properties, calculating things and other fun stuff. Here is an example of a function:

function a()

Since functions can compute things, why don't we make a function that outputs a value?

local b = 0
 function a()
 b = b + 1

Hmm... This function could be better, let's use the return keyword!

local b = 0
 function a()
 b = b + 1
 return b
 print(a(), a(), a(), a())

The reason that we added to our variable b first is that once you return from a function, your function stops working.

function a()
 if true then return end
 print("This will never be executed.")

In the code above, function a returns before we get to the call to function print. This means that you won't see the print unless you remove the return.

Something else you should know about the return keyword is that you can only place it before an end keyword. Placing a return in the middle of your code is only allowed if you put the return inside of a statement[something that uses an end].

function a()
 do return end
 print("You will not see this. The return is inside a do statement.")
 --- And a broken example
 function a()
 print("This code will error.")

As you can see, the second example fails to function because we have a return in the middle. This not only makes the code harder to read, but it also causes an error.


  1. Roberto Ierusalimschy Lua Performance Tips
  2. R. Ierusalimschy, L. H. de Figueiredo, W. Celes; Lua 5.1 Reference Manual,, August 2006; ISBN 85-903798-3-3
Community content is available under CC-BY-SA unless otherwise noted.