I'm a newbie to scripting, are there any bad habits or good habits I should be building?

Use comments to loosely map out what a script does. This allows you to easily pick up on what each script does and is particularly useful if you have messy code or need to work with other programmers.

6 Likes

When not figuring out how to solve something, take a break, go somewhere else and then come back to the script. (This really helps you giving a fresh start and new ideas) I really don’t recommend working for more then 2 hours on a script.

6 Likes

If you find something hard then look up for the easy ones and then get back to the hard ones when your done with those. Small note: Don’t ditch the easy ones since they might not be helpful for you currently but will be soon in the future!

2 Likes

The only few tips I know to help you are

Good Habits

  • Use local before the declaration of a variable/function. It’s not required but a lot of developers use it so it’s honestly best to use it as well

  • Name your variables/function the same as their purpose. Say you have a function that is supposed to add 2 numbers together. It’s best to call it Add2Nums() for example instead of anything unrelated to it, it can help having to comment code that can be confusing to understand since right names can act as comments of their own

  • Comment code that can be hard to understand and can’t all be explained by proper naming. Make sure it properly details what something does.

  • Don’t Repeat Yourself. What I mean by this is if you ever find yourself in a situation where code has to be repeated, such as make multiple scripts with the same purpose, don’t. Find a way to only have to use that code once but can be used by multiple things. For duplicate code in the same script it’s simple, just make a function and reference that function instead, but for other things you’ll have to get creative

Bad Habits

  • Using the 2nd parameter for Instance.new(). The 2nd parameter is used to assign the Instance a parent, it’s slow to use than just declaring the parent at the end.
  • Focusing way too much on optimizations. Usually some programmers tend to find as many ways to optimize something when in reality those optimizations are so small that they won’t do any difference and can just harm readability, focus on the minor optimizations that are common use

  • Overcomplicating. Making your code simpler to do a specific task can often be more pleasing to look at/improves readability and can help when debugging. If you don’t know how to make something using simpler methods, you can try to research.

That’s currently all the habits I have in my head that could be of use to you

10 Likes

In addition to the words of wisdom from the other users, I would highly recommend utilizing the Roblox Lua Style Guide GitHub to ensure that your code remains legible and consistent, making it easier to modify and debug your code over time.

3 Likes

I didn’t know how true this was until today two days ago when I started trying to make my first “Devil Fruit” The feeling of confusion and inability to solve the problem is so frustrating, and then when I eventually conede to taking a break I come back with renewed vigor and my brain feels better.

2 Likes

I’m a beginner scripter myself, but one thing I have found helpful is keeping my code organised. You should try to indent your code, and write lots of comments too. Indenting your code makes it look so much nicer and more organised, and having lots of comments makes sure you can remember what each bit of code does.

I hope this helped! :heartpulse:

1 Like

More stuff
Things not to do.

  • Do not use busy waits. Busy waits are loops where you wait for something to happen like repeat wait() until script.Parent.Achored == true i

  • do not use spawn() never ever use spawn() always use coroutine.wrap()() . for example

spawn(function()
while true do 
wait(5)
print("TEST")
end
end)

Should be done like

coroutine.wrap(function()
while true do 
wait(5)
print("TEST")
end
end)()
  • If you have really small wait times try not to do wait(0) wait() or wait(.01) do not use wait for them. Use a runservice event. For example wait(0) would be game:GetService(“RunService”).Hearbeat:Wait()

  • Using runservice events is good. But the event you should be using 99% of the time is Hearbeat. Do not use RenderStepped or Stepped (Unless you absolutely known you need to use them).

  • Do not use

for i = 1, #SomeTable do
 local v = SomeTable[i]
end

use

for _, v in ipairs(SomeTable) do

end
  • Never use deprecated stuff.

  • ̶D̶o̶ ̶n̶o̶t̶ ̶u̶s̶e̶ ̶P̶A̶R̶T̶.̶V̶e̶l̶o̶c̶i̶t̶y̶ ̶=̶ ̶S̶O̶M̶E̶T̶H̶I̶N̶G̶ ̶u̶s̶e̶ ̶P̶A̶R̶T̶:̶A̶p̶p̶l̶y̶I̶m̶p̶u̶l̶s̶e̶(̶S̶O̶M̶E̶T̶H̶I̶N̶G̶)̶

  • _ named variables are temporary variables. For example if you do not need a certain variable name it _ for example if you only need to known the other returned variable see below example

local Success, Error = pcall(SOMEFUNCTION)
print(Error)

would become

local _, Error = pcall(SOMEFUNCTION)
print(Error)
  • Learn to use xpcall

  • Do not do

if SOMECONDITION then
error(SOMERRORMESSAGE)
end

do instead

assert(SOMECONDITION, SOMEERRORMESSAGE)

And a lot more that I am too tired to write here.

5 Likes

MAKE SURE YOU READ THE OUTPUT. It is definitely worth it. Sometimes it’s hard to understand, but it tell you what line of code you made a mistake in when you run the game, and what type of mistake you made.

1 Like

You will probably find out as you read these suggestions that it’ll be hard to keep them all in mind, if you get all of it. These are all great recommendations, and I encourage people to come back and analyze the way they write their code.

In my opinion, the best habits you can build as a new scripter is thinking before writing code, and asking questions often. It’s a learning experience and this forum could feed you endless amounts of tips. The more you script, the easier it gets. Things will become second nature.

1 Like

Those 2 behave differently from each other where the first one goes through all the numeric keys until the last numeric key in table with a value assigned to it, even if keys don’t have a value assigned to them; where ipairs will stop working when it encounters a numeric key without a value assigned to it. So both of them are fine to use in different scenarios.

There is no such thing as “temporary variables” in lua. _ is pretty much still a normal variable just like something is but most people use it to assign a value that isn’t important to them like Key value returned from ipairs or pairs.

Velocity and impulse are 2 different things. ApplyImpulse takes force vector as it’s argument and the resulting velocity from the impulse relies on part’s/assembly’s mass while setting Part.AssemblyLinearVelocity directly doesn’t. Here is what I mean:

2 Likes

Good habits:

  • do not to use deprecated events such as connect
  • use WaitForChild()
  • try not to make scripts that works when they are supposed to and error when they are not needed (for example using Touched event can cause error when you first not check if touching part is something of player).
1 Like

Don’t use things like :findFirstChild. Please. Use :FindFirstChild instead.
Same with :connect

It hurts me internally if you don’t do this lol

1 Like

Use print() a lot to check whether the events are firing or if the code is even running since you can’t go wrong with the most basic method in lua

This, don’t waste an entire day on something when you are stressing out, it makes you feel like utter garbage sometimes.

2 Likes

I concur, don’t do the same mistake.

1 Like

To add onto the WaitForChild() suggestion, keep in mind that it’s something that should only be used in certain situations:


And to add onto @VortexColor’s post for the topic OP, here are some reasons why wait() should generally be avoided:

Best thing to do to easily become a good scripter: Watch the basics series for thedevking then start learning everything else from the devhub:

Links

TheDevKing - YouTube
Roblox APIl

Some good habits:
Don’t waste your time putting parenthesis around things like FindFirstChild

--bad
bob:FindFirstChild("susan")
--good
bob:FindFirstChild"susan"

Learn to use the API reference I linked to find functions that save you tons of time.

How is putting parenthesis a bad habit though? Not using them just makes your code harder to read and inconsistent with other functions if anything.

2 Likes

I just like that personally. Sorry if I bothered you!