Writing Clean Code: Difference between revisions

From Legacy Roblox Wiki
Jump to navigationJump to search
>Ozzypig
(Rejected the last text change (by JulienDethurens) and restored revision 49212 by Ozzypig)
(SyntaxHighlight instead of Template:Code)
 
(2 intermediate revisions by 2 users not shown)
Line 7: Line 7:
--In case of bugs, call a pest control agency.
--In case of bugs, call a pest control agency.


== Indenting Your Code ==
== 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.
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.
Line 13: Line 13:
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:
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
<syntaxhighlight lang="lua">
function fancyFunction()
local powerLevel = -6
powerLevel = powerLevel +1
function fancyFunction()
end
powerLevel = powerLevel +1
for i = 1,10 do
end
if 1 + 1 == 2 then
for i = 1,10 do
fancyFunction()
if 1 + 1 == 2 then
print(powerLevel)
fancyFunction()
end
print(powerLevel)
end
</syntaxhighlight>


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


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


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:
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
<syntaxhighlight lang="lua">
function fancyFunction()
local powerLevel = -6
    powerLevel = powerLevel +1
function fancyFunction()
end
powerLevel = powerLevel +1
for i = 1, 10 do
end
    if 1 + 1 == 2 then
for i = 1, 10 do
        fancyFunction()
if 1 + 1 == 2 then
    end
fancyFunction()
    print(powerLevel)
end
end
print(powerLevel)
end
</syntaxhighlight>


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


== Good Variable Names ==
== Good variable names ==


Another important thing to do is to have good variable names.  
Another important thing to do is to have good variable names.  
Line 57: Line 63:


Here is some code with bad variable names that we can't seem to remember:
Here is some code with bad variable names that we can't seem to remember:
 
<syntaxhighlight lang="lua">
  epic1337 = false
  epic1337 = false
  georgewin = 1
  georgewin = 1
Line 63: Line 69:
     georgewin = 0
     georgewin = 0
  end
  end
 
</syntaxhighlight>
That code wasn't very long, yet it had me confused. I don't know about you though..
That code wasn't very long, yet it had me confused. I don't know about you though..


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


<pre>
<syntaxhighlight lang="lua">
atChopper = false
atChopper = false
peopleAtChopper = 1
peopleAtChopper = 1
if not atChopper then
if not atChopper then
    peopleAtChopper = 0
peopleAtChopper = 0
end
end
</pre>
</syntaxhighlight>


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. It's common practice to use lowerCamelCase to name variables.
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!
--In case of helicopter injuries, call that same pest control agency. They have a lawyer division so you can sue me!


== Commenting Code ==
== Commenting ==


What if you're making a really big game, with multiple people scripting and giving scripts to each other?
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.
Well, you <strong>could</strong> 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:
Here's an example of some confusing code:


codeIsConfusing = true
<syntaxhighlight lang="lua">
if codeIsConfusing then
codeIsConfusing = true
    print("Man, this code is confusing.")
if codeIsConfusing then
end
print("Man, this code is confusing.")
end
</syntaxhighlight>


I don't know about you, but that confused the heck out of me.
I don't know about you, but that confused the heck out of me.
Line 103: Line 111:
Here's that same confusing code, with comments to help out our friends:
Here's that same confusing code, with comments to help out our friends:


--[[
<syntaxhighlight lang="lua">
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.
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..
CodeIsConfusing = true --Boolean value for whether this code is confusing.
    print("Man, this code is confusing.") --Print out some text.
if CodeIsConfusing then --If it is confusing..
end --End the if statement.
print("Man, this code is confusing.") --Print out some text.
end --End the if statement.
</syntaxhighlight>


Now our friends will be able to understand that code.
Now our friends will be able to understand that code.
Line 116: Line 126:
--Confusing code is confusing.
--Confusing code is confusing.


== Converting Inefficient Number Stuffs Into For Loops ==
== Using for loops ==


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


script.Parent.Transparency = 0.1
<syntaxhighlight lang="lua">
wait(0.1)
script.Parent.Transparency = 0.1
script.Parent.Transparency = 0.2
wait(0.1)
wait(0.1)
script.Parent.Transparency = 0.2
script.Parent.Transparency = 0.3
wait(0.1)
wait(0.1)
script.Parent.Transparency = 0.3
script.Parent.Transparency = 0.4
wait(0.1)
wait(0.1)
script.Parent.Transparency = 0.4
script.Parent.Transparency = 0.5
wait(0.1)
wait(0.1)
script.Parent.Transparency = 0.5
script.Parent.Transparency = 0.6
wait(0.1)
wait(0.1)
script.Parent.Transparency = 0.6
script.Parent.Transparency = 0.7
wait(0.1)
wait(0.1)
script.Parent.Transparency = 0.7
script.Parent.Transparency = 0.8
wait(0.1)
wait(0.1)
script.Parent.Transparency = 0.8
script.Parent.Transparency = 0.9
wait(0.1)
wait(0.1)
script.Parent.Transparency = 0.9
script.Parent.Transparency = 1
wait(0.1)
wait(0.1)
script.Parent.Transparency = 1
wait(0.1)
</syntaxhighlight>


We can save a lot of time and memory if we just use a for loop for that.  
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.  
Basically we could just set the [[Transparency]] of the part to your index variable, in the loop.


Here's an example:
Here's an example:


for i = 1, 10 do
<syntaxhighlight lang="lua">
    script.Parent.Transparency = i/10
for i = 1, 10 do
    wait(0.1)
script.Parent.Transparency = i/10
end
wait(0.1)
end
</syntaxhighlight>


However, we can make that more efficient! It's true!
However, we can make that more efficient! It's true!
Line 158: Line 172:
Here's an example:
Here's an example:


for transparency = 0, 1, 0.1 do
<syntaxhighlight lang="lua">
    script.Parent.Transparency = transparency
for transparency = 0, 1, 0.1 do
    wait(0.1)
script.Parent.Transparency = transparency
end
wait(0.1)
end
</syntaxhighlight>


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


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


== Better Booleans ==
== 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.
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.
Line 175: Line 191:
Basically, if you give it something that exists it will say true, and if it's nil it will be false.  
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:
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.
Just take away the == true/false. It's as easy as that.


Here's an example of some BAD code:
Here's an example of some bad code:


cake = game.Workspace:FindFirstChild("Cake")
<syntaxhighlight lang="lua">
yummy = true
cake = Workspace:FindFirstChild("Cake")
if cake ~= nil then
yummy = true
    if yummy == true then
if cake ~= nil then
        print("The cake exists, and is yummy.")
if yummy == true then
    end
print("The cake exists, and is yummy.")
end
end
end
</syntaxhighlight>


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


cake = game.Workspace:FindFirstChild("Cake")
<syntaxhighlight lang="lua">
yummy = true
cake = Workspace:FindFirstChild("Cake")
if cake then
yummy = true
    if yummy then
if cake then
        print("The cake exists, and is yummy.")
if yummy then
    end
print("The cake exists, and is yummy.")
end
end
end
</syntaxhighlight>


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."
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?  
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!
Well, we can use "not" which reverses a boolean! Huzzah!
Line 207: Line 227:
Here's an example:
Here's an example:


cake = game.Workspace:FindFirstChild("Cake")
<syntaxhighlight lang="lua">
yummy = true
cake = Workspace:FindFirstChild("Cake")
if not cake then
yummy = true
    if not yummy then
if not cake then
        print("The cake does not exist, and wouldn't be yummy anyway.")
if not yummy then
    end
print("The cake does not exist, and wouldn't be yummy anyway.")
end
end
end
</syntaxhighlight>


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


== Using Clean Math ==
== Math ==


Believe it or not, the way you syntax math in a script can make it much easier to read and edit.
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:
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
*Parenthesis are always the first thing to be calculated in math
*Exponents are calculated after parenthesis
*Exponents are calculated after parenthesis
Line 231: Line 253:
Well, many people's scripts look like this when it comes to math:
Well, many people's scripts look like this when it comes to math:


5 * 2 + 6 / 3
<syntaxhighlight lang="lua">
local number = 5 * 2 + 6 / 3
</syntaxhighlight>


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.
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.
Line 237: Line 261:
You can do this however you like, but here's how I personally do it.
You can do this however you like, but here's how I personally do it.


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


Using your personal style for math can make a code much easier to see how it will execute.
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:
Cleaning up our previous code can give us this:


(5*2) + (6/3)
<syntaxhighlight lang="lua">local number = (5*2) + (6/3)</syntaxhighlight>


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

Latest revision as of 23:11, 26 April 2023

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.