Skip to content

Instantly share code, notes, and snippets.

@Luracasmus
Last active January 24, 2024 08:00
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Luracasmus/e9ca2417c5dabd80a5c93001f0b4024c to your computer and use it in GitHub Desktop.
Save Luracasmus/e9ca2417c5dabd80a5c93001f0b4024c to your computer and use it in GitHub Desktop.
Luau & Roblox Scripting - An introduction

Luau & Roblox Scripting - An introduction

Variables & local

Similar to how other languages use let, variable, etc. Luau uses the local keyword for creating a new variable, with = being used to give the variable a value

local message = "Hello"
print(message) -- This will print "Hello" in the console/output when ran

As you can see above, -- allows you to make comments in your code, which will be ignored when the script is running

Strings

The "" around "Hello" above also signify that everything between them is a string (text) and not actual code

local message = Hello -- Variable 'Hello' doesn't exist

This would be interpreted as trying to set message to the value of another variable called Hello that doesn't exist

local message = "Hello" -- Do this instead

Modifying (mutating) variables

local a = "Hello"
local b = a -- This will ´copy´ the value of ´a´ into ´b´

a = "Hi" -- This will change the value of ´a´, but not ´b´, as it's a copy

print(a) -- Hi
print(b) -- Hello

Numbers

Most code is mainly oriented around numbers

In Luau, there is only one number type, simply called number, which supports most common math symbols and functions

local two = 1 + 1

local zero = 0.0 * 1.0 / 2.0

local three = two - zero + 1.0

This works because every line within a scope is executed from top to bottom, so the value of two and zero are calculated first, and can be used later when assigning a value to the variable three

Booleans

Booleans are simple true/false values, which can be created by comparing other variables, or by simply typing true or false as a value

local hopefullyTrue = 1 > 0 -- ">" means "more than", and "<" means "less than"
local probablyFalse = 1 == 0 -- "==" means "equals" while "!=" means "doesn't equal"

local definitelyTrue = true
  • > - More than
  • < - Less than
  • == - Equal to
  • ~= - Not equal to
  • >= - More than or equal to
  • <= - Less than or equal to

You can also use and and or to combine booleans

local someBoolean = false
local someOtherBoolean = true

local bothTrue = someBoolean and someOtherBoolean -- false
local oneTrue = someBoolean or someOtherBoolean -- true

not negates/inverts a boolean

local someBoolean = false

local inverse = not someBoolean -- true

Types

Luau has lots of types of variables. These can be strings, numbers or booleans like I mentioned earlier, but also other types such as Instance or even nil, which means that the variable has no value

Type Annotations

In most cases Luau can figure out what type a variable is based on the value you give it, but you can also specify types manually using type annotations

local message: string = "Hello"

local two: number = 1 + 1

This might also give a warning if you accidentally change the type of a variable, depending on your code editor

Nil and option types

In some cases, variables do not have a value. This can be signified by giving a variable the type nil, meaning that it will always be an "empty" variable, or by giving it a type such as number?, meaning that it can be either a number or nil, depending on the situation

To check if a variable has a value, you can use an if statement

local someVariable: number? = nil

if someVariable then
    -- In here, someVariable has the type "number"
    print("someVariable has a value!")
else
    -- In here, someVariable has the type "nil"
    print("someVariable is nil!")
end

You can also use the built-in assert() function

local someVariable: number? = nil
assert(someVariable) -- This will stop the Script if someVariable is nil

-- The Script will continue if someVariable has a value, and its type will be changed to "number"

print("someVariable is has a value!")

Strict Type Checking

In Roblox Scripts, you can add this to the top of the Script to show warnings for cases where you might need to add type annotations or where the type of a variable doesn't match the value you're giving it

--!strict

local message: string = "Hello"

message = 2 -- This is probably not what you want, and Roblox Studio will warn you

Functions & Arguments

If you have a piece of code that you want to run multiple times in more than one place, making it a function can be a good solution

local function addOne(input: number): number
    return input + 1
end

local two: number = addOne(1) -- "two" will get the value that "addOne" returns when supplied with the argument "1"

Functions in Luau work very similar to functions in math. In the code above, input is an argument to the function of type number, meaning that you will need to supply a number to the function every time you use it (called "calling" the function)

The : number after the function shows that the function will always return a variable of type number. In this case, the function always returns the input variable plus 1

Built-in functions

Luau has some built-in functions that are always available

  • print() takes a string as an argument and doesn't return anything
  • assert() takes a boolean, nil or option type and stops the Script if the value is nil or false. If its input is an option type and it's not nil, it will remove the ? from that type (assert(number?) -> number)
  • tostring() takes any type as an argument and returns the value of that "converted" to a string
  • And more...

Functions without return values

local function printTwice(input: string): ()
    print(input)
    print(input)
end

local message: string = "Hello"

printTwice(message) -- This calls the function, and we can't set a variable to its return value because it doens't return anything

-- Hello
-- Hello

: () Means that the function doens't return anything, but is also optional and can be removed entirely if you want

Arguments are also optional, and you can use multiple arguments by separating them with ,

local function something(): ()
    -- Do something that doesn't require arguments
end

local function someOtherThing(input1: number, input2: string): ()
    -- Do something that requires a number and a string
end

something()

someOtherThing(1, "Hello")

Tuples

Tuples are "packages" of different variables that are usually returned by a function

local function getValues(): (number, string)
    return 1, "Hello"
end

local one, message = getValues()

(number, string) is a tuple of a number and a string, which can be used to assign a value to two variables at the same time

Loops

You often run into problems where you have to run a piece of code many times. This can be done using different types of loops

While loops

While loops are similar to if statements, but will repeat their "contained" code until the condition is false or nil

local counter: number = 0

while counter < 10 do
    counter += 1
    print(tostring(counter))
end

print("Done!")

This while loop will count to 10 before continuing to the code below it

For loops

For loops are a bit more advanced than while loops

for counter = 0, 10, 1 do
    print(tostring(counter))
end

print("Done!")

This example does the same as the while loop above

  • counter = 0 creates a new variable that is available only within the for loop
  • 10 is the max value (similar to counter < 10 in the while loop)
  • 1 is the increment for every iteration of the loop (similar to counter += 1)

Tables can be seen as lists or arrays of variables of the same type

local myNumbers: {number} = {1, 2, 3, 4}

local myStrings: {string} = {"Hello", "Hi"}

You can iterate over a table using a for loop

local myNumbers: {number} = {1, 2, 3, 4}

for _, myNumber: number in myNumbers do
    print(tostring(number))
end

This will print all numbers in myNumbers

You can also access specific values of a table

local myNumbers: {number} = {7, 6, 1, 8}

local six: number = myNumbers[2] -- This gets the second value of the table

Dictionaries are tables that use a key (basically a name) for every value. They can also contain values of different types

local person = {
    name = "Jeff",
    age = 48
}

print(person["name"])
print(tostring(person["age"]))

Roblox Classes & Instances (Roblox only, not Luau)

In Roblox, some types can inherit other types. These types are called classes, and can be found in the Explorer window within Roblox Studio

Instance -> PVInstance -> BasePart -> FormFactorPart -> Part

This means that a Part inherits the properties of all other "parent" types, with Instance always being the top "ancestor". So a Part is also an Instance, but not the other way around

Beware that this only applies to things you can see in the Roblox Studio Explorer window

Instances in code

To use and modify Instances in your Scripts you can make a variable point to a specific Instance in your game

local part: Instance? = workspace:FindFirstChild("MyPart")

if part then
    print("MyPart exists!")
else
    print("MyPart is gone :(")
end

FindFirstChild is a method of the Workspace class (inherited from Instance) that checks for an Instance named "MyPart" in workspace, and returns nil if it doesn't exist

Methods are functions that use self as their first argument, and are accessed using : instead of .

Properties

Properties are values that affect different aspects of an Instance, such as appearance or position in the world

You can see all properties in the Properties window in Roblox Studio

local part: Instance? = workspace:FindFirstChild("MyPart")
assert(part and part:IsA("Part")) -- This makes sure that "part" isn't nil and uses the "Instance:IsA" method to check if it's of type "Part"

-- Now that we know that "part" exists and is of type "Part" we can access properties that are specific to the "Part" class

part.Transparency = 1 -- This makes the Part fully transparent by changing it's "Transparency" property

print(part.Name) -- You can read properties as well. This should print "Part"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment