Scripting Helpers is winding down operations and is now read-only. More info→
← Blog Home

Clean and Tidy

What separates an amateur scripter from an expert? Surely, it is what they can do? Or, maybe it is how many games they've made?

Another question...What would a boss be looking for in your code if you were applying for a job as a programmer? Is it the knowledge of the language? Is it the complexity of what you can write?

I am a professional software engineer, and I have been since I was fifteen years old. Also, I've been scripting since I was twelve and I received a 5 on my AP Computer Science Exam A without ever taking a formal class. Why am I telling you this? Because, hopefully, these facts qualify me to answer the questions posed above.

So, what is the answer? What separates an amateur scripter from an expert, and what would a potential boss be looking for in a job application? The answer is simple. Clean code. Yes, knowing how to write code is necessary. Yes, the more you know the better it is for you. Yes, the more complex of code you can successfully write will help you. But none of that will ever matter when someone else is judging your skills if you don't write your code cleanly.


What do I mean by clean code? I mean formatting. I mean choosing clear and concise variable and function names. I mean making sure your code is readable by another scripter who has never seen your work before, and a third party can begin to understand everything in your code within minutes.

You may be asking How can I write clean code? Let's take a look.

Here is an example of some poorly formatted code that, really, doesn't make sense at first glance:

local a=script.Parent function b() if a.Position.X.Offset==-200 then a.Position=UDim2.new(0,0,0,0) a.Size=UDim2.new(0,100,1,0) a.BackgroundColor3=Color3.new(0.7855,0.234,0.6238) else a.Position=UDim2.new(0.5,-200,0.5,-200) a.BackgroundColor3=BrickColor.Random().Color a.Size=UDim2.new(0,400,0,400) end end a.MouseButton1Click:connect(b)

What is that monstrosity? Is that even valid code!? Well, it technically runs and works perfectly. But it takes several read throughs for anybody to really start to understand what is happening because it is all jumpled together and written on one line. The worst part? I found this from a free model...Someone actually wrote this and is distributing it to millions of ROBLOX players. And yet even the best of scripters can't understand it right away!

So, it's code clean-up time! Let's try to fix that code. The first step is probably to separate each part into its own line, like most people write their code. What does it look like after we do that?

local a=script.Parent
function b()
if a.Position.X.Offset==-200 then
a.Position=UDim2.new(0,0,0,0)
a.Size=UDim2.new(0,100,1,0) 
a.BackgroundColor3=Color3.new(0.7855,0.234,0.6238) 
else 
a.Position=UDim2.new(0.5,-200,0.5,-200) 
a.BackgroundColor3=BrickColor.Random().Color 
a.Size=UDim2.new(0,400,0,400) 
end 
end 
a.MouseButton1Click:connect(b)

Okay, it's a lot better now! Still, though...It's not very easy to read. Let's fix it up some more. Next, we should indent the lines appropriately.

local a=script.Parent
function b()
    if a.Position.X.Offset==-200 then
        a.Position=UDim2.new(0,0,0,0)
        a.Size=UDim2.new(0,100,1,0) 
        a.BackgroundColor3=Color3.new(0.7855,0.234,0.6238) 
    else 
        a.Position=UDim2.new(0.5,-200,0.5,-200) 
        a.BackgroundColor3=BrickColor.Random().Color 
        a.Size=UDim2.new(0,400,0,400) 
    end 
end 
a.MouseButton1Click:connect(b)

Woah! That just got so much better!! I'm starting to really understand it now! But, it could use some more whitespace. All those equals signs and commas without spaces make my eyes hurt! SPACEBAR

local a = script.Parent
function b()
    if a.Position.X.Offset == -200 then
        a.Position = UDim2.new(0, 0, 0, 0)
        a.Size = UDim2.new(0, 100, 1, 0) 
        a.BackgroundColor3 = Color3.new(0.7855, 0.234, 0.6238) 
    else 
        a.Position = UDim2.new(0.5, -200, 0.5, -200) 
        a.BackgroundColor3 = BrickColor.Random().Color 
        a.Size = UDim2.new(0, 400, 0, 400) 
    end 
end 
a.MouseButton1Click:connect(b)

Okay, now we can read it without hallucinating. But, those variable and function names are just, not working for me. Let's make those more meaningful now that we can understand what they are by reading through.

local button = script.Parent
function moveButton()
    if button.Position.X.Offset == -200 then
        button.Position = UDim2.new(0, 0, 0, 0)
        button.Size = UDim2.new(0, 100, 1, 0) 
        button.BackgroundColor3 = Color3.new(0.7855, 0.234, 0.6238) 
    else 
        button.Position = UDim2.new(0.5, -200, 0.5, -200) 
        button.BackgroundColor3 = BrickColor.Random().Color 
        button.Size = UDim2.new(0, 400, 0, 400) 
    end 
end 
button.MouseButton1Click:connect(moveButton)

Hey! Now I can understand most of what is going on really easily!! There's just a little bit more I want to change. One thing is that Color3.new(0.7865, 0.234, 0.6238). Who knows what color that is!? Gah, no, let's change that. A simple math problem of multiplying 255 by each of those decimals will help us out, and then we might as well round to the nearest whole number. When we do that, it turns into this: Color3.new(200/255, 60/255, 160/255). (Color3.new takes a number between 0-1, so we have to divide by 255. This is an instance of when readability trumps a minor change in efficiency.) So much better. Now, just by looking at it, I can tell it's going to be a purplish color due to the red and blue dominance. That's better.

The next thing I want to do is separate some core parts of the script with an extra line of whitespace. Not too hard. And, while we're at it, let's rearrange some of the property changes so that both blocks follow the same pattern. So, let's look at what we have after this step:

local button = script.Parent

function moveButton()
    if button.Position.X.Offset == -200 then
        button.BackgroundColor3 = Color3.new(200/255, 60/255, 160/255)
        button.Position = UDim2.new(0, 0, 0, 0)
        button.Size = UDim2.new(0, 100, 1, 0) 
    else
        button.BackgroundColor3 = BrickColor.Random().Color 
        button.Position = UDim2.new(0.5, -200, 0.5, -200) 
        button.Size = UDim2.new(0, 400, 0, 400) 
    end 
end 

button.MouseButton1Click:connect(moveButton)

Now THAT'S some great code!! I think we can officially share this with people and they will understand soon enough. But if we really wanna write clean, understandable code, there is one last step -- comments!

local button = script.Parent --This variable holds the button to be altered

function moveButton() --This function moves the button and does some other changes
    if button.Position.X.Offset== -200 then --If the button is in the middle of the screen
        button.BackgroundColor3 = Color3.new(200/255, 60/255, 160/255) --Set its color to a purple
        button.Position = UDim2.new(0, 0, 0, 0) --Move it to the top left corner
        button.Size = UDim2.new(0, 100, 1, 0)  --Change its size
    else --Otherwise, if the button is not already in the middle...
        button.BackgroundColor3 = BrickColor.Random().Color --Set its color randomly
        button.Position = UDim2.new(0.5, -200, 0.5, -200) --Move the button to the middle
        button.Size = UDim2.new(0, 400, 0, 400) --Change its size
    end --End if
end --End function

button.MouseButton1Click:connect(moveButton) --Handle the click event with moveButton

And now, even non-coders can understand what happens! Maybe commenting on EVERY line is excessive, and actually it probably is. But getting into a habit of commenting at every important part of a script (such as when some complicated bit of code is seen or at the beginning of a function) is one that every aspiring programmer should get into.

To summarize, if you want to be known as an expert scripter and maybe work as a programmer some day, keep your code clean! It took us several steps to clean up one small piece of code that really just moved a button on a screen just so we could read it easily. But if you practice readability and clean code as you go, you won't have to take so much time doing this and you'll be able to share it with others easily!

Now go out there and write some clean code!

Posted in Scripting Tips

Commentary

Leave a Comment

Perci1 says: June 4, 2015
This makes me feel happy :D I can write clean code. Although I disagree with all the comments.I think comments should be placed at key intervals, like at the beginning of a code block, and only when something needs clarifying. All those comments take away from the readability in my opinion (although admittedly it would be better without the line wrapping).
M39a9am3R says: June 5, 2015
I usually just use comments to host unneeded code (as in code I would use for later). Some of my scripts are messy, but if a person were to ask me what a line of my code were to do, then I'd be able to tell them. I have a method to my madness. Some lines of code I leave on one line, other lines of code I leave on multiple lines, just the way I roll.
alphawolvess says: June 5, 2015
I like how my normal way to code is this clean form, just the habit I obtained because I liked it when I first started. People need to remember that tab key.
AmiracIe says: June 5, 2015
Great blog article. I loved the introduction, and it helped me on my coding journey.
unmiss says: June 5, 2015
What a wonderful article to write. Helps a lot. How would one even make that starting code, what a jumbled mess. maybe it was you, mister clean code e.e
DevChris says: June 17, 2015
To be honest, although it is important to help others understand your code, much of this post was opinion-based (for example, the spacebar thing. Some people do it as their own personal style/preference and to speed up coding.) Also, I think this was very brief and written poorly (you don't even explain how to indent properly.)
User#5423 says: July 2, 2015
Not a lot of people do this when scripting in roblox but it is done a lot in other languages. A description about what the script is should also be included especially in modular scripts to help in future updates.
KenzaXI says: July 20, 2015
I never use comments, Because they're a waste of time, Why bother going through your script and reading the comments you made when you made the script, apart from that I always clean code, Since I started, I hate untidiness :)
BlueTaslem says: July 27, 2015
@devChris It is universally accepted by professional programmers that you need space around operators of low precedence. It isn't really so much an opinion as a mechanism that definitively improves readability. @Perci1 There's a style called "literate code." The idea is that you mark code and unmarked code is comments. It's usually displayed in two columns. Most code definitely doesn't need it.
GreekGodOfMLG says: August 5, 2015
Writing Clean Code Is Legit :3