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 always equal nil! _ 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!

46 Likes

This scripting basics tutorial is great; it seems pretty easy to follow, and it’s way better than some tutorials I’ve seen. From what I can tell, all the ideas there are right, but some of your terminology is off. I’m not trying to say this post is bad, but using the official terms would make it even better.

When I think “a way to run code,” I think of functions. do is just a way to enter a new scope and isn’t used for much on its own.

Also, variables can contain more than you listed: they can have numbers, tables, strings, booleans, userdata, functions, threads(?) or nil. local function x() is just syntactic sugar for local x = function(). I feel like it’s worth mentioning all the types a variable can be, although threads/coroutines are probably not the best beginner topic.

Variables are a name you assign a value to, like x = 3. When you call a function with a specific value, that value is an argument being passed as a parameter to that function. This is easy to get confused on, which is why there’s (luckily) a tutorial on it. On a related note, although this is mostly nitpicking at this point, when you use ... as a parameter it has a specific name. It’s called varargs or variadic arguments. It represents that the function can be called with a variable number of arguments.

... itself is a tuple, which is how you refer to multiple arguments at once.

4 Likes

I do agree to an extent that I may not be using terminology accurately. I just want to explain it in a way that’s easy for anyone to understand rather than throwing too many terms at people. I’ll adjust some of the phrasing in my post though just to make sure thing are a bit clearer.

1 Like

Yeah, that makes sense. Since you link to the developer hub, I’m sure people can figure out the terms anyway. I was mostly worried that the wording might make it seem confusing to beginners - like if variables were both parameters and what they actually are.

Yeah I can understand that. I adjusted the wording a bit. I think it’s more clear now and addresses the terms a little better.

I also added some new sections. (Mainly about finding instances)

2 Likes

No. It’s actually syntactic sugar for local x; x = function().

They’re still variables. You can assign values to parameters, and internally Lua treats them exactly the same as a local variable.

1 Like

I like this short tutorial however:

Indeeed they’re numbers yet they have 2 types which are integers (whole numbers) and floats/doubles (numbers which have a decimal point). The script will read these as 2 different types so you do need to give the correct one.

1 Like

If i was a beginner at programming, I would want to be taught the correct terminology rather than taught the wrong terminology… who really cares about the difficulty…

1 Like

If it’s simplified, it creates an easier entry point. Once you understand the concepts in a way easier for you, then you can learn the proper terminology to use when discussing or presenting your work. This guide is meant for people who have no knowledge, not those who have the knowledge.

1 Like

But you gain knowledge by learning the correct information not the incorrect information… learning the proper terminology is basically the same difficulty level as learning the incorrect terminology except you are actually learning something in one situation.

1 Like

Lua (at least this version and predecessors) only has a single number type. double is used for all native numbers.

5 Likes

I call them parameters.

DISCLAIMER: I’m in no position to speak seeing as I haven’t even attempted to make a scripting tutorial (for Lua) before, so just take what I say with a pinch of salt.

Whilst simplification is good and all, over-simplification isn’t the best either.

Personally, if I saw that when I was a beginner programmer (which was way before I even learnt decimals and fractions where a thing), I would assume that it would be limited to integers and would be at a stump whenever I needed decimals.

You missed off a really important part to data types, being booleans. >:(

For variables, mentioning the difference between constants & variables, as well as the _G. variable type (never used this before, makes variable usable across multiple script) could be helpful, as well as that the variable types used in your snippets are all limited to the script that they were initialised in. Local variables also initialise faster, I believe (correct me if I’m wrong, can easily be tested).

The positioning is a bit hectic, I frowned after seeing functions coming up twice - though you could say the same for this post.

If I were to go about an order (this is all me, ya’ll can ignore) for something like this:

  • I’d first address the different data types (strings, integers, booleans etc) and how Lua is different so certain other languages were both integers and floats/doubles/decimal are all treated as numbers.
  • Variables & Constants. Differences, how Lua doesn’t require the type of variable (nor the data type) of a variable to be called along with it. Different types of variables and uses.
  • Functions & Procedures - different use cases etc.
  • The three types of “statements” (maybe more, my programming teacher probably lied to us) - being sequence (i.e. “normal” code), iteration (i.e. loops etc) and selection (i.e. if statements - I call them conditionals). Uses, different types of the different types (i.e. for iteration, while loops, repeat … until loops, etc)
  • Debugging - Good idea to add that

Other stuff :smiley:

Though, good job with the guide…

Nice last paragraph
3 Likes

The first thing I learnt when I was learning to script wasn’t functions, nor variables, nor anything else.

It was learning the correct terminology, specifically the word:

Boolean

(Which took me 3 years to memorise)

And yes, I still have crap memory.

1 Like

This is just a table set on a global variable, not a variable type. It doesn’t really have a place in a beginner tutorial.

3 Likes

Thank you for all of the feedback! I’ll add some more information on the numbers bit, and add information about booleans (seriously don’t know how I missed those haha). I was planning on getting to statements, I didn’t quite have time last night to formalize those.

However, in terms of other programming languages this is more meant to be a guide to Roblox lua specifically rather than a full on guide to programming. My biggest reason for making this is simply I see a lot of confusion among new scripters. I want to address and explain some of the topics that aren’t always addressed so frequently in tutorials due to their main focus being programming rather than specifically Roblox.

1 Like

Yes… totally know what that means. Never used it before so no clue how it works, just assumed it was a variable type.

My version of logic dictates (from what you said) that a _G. “variable” is just a global variable that’s added to a table shared between scripts? Correct or incorrect inference?

1 Like

Wow, what Lua tutorials have you seen? Would love some links or site names because whenever I ever tried to check Lua tutorials, they’d always use Roblox Studio for it (unless it’s the Lua documentation site thing).

1 Like

Thank you for this great tutorial. This will massively benefit me. Not because I am learning to code, but because I can send a link to this in response to anyone asking me how to learn to code or how I learnt the basics.

1 Like

You can learn anyway that works for you, everyone is different. I’m simply stating that making it easy to understand is the point of this post. I learned how to use many things in scripting without even knowing what those things were called.

1 Like

Again this is an entry point topic. The information is correct, just not using the terminology. If I teach someone that the number 10 times the number 10 equals 100, they would know what kids learn both as times tables and multiplication tables. We’re both not wrong, I’m simply stating that you can learn how things work and alternative names and methods that are simpler to understand prior to learning a lot of fancy names and what not. It makes it easier since the target audience of the platform are children.

2 Likes