Programming Guidelines || Make your code industry-standard

These are map guidelines from iG Studios , made public as a resource for others to use.

Programming guidelines are quite extensive for a variety of purposes. When writing code, you are being logical and straightforward, not artistic or flourished. Communication, consistency, and logical sense are all crucial to code to create a proper workflow.

These are based heavily on another general set of guidelines, but these are made to expand upon it and provide more context for Lua/LuaU.


Name everything with description and blatancy

Do not abbreviate or truncate variable or function names in most cases. Names should make sense, and should not require or provoke thought into what it actually is used for. For example, “player” is much better than “plr,” and even better than “p.”

Be incredibly direct with names. For example, functions should be concise; “modifyWalkspeed” is better than “walkspeedModification,” “listenToRemote” is better than “remoteBind,” “notify” is better than “doNotification,” etc. Keep time in mind as well; events happen in the moment, so for example, “onRemoteFire” or “onClick” will make much more sense than “remoteFire” or “click.”

Booleans can only be true or false. As such, they should be named as if they were yes or no questions. “isAlive” sounds like a yes or no question, but “alive” does not.

Functions, when called, happen in the moment as an event. As such, they must be named as if they are in present verb form. “getChildren” is better than “allChildren.” “movePlayer” is better than “playerMovement.”

It is easiest to read names if they are put in “positive form.” This means things should be named as if they could be true, not false.

  • The name itself matters. If you have a variable named “isDead,” try to instead use “isAlive.” “isShooting” makes more sense than “isNotShooting.”
  • When working with conditions, avoid using the “not” keyword too much If the inverse of a value is evaluated more, turn the name into a positive. For example, instead of having “not foo,” use a variable named “isNotFoo”

Functions must be concise

Avoid Boolean arguments that change the behavior of a function almost entirely. If you pass a boolean and it changes what the function does, then that is called “inappropriate sharing.” Duplication is superior this; create different functions that do different things, not a single function that does different things.

nil/null arguments are considered bad practice. Avoid these when possible, or at minimum, put them at the end of a parameter list inside of a dictionary.

Keep the amount of code to a reasonable minimum

Take this quite literally. Less code is better, as it makes it much easier to spot issues.

Open-source libraries are to be taken advantage of, when possible – this is not shameful, this is smart. If the library works well and is industry-standard, use it, as you will not have to spend your time writing it.

Do not overwrite code. Do not make variables if you will only use them once. Do not repeat yourself.

Do not cache inline functions, such as those from the math or cframe libraries, for example. LuaU includes inline caching.

The juxtaposition of your code matters

Colocate your code by feature. Variables should be at the top, then functions, then constructors, methods, and finally main “runners.”

Prefer generic solutions to many problems, not complex solutions to specific problems

Code should be reusable in different contexts. One function should not both load and use data, those should be separate. Attempt to use functions that do not rely on too many outside contexts to reduce side-effects. Since side-effects do happen, make sure they are defined.

Do not make code that makes it easy to make mistakes. Code is imperfect, but only because humans are, and all humans are fallible.

Create instances that are object-oriented, not procedural. Avoid global states. Prefer composition over inheritance. Prefer getter/setter functions rather than public read/write.

Make sure everything stays tidy. Event listeners should clean up. Classes should include deconstructors.

If there is a better way to do something, do the better way. Do not spend your time creating many solutions for different problems if a single solution can solve that problem.

Code should be readable

Your code should be readable by different people with different brains.

Include comments in your code! Comments should also include answers for “why does this do what it does,” not “what does this do.”

Be consistent with your style, otherwise, it will be hard to spot differences between data types.

Your code should be boring, but your comments may be interesting.

Your code should not have surprising results. Any user of similar skill should be able to observe your code and immediately determine what it does.

Code should be testable

If code cannot be tested, it is immediately bad. Enough said.

Exceptions should be handled properly

Return a state or success value in return tuples. This creates room for failure cases, which, creates soft-fail solutions, rather than hard errors. Errors should be reserved for when your code has reached a point of no return, such as with unexpected situations, unrecoverable state, etc.

Your code should handle exceptions and errors as standard control flow, but not rely on it.

Do not assume a truthy value is always returned in some methods.

Code should be optimized

All code should be tested extensively for optimal performance. Prefer methods that use less memory, CPU, and GPU.

If instances are spawned often, consider culling, not constructing and destructing.

Do not repeat yourself, make variables. This prevents the Lua engine from having to remake your data in the immediate memory.

Prefer code over instances.

Do not microoptimize, it is a waste of time and resources. It makes your code unreadable in many cases.

Avoid doing many heavy calculations in a short time period.

Avoid yielding when it is not needed. For example, WaitForChild is not needed for implicit objects.


Note

Please note these guidelines are used within iG-Studios as required aspects, but they do not determine other contexts. Take everything with a grain of salt. That being said, these guidelines have been reviewed by other programmers and it has universally agreed upon that these are industry standard.

More posts like this

This post is part of a series! See the below for all development guidelines:

80 Likes

I think this section could do with more clarification on what qualities make code testable. Assumptions can be made to what it could entail, but compared to the rest of your points, could do for some clarification.

I did some searching on the topic and their is a big opportunity to be learned from what testable code means. From my understanding it would encourage the use of Module Scripts and spacing code out than shoving code into Scripts and leaving them closed off from each other. This is something I think newer programmers don’t utilize enough and contributes to messy code.

3 Likes

Something to add to the optimization section of this thread is some resources. A lot of intermediate and beginner programmers leave their useless/used connections and loops opened. Programmers, if you are using connections on a wide scale that’s fine but please use a resource like Maid (Quenty’s github) to clean your connections afterwards! Open connections is one of the leading causes for memory leaks unrelated to Roblox’s own memory leaks (that do exist). Loops can also be tidied very easily, if you plan on using task.spawn() + a while loop, consider defining that new thread to then run task.cancel to effectively kill the loop (if you don’t do it already with break).

Great thread! Needs more publicity.

4 Likes