(Original 2019 article) Scripting Basics - Beginner guide for scripting on Roblox

Hello! :smile:
I’m making this guide to help players who are new to scripting learn some basic concepts of scripting and a few dos and donts. This is definitely missing a lot of important information, but I will be updating it.

If you’re brand new you should read The Basics below, but if you know about variables, functions, and data types you should skip to Concepts.

The Basics

Data types

Strings

Strings hold text! They are surrounded by double quotes, ", or single quotes, '. They can also be surrounded with [[ and ]] to make them span across multiple lines!

Tables

Tables are lists which can have named “indexes”. You may have heard of Arrays, Objects, or Dictionaries. Tables are both of these combined.

{"My array", "is cool"} -- I'm like an object but my indexes are numbers in order! I don't skip gaps.
{["My object"] = "is cool"} -- I can have indexes with any value! I can be an array but I might not be one! Just like squares and rectangles.

Booleans

Booleans are true or false. They aren’t much more, but they offer a lot of use in programming. When you compare values in programming languages you’ll get a Boolean!

1 < 3 -- One is less than three, so true
4 == 2 -- Four doesn't equal two, so false
6 > 7 -- 6 is less than 7, not greater than, so false again

Numbers

Numbers! 1, 2, 3, and all the rest.
Numbers can be stored in different ways. Floats can efficiently store non whole numbers. They’re basically scientific notation! Integers are whole numbers. Doubles are another way to store numbers which are similar to floats.

Lua numbers can contain decimals. You can represent them as a fraction through division: 1/5 = 0.2

Variables and functions

Variables are simply a way to store a value. They can hold anything and are one of the most important features in all programming languages. They can be local, meaning they can be used where they are created or global meaning they can be used anywhere!

variable = "My string"
local localVariable = "My other string"

do -- I don't do anything special, but I have my own set of locals! That's called a scope.
	print(abc) -- I can't see the variable yet!
	local abc = 123 -- I only exist inside of the do statement and I can only be used after this line!
	-- Everything past here can see abc!
	print(abc) -- prints 123
end
print(abc) -- you'll see nil when this prints. Nil means no value.

Functions can run the same code multiple times! Functions can even be local!

local function myFunction(a, b, c) -- These are like variables! They're called arguments
	return a, b, c
end

print(myFunction(1, 2, 3)) -- You should see "1 2 3"!

local myFunction2(a, b, ...) -- ... Is like a variable but can only be used here! It represents multiple function arguments
	print(a, b)
	warn(...)
end

myFunction2(1, "b", 2, "d", 3, "f")

Statements

Statements make up code.
There are different types of statements.
For example, the if statement. The if statement executes code, if a condition is true. If statements use Booleans!

if true then
    print("It ran!")
end

if false then
    print("You won't see me because the condition is false!")
end

Remember nil? Nil acts like false! And all values other than false and nil act like true!

if nil then
    print("I won't execute!")
end
if not nil then
    print("Not nil is true! See? "..tostring(not nil))
end
if 2 then
    print("Number!")
end
if {} then
    print("Table!")
end

If statements also have else and elseif clauses.
Think about it like this, if one thing happens do this, otherwise if this (elseif) then do this, otherwise (else) do this

if thing1 then

elseif thing2 then

else

end

There are many statements, like the do statement from earlier that do different things but if is one of the most important statements!

Loops

Loops are super important. They let you select items in an array or dictionary or repeat things a select number of times! They can also repeat forever or until a condition is met.
Prepare for a lot of information!

There are three main types of loops.
While and repeat loops

while myCondition do -- These loops repeat while a condition is true! This condition works the same way as if statement conditions
	-- Stuff
end
repeat -- These loops are like while loops but they repeat *until* a condition is true. They are the opposite of while loops.
	-- Stuff
until myCondition
-- Repeat loops can also be represented in a while loop:
while not myCondition do -- This is exactly the same as the repeat loop above! These loops exist in these two forms just as a personal preference thing. Whichever loop you think makes more sense you can use!
	-- Stuff
end

For loops

-- There are two main types of for loops
-- There are these loops, which "count". You can use them to repeat something any number of times!
for i=1, 10 do -- i is a local! It represents the current "index." It can be named anything you want!
	print(i) -- The index gets printed! You should see the numbers from 1 to 10
end
for i=1, 10, 2 do -- For loops like these also have a third option. This is the "step" option. It represents how much to add to i each loop!
	print(i) -- You should see the odd numbers from 1 to 10! 
	i = i + 100 -- You can also add to i and it won't effect the next loop.
	warn("I added 100 to i! "..i)
end
-- The second main type of for loop are these loops! These are also known as "foreach" loops because they loop for each of every item in an array or dictionary
local tbl = {
	["abc"] = 123,
	[1] = "abc",
	"def" -- This actually has index 2! It's like writing [2] = "def"
	[3] = "I am number 3!", -- That means that you don't need to write [3] here!
	"I am number 4!",
	"I am number 5!",
	nil -- This is nil! Watch out for this later!
	"I am number 6!",
	[{My="table"}] = "I have a special non-string index!",
	[{My="table"}] = "I have a special non-string index too! Notice how I didn't overwrite the previous index! \
		All complex data types (non-strings, non-numbers, non-booleans, non-nil, etc. \
		Tables, Instances, Vector3s, and all others are complex!) are always unique even if their content is the same." -- This string also spans multiple lines! Using \ before you press enter will make sure it stays there similar to a long string. You can also write \n and it will become a new line just like if you press enter!
}
for index, value in pairs(tbl) do -- This loop will loop through table giving you each index and the corresponding value! This condition is always true: tbl[index] == value.
	print(index, "=", value) -- Using commas in print, warn, or error will add a space between each item. I prefer to use commas sometimes because it types faster and is sometimes easier to read.
	-- You should see every index and its value!
end

-- But there are also these loops!
for _, value in ipairs(tbl) do -- If you change the _ to any variable name the value of that variable will be the numeric index. _ has some functionality in loops and function parameters.
	-- It represents "no variable." Setting _ to something will truly create a variable with the "_" name but when used in loops and function parameters it doesn't create a variable.
	-- That means that there's no variable to clean up later which can ever so slightly improve performance and reduce memory usage but it's not something to worry about. This is simply considered a "good practice" even though it doesn't offer much benefit.
	print(value) -- This only prints "array-like" values. "array-like" values have an integer index from 1 to infinity. If you have an integer index set to nil *anywhere* in your table it will stop iterating.
	-- You should see all of the values up to index 5 because there's a gap at index 6 which is nil!
end

-- And finally, function based for loops and next loops:
for index, value in next, tbl do -- The "tbl" value is passed to next as its first argument! Then the arguments that next returned previously are passed after it!

end

local function iteratorFunction(my123Value, lastKey, lastValue, ...) -- This is exactly like the function pairs returns! It isn't represented in lua though so it's faster! It's called by the for loop internally and it gives us all of the values returned previously and any extra values!
	print(my123Value) -- Will always print 123 since we pass it in our loop!
	return next(tbl, lastKey) -- This returns the index and value after lastKey! If lastKey is nil than the first item in the array is returned! These are the values used in the for loop and we can return as many as we want!
end

for index, value in iteratorFunction, 123 do -- This uses the iterator function we created to get an index and a value! It passes 123 as the first argument and then index, value.
	print(index, "=", value)
end

Concepts

These are the basics of Roblox! These are what you need to know to use the documentation on developer.roblox.com

Properties

These are like variables but they exist on an Instance. For example, parts have the Anchored property which can be true or false.
You can think of an Instance just like a table.

Functions

These are actually just like properties! They offer you extra functionality that properties can’t.
For example:

local Destroy = part.Destroy -- This is a function!
Destroy() -- But why can't we call it?
-- Because it's special!
-- It uses a colon (:)!
-- But what does : do?
Destroy(part) -- : gives the function an extra argument!
local tbl = {}
function tbl:func()
	print(self) -- This will print the same I'd!
end 
function tbl.func2(self)
	print(self) -- Will do the same as the above!
end
print(tbl) -- This will print out an id for a table
tbl:func() -- Here's an example
tbl:func2()
tbl.func(tbl)

-- All of them print the same table id!

Events

Events are similar to instances.
They have two functions.
Connect and Wait.
Connect will call a function when the event is “fired”.
For example Instances have a ChildAdded event which is fired whenever an instance is added to it aka “parented” to it.
Wait will wait until the event is fired.

local myEvent = Instance.new("BindableEvent")
myEvent.Event:Connect(print) -- Will call print when we fire it! Event is an Event on the Instance BindableEvent. It's very similar to a property.

myEvent:Fire("abc")

Getting instances

Instances have FindFirstChild, WaitForChild, and GetChildren functions. GetChildren returns an array of instances which are the “children” of the target instance. FindFirstChild looks for an Instance with a given name and returns it. If it doesn’t exist it returns nil! WaitForChild is similar, but it waits for the instance to exist instead.

You should read the documentation pages for them!
The Instance class.
WaitForChild
FindFirstChild
GetChildren

The dos and donts

How should you find information?

Google! Googling your problems is a great place to find information. You can find everything you need on Google including devforum posts and documentation. If you’re looking for something specific though you should search for documentation directly or look on the devforum!

Neatness is important

When writing Roblox scripts I would recommend keeping your code neat. If your code is readable it means you can look back at it in the future! It’s important for you and others to be able to read your code so they can understand what it does and maybe give some tips on what you could do differently! It also gives you opportunity to reflect on your work and see how far you’ve gone.

That means name your variables clearly and indent your code!

Capitalization can give you context!

This isn’t super important but you should keep it in mind! Make sure your capitalization style is consistent. Often times (but not always) you want variables to start with a lower case letter unless it is a class, Instance, Service, or important variable. That lets people know ahead of time what a variable might be used for. It’s by no means the end of the world if your capitalization doesn’t follow that rule as long as it’s understandable and consistent!

Services in Roblox

Usually when using Roblox services people will recommend that you keep services in variables and keep them with the same name. This is generally a good idea because it lets people reading your code know what services you use before hand and it makes editing and reading code code much easier!

Example:

local ServerScriptService = game:GetService("ServerScriptService")

This format allows you to quickly double click on service names and see where they are used. It also lets you easily replace them if you make a mistake. It also helps you keep your code more organized and readable.

It’s okay to copy code - Sometimes!

Copying code from people is great! Trying to understand other people’s code is how most developers learn. It allows you to pick up on new tricks and better formats. Not everyone is perfect so it’s great to learn from people who have learned something you haven’t learned yet. But always make sure you are not using code without permission! Free models are a great place to find code, but be careful when using them in your game because a lot of them contain malicious scripts. And most importantly of all, make sure you never claim someone else’s code as your own!

6 Likes