Writing Clean Code

From Legacy Roblox Wiki
Jump to navigationJump to search

Hey there! I'm going to show you how to write efficient, professional looking code.

It's important to know how to do this, as it will be easier for people to read your code and to debug it. (Not implying your code will have bugs.)

--In case of bugs, call a pest control agency.

Indenting

One of the most important things to do when writing good code is to indent it. Indenting may sound like something fancy, but all it really means is that we add one tab per block of code depth. One tab for every if, while, for, function, repeat, etc. For every line after one of those keywords, the next line has one more tab at the beginning. This lets you see visually where the block of code starts and ends. This also makes it nearly impossible for you to miss an "end" statement.

Here is an example of some messy, broken code that doesn't work due to a missing end that we can't seem to find:

local powerLevel = -6
function fancyFunction()
powerLevel = powerLevel +1
end
for i = 1,10 do
if 1 + 1 == 2 then
fancyFunction()
print(powerLevel)
end

With indenting we can easily see where our ends meet up, and where there might be a missing one:

local powerLevel = -6
function fancyFunction()
	powerLevel = powerLevel +1
end
for i = 1, 10 do
	if 1 + 1 == 2 then
		fancyFunction()
	print(powerLevel) --Oh noes, this doesn't look right!
end

We can see there that the function's end and for-loop's end match up, but our if statement doesn't seem to have one. Then it's a simple matter of adding that in there:

local powerLevel = -6
function fancyFunction()
	powerLevel = powerLevel +1
end
for i = 1, 10 do
	if 1 + 1 == 2 then
		fancyFunction()
	end
	print(powerLevel)
end

Indenting will not slow your scripts down - whitespace is ignored by the Lua interpreter.

Good variable names

Another important thing to do is to have good variable names.

If you have messy variable names like "mj90_z" it can be confusing for people trying to read your code, it will confuse you if you come back and read it as well as they can be hard to remember.

Here is some code with bad variable names that we can't seem to remember:

 epic1337 = false
 georgewin = 1
 if not epic1337 then
     georgewin = 0
 end

That code wasn't very long, yet it had me confused. I don't know about you though..

I think that code was titled "Get to the chopper script!" but it doesn't seem to make any sense.

We can rename the variables, so it's easier to see what it's doing:

atChopper = false
peopleAtChopper = 1
if not atChopper then
	peopleAtChopper = 0
end

Ah. So if you're not at the helicopter the number of people at it is 0. That makes a lot more sense, and now you can understand what's going on.

--In case of helicopter injuries, call that same pest control agency. They have a lawyer division so you can sue me!

Commenting

What if you're making a really big game, with multiple people scripting and giving scripts to each other?

Well, you could hope that your friends understand what you're doing when they add on, or you could comment your code so that it's well explained, and they just have to read a bit of text.

Here's an example of some confusing code:

codeIsConfusing = true
if codeIsConfusing then
	print("Man, this code is confusing.")
end

I don't know about you, but that confused the heck out of me.

We can comment that, so it makes more sense. To write a single line comment use --. All the text after that will be a comment.

If we want to do a big chunk of comments we can do a start comment: --[[ and an end comment ]] to signify we want to do comments in between.

Here's that same confusing code, with comments to help out our friends:

--[[
	This is some code that checks out how confusing the code is.
	Set CodeIsConfusing to true or false, depending on whether it's confusing or not.
]]
CodeIsConfusing = true --Boolean value for whether this code is confusing.
if CodeIsConfusing then --If it is confusing..
	print("Man, this code is confusing.") --Print out some text.
end --End the if statement.

Now our friends will be able to understand that code.

--Confusing code is confusing.

Using for loops

Have you ever seen code for a fading door like this?

script.Parent.Transparency = 0.1
wait(0.1)
script.Parent.Transparency = 0.2
wait(0.1)
script.Parent.Transparency = 0.3
wait(0.1)
script.Parent.Transparency = 0.4
wait(0.1)
script.Parent.Transparency = 0.5
wait(0.1)
script.Parent.Transparency = 0.6
wait(0.1)
script.Parent.Transparency = 0.7
wait(0.1)
script.Parent.Transparency = 0.8
wait(0.1)
script.Parent.Transparency = 0.9
wait(0.1)
script.Parent.Transparency = 1
wait(0.1)

We can save a lot of time and memory if we just use a for loop for that.

Basically we could just set the Transparency of the part to your index variable, in the loop.

Here's an example:

for i = 1, 10 do
	script.Parent.Transparency = i/10
	wait(0.1)
end

However, we can make that more efficient! It's true!

Using the for loop's third argument, the increment, we can make it go up by 0.1 instead of 1 which means we wouldn't need the /10.

Here's an example:

for transparency = 0, 1, 0.1 do
	script.Parent.Transparency = transparency
	wait(0.1)
end

This is a handy trick, which will save you a lot of time animating and creating things.

--Have hope you who enter here. For loops are the future!

Booleans

When you're writing code, and you have a true or false value, you probably tend to say if value == true/false then do something.

Wait! We can improve that! One nice thing ROBLOX can do is convert values into true/false in if statements.

Basically, if you give it something that exists it will say true, and if it's nil it will be false.

With this, we can write efficient code that doesn't use == true/false. Here's how:

Just take away the == true/false. It's as easy as that.

Here's an example of some bad code:

cake = Workspace:FindFirstChild("Cake")
yummy = true
if cake ~= nil then
	if yummy == true then
		print("The cake exists, and is yummy.")
	end
end

And here we are with the == true/false and ~= true/false removed:

cake = Workspace:FindFirstChild("Cake")
yummy = true
if cake then
	if yummy then
		print("The cake exists, and is yummy.")
	end
end

It works just as well, and is a more efficient way of doing it. This also makes more sense, it's like saying "if cake then do this" instead of "if cake is the equivalent of true then do this."

Now what if we want it to fire if the cake doesn't exist and isn't yummy?

Well, we can use "not" which reverses a boolean! Huzzah!

Here's an example:

cake = Workspace:FindFirstChild("Cake")
yummy = true
if not cake then
	if not yummy then
		print("The cake does not exist, and wouldn't be yummy anyway.")
	end
end

--We are not responsible if the cake is a lie.

Math

Believe it or not, the way you syntax math in a script can make it much easier to read and edit.

Here's a crash course on order of operations for those of you who have never learned it:

  • Parenthesis are always the first thing to be calculated in math
  • Exponents are calculated after parenthesis
  • Multiplication and Division are calculated third
  • Addition and Subtraction are the last to be calculated.

So how do we use this knowledge to make our scripts look cleaner?

Well, many people's scripts look like this when it comes to math:

local number = 5 * 2 + 6 / 3

Right now, it just looks like a bunch of numbers and symbols. You can figure out how it will execute, but it can definitely be cleaned up.

You can do this however you like, but here's how I personally do it.

  • Don't use spaces in multiplication or division.
    local number = 5*2, 6/3
    
  • Use spaces when adding or subtracting.
    local number = 2 + 6, 10 - 4
    
  • Use parenthesis when applicable.
    local number = (5*2), (6/3)
    

Using your personal style for math can make a code much easier to see how it will execute. Cleaning up our previous code can give us this:

local number = (5*2) + (6/3)

I don't know what you think, but it sure looks easier to my eyes.