The Output is a window where several things are shown: Errors, notifications (or warnings), and things printed out by the print()
function. The Output window can be enabled in Studio, by going to View > Output Window.
Debounce is a term that is often associated with the act of adding a cool-down time to a function so it doesn't get called rapidly. This can be especially helpful when used in conjunction with the Touched event of parts. Oftentimes, this is accomplished by setting a variable to true at the beginning of a function, and setting it to false again at the end. Then, at the very beginning of the function, if the variable is already true, then you use the 'return' keyword, effectively ending the function.
A global variable can mean two things in Lua:
A variable that is created in a script and that can be accessed in every scope in the same script (i.e., is not local
), or a variable that is created in a script and that can be used in other scripts.
In general, global variables (of both kinds) should be avoided. They make code complicated to follow since they can be affected by many places at once.
In the first case you just define a variable without the local
keyword.
For example, x = 9
y = 5
blah = "accessed in this script"
are definitions of global variables.
In the second case, you use the global _G
table.
For example, _G.x = 8
, _G.word = "hax"
, _G["my name"] = "Myrco"
are definitions of names on the global table.
They are accessed the same way, and every Script/LocalScript on the same client/server share the _G
table:
print(_G["my name"])
print(_G.x * 2)
An Integer is a positive or negative numerical value that cannot contain a decimal. Examples: 1, -2, 5, 87
A value that represents the absence of a useful value; valueless.
nil
frequently marks the non-existence of a value being searched for. For example, :FindFirstChild(name)
returns nil
if no object was found with the given name
.
nil
and false
are the only two "falsey" values In Lua (values that fail conditions in if
, while
, or
, and
, and not
)
A piece of code that can be run multiple times, or called when a certain event happens in the game. See [[Functions]]
A value that is blocks of raw memory in C. Basically is where C data is stored in Lua variables and cannot be created/modified through Lua, but only through C.
An array or list is a table containing an ordered sequence of values. All keys/indices in an array are positive integers. See [[Table]].
A script is an object which contains code that is executed when run. Make sure that the script is un-disabled, else it won't run.
Is also an object like the Script object, except it can manipulate client things like the client's ((local )player's) Camera. It also has several other features over normal Scripts, for example for able to use the LocalPlayer property in the Players service - which will return the host of the script. The LocalScript should always be a child or descendant (child of a child, or even lower in the hierarchy) of a Player (object). It's recommended to use LocalScripts in combination with Guis and Tools with their extra abilities.
A Boolean (commonly known as "Bool") is a data type which has the value of either true or false.
Lua is a scripting language which is used in ROBLOX. ROBLOX-flavored Lua, referred to as "RBX.Lua" has several additions to it from the standard Lua. Do not confuse this with being a different programming language, it is not.
GUI (pronounced "gooey") is an acronym for "Graphical User Interface." Conceptualized by Xerox in the 1970's, GUIs allow simple user-interaction with computers through various graphics.
The local
keyword is often used when defining variables, but can also be used with functions.
The local
keyword restricts a name's usage from where it was defined until where the current block ends (at an end
or until
).
local
variables are slightly faster and easier to reason about. ROBLOX's Script Analysis can give more helpful hints with local
variables. local
variables are necessary for allowing functions to be recursive.
You should define most or all of your variables as local
.
Scopes are started after the keywords do
,then
, else
, repeat
and function
and are ended with the keywords end
or until
.
The scope of a name is the places that a name has meaning.
For local
variables, scopes begin at definition and end at the end of the block the local was defined in (at the corresponding end
or until
keyword).
Not-local variables have the scope of the entire script.
Function parameters have the scope of the function they are defined in. ...
cannot be used in functions defined with another function.
Variables defined in a then
or else
are not "visible" after the if
end
s.
Variables defined in a repeat
loop can be used in the condition of the until
but cannot be used after the loop.
Local variables cannot be used in the statement that defines them; this can pose a problem for connections and other anonymous functions:
local con = part.Touched:connect(function() con:disconnect() -- NO! `con`'s scope does not include its definition end)
You have to break this up into two statements:
local con con = part.Touched:connect(function() con:disconnect() end)
Because blocks of statements mark the possible boundaries of scopes, they are often referred to as scopes. Every script has a global scope for all non-local variables.
Each block gets one level of indentation. See Indentation.
The do keyword can be used for multiple things depending on how it's used. When it's used on its own then it will create a scope. The scope is ended with the end keyword. It can also be used in combination with the for or while keywords to create a loop. Search the while and/or for keywords in the glossary for more information about the loops.
The until
keyword closes a repeat
block. It's followed by the condition (written on one line, together) that the repeat
loop needs to meet before it can stop executing. Everything in-between the repeat and until keywords is what is executed in the loop.
For example,
repeat useUmbrella() until sunshine()
A table holds data together as a set of key-value pairs.
Tables are used in two main ways. Lists or arrays are collections of things in an order. These use 1
, 2
, 3
, ... as the keys.
list = {"hi", "word", 2380.0, 18, 19}
Dictionaries or maps are used to "map" the keys "to" the values. These are inherently not ordered -- the order the key/values are written in the literal is not significant.
dictionary = { alpha = "a", beta = "b", gamma = "c", ["Delta"] = "d", }
Table literals are marked by curly braces {}
and each key & value is separated by a comma or semicolon. Tables can hold any type of value (except nil
) including booleans, strings, numbers, ROBLOX objects, and other tables.
Arrays always have consecutive numerical keys whereas tables in general have other kinds of keys. Some built-in functions and operators, like #t
and table.insert
, and ipairs
assume that their arguments are arrays (and not general tables)
A String is a value that is made up of a sequence of characters. String literals, strings defined literally in the program, are usually formed with single or double quotes: "cat"
or 'cat'
.
Strings are the usual way of representing text.
A character in Lua is one byte, ranging from 0 to 255. Usually, one character represents one symbol. Thus "cute dog"
has 8 characters (4 for cute, 1 for the space, 3 for dog).
string.lower
and string.upper
use the ASCII character encoding, which is what ROBLOX (usually) uses. Similarly, patterns like %w
, %a
, and %d
use ASCII character encoding.
A number is any numerical value that can have mathematical operation performed on it like addition +
, subtraction and negation -
, multiplication *
, (real) division/
, remainder after division ('modulo') %
, and exponentiation ^
.
Numbers can be positive or negative and can be include decimal points: -5
-5.
-1
-.12
-0.12
0
0.1
.12
0.12
5.82
6
Numbers can be written as exponential notation, too: 5e3
is 5000
.
ROBLOX Lua uses "double precision floating point" values to represent numbers. This means there are the special values -0
, negative and positive infinity, and "not a number" (NaN) or "indefinite".
A scripting environment surrounds you with pre-made functions or values in general. An example of something pre-made in an environment is the print function.
A variable that is created in a scope and that can only be accesed in the same or lower scopes. Local variables are created like normal variables, but then with the local keyword added infront of them: local x = 9, local string = "test". (Search "local (keyword)" in the glossary for more information)
A loop is a block of code ran multiple times until the condition is reached or until the end is reached. There are 4 kind of loops: while
loops, generic and numeric for
loops and repeat
loops.
A method is a function that is called on an object. A method is usually associated with a particular type of object. Methods use the :
instead of the .
to access them.
Calling object:method(parameter)
is the same as doing object.method(object, parameter)
. This lets many objects "share" the same function value, but the function knows which object is being used.
Methods can be defined with the following syntax:
function object:method(parameter) -- (body) end
This is equivalent to the following standard function definition:
function object.method(self, parameter) -- (body) end
Note the implicit self
parameter that method declarations receive.
A statement is an instruction to tell the computer to do a single thing.
Simple statements are
a = b
)local x = y
or function f() end
)print(5)
)return
statements (e.g., return
or return 5
) break
statements.Compound statements include if
statements, repeat
...until
statements, and while
...do
statements. These include blocks of code, which many statements grouped between two keywords (e.g., between do
and end
)
Syntax is the arrangement of words, characters and symbols that form correct Lua code. It's like grammar for coding languages.
A Variable is a name that holds or stores a value. You can declare a variable by typing the name, followed by an equal sign (=), followed by the value. You can use the characters a-z (capital and lowercase), 0-9 and _ (and combinations of those) for variables, but they cannot start with numbers. Examples: x = 9, variableName = 80, Variable_1 = 80 + 5, __Myrco__5_9 = "hax".
From PIL:
A coroutine is similar to a thread (in the sense of multithreading): a line of execution, with its own stack, its own local variables, and its own instruction pointer; but sharing global variables and mostly anything else with other coroutines.
Two different coroutines can be at completely different places in a Script at the same time, taking turns executing statements. They are very similar to generators in other languages.
A different coroutine can be started using coroutine.resume( othercoroutine )
. The current coroutine can be stopped (returning to the one that last called resume
) using coroutine.yield()
.
ROBLOX uses coroutines and a scheduler hidden from the programmer to make the appearance of many different threads executing at the same time. In fact, only one coroutine executes at a time. The scheduler simply quickly switches between them at calls to wait
and the ends of events.
A value that is a number, positive or negative, with decimals. The difference between a double and float is that doubles have more decimals and rounding precision than floats. Example: 1, -9, 2.66, 3.14, -50.
Events are a type of class. They are fired when something takes place which is usually used for user-defined functions.
The end
keyword is used to end (or close) the block of statements created by the function
, then
, else
, and do
keywords.
This means the end
keyword is used to "group" statements in blocks that are controlled by if
, while
, for
, and function
s.
end
ends all blocks except those made by repeat
(which are closed with the until
keyword).
The keywords and
and or
are logical operators that are used to combine Boolean expressions.
The or
keyword will return true if either (or both) of the comparisons are true. e.g.: if x < 0 or 0 < x then print("x isn't zero") end
The and
keyword will return true if both the comparisons return true. e.g.: if -5 < x and x < 5 then print("x is between -5 and 5") end
The not
operator is the other Boolean operator in Lua.
Both keywords can be used together to make complicated expressions:
if x == 0 or x > 10 and x < 20 then print("x equals either 0 or something between 10 to 20.") end
and
has higher precedence than or
.
Both operators "short circuit." true or print(5)
has different behavior than print(5) or true
.
The while
keyword creates a loop and must be used in combination with the do keyword.
Between the while
and do
keywords is the condition that the loop must meet to execute. The loop is ended with the end keyword. Everything in between the do
and end
keywords is what is executed in the loop.
The repeat
loop is similar to the while
loop. while
checks the condition before executing the first time, and stops when the condition is false
.
while isRaining() do useUmbrella() end
The repeat
keyword creates a loop.
The loop is closed with the until
keyword. Everything in between the two keywords is executed until the condition is true.
The condition is written after the until keyword.
The while
loop is very similar. repeat
executes the code before checking the condition. The repeat
loop stops when the condition is true.
repeat
loops are rarely used.
The for
keyword creates a loop in combination with the do
keyword.
for
loops execute a block of code "for each" value you asked for.
There are two kinds of for
loops.
The body of the for
loop is ended with the end
keyword.
The numeric for
loop over a certain range of numbers. It executes the code for each number in a range from low to high (inclusive) by stepping a certain amount (default positive 1)
They look like this:
for variable = start, stop, step do bodyHere() end -- OR, with `step` omitted (step = 1) for variable = low, high do bodyHere() end
for x = 1, 10 do
counts x
up from 1
, 2
, ..., 9
, 10
.
for x = 1, 10, 3 do
counts x
up by 3s from 1
, 4
, 7
, 10
.
for x = 10, 1, -1 do
counts x
down from 10
, 9
, ..., 2
, 1
.
for x = 10, 1 do
does nothing, because 10 is already bigger than 1.
The generic for
loop uses an iterator to produce values from an object. Lua has built in the iterators pairs
(which iterates over dictionaries) and ipairs
(which iterators over lists).
They look like this:
for variables in iterator do
For example, to print everything in the math
table, we can use pairs
:
for key, value in pairs(math) do -- math[key] == value print(key, value) end
This will give output like deg function: 00CBBB28
and pi 3.1415926535898
.
The not
keyword flips a boolean value. true
becomes false
and false
becomes true
.
Like the other boolean operations, not
works on other data types. not
treats all values except false
and nil
as true
. not
treats nil
just like false
.
Thus not 5
is false
and not nil
is true
.
The keywords 'if' and 'then' are used to check if a statement is true or not. This pair of keywords, better known as a conditional statement, is used frequently by scripters. Between the words 'if' and 'then' would be placed a conditional which is checked with a double equal sign. A double equal sign is used for checking a value rather than setting one. Conditional statements can be used to check anything from the Name of an object to the Value of a player's leaderstat. if 1 == 1 then
would cause any code between 'then' and the end of the scope to execute since 1 is equal to 1.
The break
keyword stops the execution of a loop, jumping to immediately after and outside the loop. It "breaks" the loop.
The return
keyword stops the execution of a function and states what value or values (if any) that the function should result in.
Ex:
function test() return "Hi" -- The value it returns end print(test()) -- Will print Hi
These two keywords represent the two boolean values: true (yes, success, continue) and false (no, failure)
nil
and false
are the only two values that "fail" a condition in if
, while
, and
, or
, and not
.
The function
keyword is used to define functions:
function myfun(parameters) -- body statements here print(parameters) end -- end of function body
After the keyword you write the function name, and the parenthesis with parameters. The function's body continues until the corresponding end
keyword. The body in between the parameters and the function's end
are the statements that will be executed when the function is called.
A function definition without any name makes an anonymous function that might be saved to a variable or passed to a function: local blah = function(x) return x * x end
Keywords are words which are coloured blue and 'tell' the compiler that a specific piece of code is following after it, a specific task needs to be done or to express a certain value. All the keywords are repeat, while, for, do, until, function, if, then, local, and, end, or, break, return, else, elseif, nil, true, false and not. You can search every keyword in the glossary to get an description of them.
A library is a table of functions that is predefined and added to the script before code is executed. These are done by ROBLOX before anything in the script runs, so you may safely assume that they are present.
Combining or joining two or more strings to form a single string by putting them next to each other is called concatenation. Lua can concatenate two strings with the ..
operator.
The table.concat
function concatenates all of the strings in a table into one long string, optionally separated by some other string.
Indentation is when you add (white)space to your code to make it readable.
Each block of statements (statements grouped between do
/then
/else
/repeat
and end
/until
) should be indented one level using the tab key on your keyboard.
This lets you use the left line of the code to see which statements are executed together. Statements in the uninterrupted vertical line are executed in order together.
Large tables are also often tabbed, with the contents of the table being tabbed one more level than the outside curly braces.
-- Correctly indented code: function hello(name) if tick() % 24*60*60 < 12*60*60 then print("Good morning, ", name) else print("Good evening", name) end end local names = { "BlueTaslem", "evaera", } for i = 1, #names do if math.cos(i) > 0 then hello( names[i] ) end end
Increase the indent once after a line that "opens" a block with then
, do
, repeat
, (
, {
, or function
.
Decrease the indent once after a line that "closes" a block with end
, until
, )
, or }
.
A base class for in game objects. Any ROBLOX object (Part, SpawnLocation, Model, Script, Sparkles, ForceField, BodyPosition) is an Instance. (This does not include things like CFrame, BrickColor, UDim2)
Delimiting is separating a list of values by some obvious marker, most commonly referred to as a "delimiting character".
In Lua, values in tables are delimited by ;
or ,
.
Function arguments are delimited by ,
.
A content ID on ROBLOX is anything that isn't built into the game, such as a decal ID or shirt ID.
A parameter is a variable that takes on the value of an argument that is passed into a function.
Object belonging to a parent. In hierarchical terms, these objects will be inside another object.
A metatable in Lua is a special kind of table which can be attached to a regular table to extend its abilities and flexibility. A metatable contains named functions, called metamethods, which are called when something specific happens concerning the table. You can use this to change how a table works dramatically.
A metamethod is a function which resides inside of a metatable. Metamethods have specific names and are called when something happens to a table. An example of some useful metamethods are __index, __newindex, and __call. They allow a programmer to override the default behavior of things like + or *, or calling or setting an index on the value.
Data Stores are the newest way to save information within a game. Data Stores are accessible throughout a universe, have a very high limit of data units and can save any value in Roblox including, but not limited to strings, numbers, integers, and booleans. Use DataStoreService to access Data Stores.
A Universe is a set of places saved under a single game. Players can teleport back and forth between places and Data Stores can be accessed and shared by all of these places. The main place has to remain active or else the Universe cannot be accessed. The other places that make up the Universe do not have to be active but will require players to be teleported to each place in order for the place to be accessible. A Universe is also known as a Game.
The keywords 'else' and 'elseif' are used along with a conditional statement(see if + then) to give more options for the statement. Rather than multiple conditional statements to give the script different options of what to do in certain cases, you can use 'else' or 'elseif' to give it more options in a single conditional statement. 'Else' would execute if all previous 'elseif' statements and the original 'if' statement were all false. 'Elseif' allows you type another conditional, followed by 'then' which would execute if it were true. 'Else' and 'elseif' can both be used within the same conditional statement and 'elseif' can be used multiple times.
Dictionaries are extensions of arrays/tables and allow you to set a value to a specific key. This can come in useful when storing information in a Data Store. A key can be set to any type of value such as a string, int, boolean, etc. A dictionary can be indexed by typing the name of the dictionary, followed by a set of square brackets, with the key that is to be looked at inside the brackets. The value can be read or written to with this method, indexing. In addition, dictionaries can be iterated through like normal tables.
The print function is used to add a message to the Output. Whatever is given to the function will printed. Every type of value can be printed; Lua uses the tostring
function to print numbers, booleans, BrickColors, tables, etc. If more than one value is given, they will be shown separated by tabs in the Output.
Any variable, table or function with '_G' in front of is global. This variable, table or function can be used, called or changed from any script in the game. LocalScripts and Server Scripts cannot share data with '_G', a value object or ModuleScript must be used for this.
The functions tonumber()
and tostring()
convert objects to numbers and strings (text).
Lua automatically calls tostring
on all of the parameters to the print
function.
The __tostring
metamethod lets tables customize the behavior of tostring
on the table.
ModuleScripts are script-like objects that returns a value of any type (table, object, boolean, function, etc.). The code in a ModuleScript can be run by using the require
function on the ModuleScript object. The code is only executed the first time the ModuleScript is require
d; the value returned the first time is remembered for later calls of require
. ModuleScripts are executed on the server/client that called require
.
Lerp, short for linear interpolation, is the process of transforming one piece of data into another in a linear fashion. Usually a percentage through the transition is given, in which 0 is the initial position, 0.5 is half way between the initial and end, and 1 is the end position.
A RemoteEvent is typically to communicate between the server and client, sharing information. When firing a RemoveEvent from the client to the server, the first parameter of OnServerEvent
must be the player.
-- Client game.ReplicatedStorage.RemoteEvent:FireServer("Pumpkin") --Server game.ReplicatedStorage.RemoveEvent.OnServerEvent:connect(function(plr, msg) print(plr.." has sent "..msg) end)
As usual with any other function, you may pass any type of value through a RemoteEvent, for the client to read, or vice versa.
Filtering Enabled is a setting in Workspace that makes the line between the client and the server more heavily defined. When enabled the setting will prevent the client from replicating changes to the server. However the server will not be prevented from making changes to the client. This means the player's Camera, PlayerGui, or other client made objects may only be modified by a LocalScript. In order for client to server communication the prefered tools to use would be Remote Events and Remote Functions.
RemoteFunctions are similar to RemoteEvents in that server scripts can invoke functions in local scripts and vice-versa. The primary difference is that RemoteFunctions allow a value to be returned after the function call, which allows for communication back to the server or client.
Ex:
-- Inside Server Script local myRemoteFunction = Instance.new("RemoteFunction") myRemoteFunction.Parent = game.Workspace myRemoteFunction.Name = "MyRemoteFunction" function myRemoteFunction.OnServerInvoke() print("prints on the server") return "prints on the client" end
--Client local message = game.Workspace.MyRemoteFunction:InvokeServer() print(message) -- Will print "prints on the client"
loadstring takes the string provided and creates a Lua function with that as the body.
This lets Lua scripts generate and run new code on the fly. This is difficult to reason about, and is very dangerous, since it is easy to make mistakes that would allow players to take over your game by abusing the power of loadstring
. ROBLOX disables loadstring
by default. Checking LoadStringEnabled in the ServerScriptService will allow server scripts to use loadstring
, but will disable some features that communicate with ROBLOX.
To use loadstring
you must set LoadStringEnabled in Workspace set to true, and execute the code in a Server Script.
loadstring([[print("Hello World!")]])()
You are discouraged from using loadstring
for any purpose in your games -- it is not necessary for games that don't explicitly want players to be able to execute arbitrary Lua code (including that could kick others or kill the server)
wait is a function that yields the current thread for a given number of seconds. If the time is not specified (or a time shorter than the default is specified), a small number is used as the default.
wait
returns the actual amount of time that was spent, as well as the current place time.
local elapsed = wait() -- $100/second increase: money = money + elapsed * 100
:wait() is also a method on ROBLOX events. The current thread yields until the event happens next. The method returns the values that the event gives.
local firstPlayer = game.Players.PlayerAdded:wait()
A tuple is a sequence of comma separated values. They can be used in several places in Lua.
In Lua, an assignment may affect multiple variables at once. The right side is a tuple of values that is evaluated before modifying any of the variables on the left.
alpha, beta = 1, 2
Functions may return multiple values:
function f() return 3, 4 end
You can capture these in a multiple-assignment:
gamma, delta = f() -- same as: -- gamma, delta = 3, 4
Multiple results from a function can also be used to pass parameters to another function:
print( f() ) -- same as -- print(3, 4)
The special ...
function argument can capture all of the arguments in a function as a tuple. This lets functions take in any number of arguments.
-- a recursive definition of "sum" using `...` function sum(first, ...) if first then return first + sum(...) else return first end end sum(1, 2, 3, 4, 5) -- 1 + sum(2, 3, 4, 5) -- 1 + 2 + sum(3, 4, 5) -- etc
Just like function returns and ...
can "spread" arguments into functions, they can also spread values into lists:
list = {f()} -- same as -- list = {3, 4}
You can also use ...
with {}
to make a list of all of the parameters to a function:
function sum(...) local t = {...} local s = 0 for i = 1, #t do s = s + t[i] end return s end