Introduction
This post is intended to be a resource to provide valuable information on performance considerations when constructing games. To those who may come across this thread, if there are concerns of inaccurate information please contact me.
General
Introduction To General Performance Considerations
The general category will include general performance issues that are affected across other development categories.
Particles
Introduction To Particles
Particles are fantastic tools that we can use in order to improve the quality of our games. Particles are automatically optimized (based on graphics level) by Roblox but there is a way of using them through the method known as :Emit()
. You can read about this here.
As mentioned on the DeveloperHub:
Now if you’re creating special effects that require you to use the :Emit()
function, I’ve created a function that compresses the amount of particles based on the local players graphic levels.
return function(Particle, EmissionAmount)
local QualityLevel = UserSettings().GameSettings.SavedQualityLevel
if QualityLevel == Enum.SavedQualitySetting.Automatic then
local Compressor = 1/2
Particle:Emit(EmissionAmount*Compressor)
else
local Compressor = QualityLevel.Value/21
Particle:Emit(EmissionAmount*Compressor)
end
end
You can utilize this function by copy and pasting it into a ModuleScript
. You can then simply require the module script and do the followig:
local Emit = require(Emit)
Emit(Particle, Amount)
Instance Count
Introduction To Instance Count
Though this is pretty self-explanatory I believe I should still talk about this topic. It should be common sense that the less objects and items you have in your world, the better performing it will be. That being said, there are times where reducing the amount of instances become impossible while keeping quality in mind.
To those who have trouble with reducing instances with blocks (if you’re making a block game) there are a few posts that can help you like this one.
Overall, be aware of how many instances you are using and ask yourself; is it’s necessary? This doesn’t only apply to building, as an example, some programmers strictly stick to using Table overs objects to store values while others find it convenient to use objects. Read the other categories to learn more about this.
Using Multiple Places
Introduction To Having Multiple Places
Are you making a game with a LOT of content? If that is the case, you may want to consider using multiple places within the same Universe. By creating multiple places, you can split up worlds/dimensions as well cut down on scripts that may be crucial only to certain worlds.
You can learn about how to use TeleportService and start using multiple places. Examples of games that may need to use multiple places are MMORPG grinding games.
Lighting
Introduction To Lighting
Lighting is more important than it seems and can drastically affect the performance of lower end users. The most expensive technologies are ShadowMap
and Future
because of how much more detailed they are and the more functionality it provides. You can see more about this in the Building Category which talks about CastShadow.
Memory
Introduction To Memory
Memory is important when it comes to constructing your game. You usually want your game to be accessible to every platform to acquire the most amount of players as possible. Now, some of you may not care about mobile support and if that’s the case memory isn’t as important (but memory leaks are when it comes to scripting). Regardless, you still want to optimize your game as much as possible to provide the best experience to players.
What is memory?
Memory is the amount of data needed to be stored for unique assets. These are a few assets that use up memory:
- meshes
- textures
- animations
- sounds
- unions (CSG)
Please note, memory is measured by unique assets when it comes to visuals not the amount. By now, it should be common sense to reduce the total amount of items (instances) in your world if possible.
What should my memory be at?
This is a common question asked quite frequently and that is how much memory should your game shoot for. Here is an image of the estimated memory storage available on each device:
You can find a post on it here.
One thing you can do is look at the front-page games of Roblox and check out how they are doing on memory. You can check memory by joining a game and pressing F9. I’d recommend looking at more popular games as they may possibly have mobile support.
How can I reduce memory?
Because memory is such a broad topic, I’m going to list majority of everything here. Please note, some information is rumored and not 100% accurate. I’m going to be labeling what I know is for sure factual.
will represent unsure,
will mean it’s factual. If I made a mistake or you know if one is factual or not feel free to contact me to correct it.
Methods | Factual |
---|---|
Reducing Image Dimensions | ![]() |
Compressing Image Size | ![]() |
Reduce Amount Of Unique Images | ![]() |
Reduce Amount Of Unique Animations | ![]() |
Reduce Amount Of Unique Textures | ![]() |
Reduce Amount Of Unique Decals | ![]() |
Reduce Amount Of Unique Meshes | ![]() |
Reduce Amount Of Unique Unions | ![]() |
Reduce Amount Of Sound Assets | ![]() |
Not Caching Variables And Functions In Scripts | ![]() |
Lower Amount The Amount Of Modules | ![]() |
Storing Assets In Server Storage Rather Than ReplicatedStorage |
![]() |
Please note, some of these are unavoidable. For example, functions and variables are extremely useful and makes things much easier while other methods such as meshes and images can possibly be reused. This is only here to provide information.
Replies To Consider
Scripting
Introduction To Scripting Performance Considerations
When it comes to scripting, we need to think logically. For a script to perform at it’s best, ideally you want to limit the amount of tasks for the script to execute. This is where algorithms come in to improve efficiency of code.
Luau
Introduction to Luau
Luau, is an extension of Lua created by Roblox. Features from Luau proves to be much more performance beneficial over Lua. Luau is constantly being updated with new features such as a recent new feature implemented into the table library table.clear()
which are much more optimized compared to clearing tables manually or making a new one. On the platform, it is recommended to use Luau, however, some of us may not be happy with it and may just stick towards official Lua more.
Visual Effects
Introduction To Scripting Visual Effects
Throughout my experience communicating with other developers, I’ve noticed one thing I believe everyone should understand. The server should be running at maximum efficiency handling important data and information. This means that all visual effects should be done on the client and replicated across the clients if necessary. The benefits of this is not only better performance on the server but smoother visuals on the client.
I’ve seen far too many people tween/lerp meshes on the server or spawn particles on the server. To replicate visuals across all the clients, consider looking at RemoteEvents and their :FireAllClients()
method.
Algorithms
Introduction To Algorithms
While I could talk about Algorithms there are plenty of articles and posts online that can help you understand. In short, Algorithms are different ways to approach certain situations to improve efficiency of code. You can read more about it here. For a more friendlier article you can read this.
While algorithms are extremely helpful, they aren’t universally applicable, certain algorithm can only be used under specific situations. For example, binary search is a well known algorithm, however, it can only be applied on sorted lists/arrays. Depending on the situation, algorithms may or may not be applicable.
Bad Practices
Introduction To Bad Scripting Practices
When it comes to scripting, bad practices are considered from typos to code structure. Though some are not necessary to change (if it’s personal preference), but some may become more crucial as we move to code structure as it can directly affect game performance. When it comes to bad coding practices, this can be extremely broad so I’ll list as many common examples as possible. Let me know if I’ve missed some important ones. For the purpose of this post, I will only post bad practices that affect performance.
I must also say, there are plenty of posts out there and one I find very informative is this one:
https://devforum.roblox.com/t/what-are-bad-programming-habits-that-you-see-often-by-scripters/761033
Bad Practices:
Using The Second Argument Of Instance.new()
Using The Second Argument Of Instance.new()
There was a public PSA on this topic here. If you’re lazy and don’t want to click links, to keep it short it’s best practice to parent last. The reason for this is so that the server does not need to replicate all the changes to the client. It’d be preferred if all the properties were set and then parented so it’s all replicated at once. For more information read the PSA.
Using Loops Improperly
Using Loops Improperly
Loops are extremely helpful and they are capable of helping us in many ways. But one way that I’ve seen many using loops improperly is using loops over built in connections. Built in connections are loops but they are much more optimized. An example would be: using a infinite loop to update a TextLabel is not recommended, instead use .Changed
or :GetPropertyChangedSignal
.
You’ll notice that after adding a few loops to just update TextLabels you’ll end up crashing your game at one point.
Not Localizing Variables
Not Localizing Variables
Not Localizing variables are sometimes important for performance. This is evident when running functions that have reiterations (loops).
local Clock = os.clock
local Start = Clock()
local RunService = game:GetService("RunService")
local VarToEdit
for i = 1, 1000 do
VarToEdit = os.clock() -- this does not use our cached variable
end
print(Clock() - Start)
Start = Clock()
for i = 1, 1000 do
VarToEdit = Clock() -- This one does
end
print(Clock() - Start)
And here are your results:
You’ll notice by a very small amount, that using the cached variable is faster.
I do want to mention that recent changes to Luau has already localized the libraries. You can read about changes here and here. That being said, if you wish to stick closer to official lua you can still cache libraries as practice.
Not Caching Your Variables As A Local Variable
Not Caching Your Variables As A Local Variable
As mentioned earlier, the more functions you give to something, the more expensive it usually is. This is why when constructing let’s say an NPC system for an example, the dumber it is the better. By localizing, you limit the variables to the script it’s in.
Memory Leaks
Introduction To Memory Leaks
Memory leaks are caused by scripts that are not cleaning up / removing assets that were created and is no longer being used. Memory leaks are also caused by internal code (usually loops or RBXSignals that don’t get disconnected when finished with). There are 2 posts that explain really well on this topic here and here.
The easiest way to prevent memory leaks is to ensure that you are destroying and disconnecting your connections and object. If you are constantly creating things but never destroy them of course the game is going to crash at one point.
One useful tool to new developers is to use the maid class created by Quenty. You can find it here.
Building
Introduction To Building Performance Considerations
When people first start building, usually they don’t consider optimization as their priority. If you’re trying to make a popular game that supports all platforms then this may come to mind.
There a few things that should be mentioned in this topic so I’ll go ahead and break this into categories.
Textures And Decals
Introduction To Textures and Decals
If you haven’t read the section on Memory in General, I suggest you do. Using multiple unique textures and decals is one way to increase memory in your world. That being said, certain built-in materials render easier than others (look at BasePart Properties).
Part/Texture Count
Introduction To Part/Texture Count
If you haven’t checked out General > Instance Count then I suggest you read that section first.
Moving on, in my personal experience, Building has been one of the most guilty in overusing objects/instances. As mentioned in the section of Instance Count, there are ways to reduce part count through a method known as Greedy Meshing. Unfortunately, greedy meshing isn’t applicable in every situation so the best tip for you builders is be aware on how many parts you are using and look for anything you can combine.
That being said, BaseParts are not the only thing that are overused. If you must use Textures try to use textures on faces that matter. If a face of a Part will never be seen by a person, don’t add a texture on that face.
Here is a nice visual example from Mariofly5’s post:
Mariofly5 has also made a post on building optimization which you can read about here.
Level Of Detail Property
Introduction To Level Of Detail
Level Of Detail is a property of Models
that was recently introduced which works with the property called StreamingEnabled
in Workspace
. For more information, check out this post.
In short, Level Of Detail will help with the system knowing what to render out and what to keep. Having the property on Automatic
or Disabled
can benefit lower end devices.
BasePart Properties
Introduction To BasePart Properties
When you build a map, you need to consider if certain parts need collision or not. The reason for this is because Roblox performs physic calculations on parts with specific properties. The best properties to have for builds would be:
Property | Value |
---|---|
Anchored | ![]() |
CollisionFidelity | Box |
CastShadow | ![]() |
CanCollide | ![]() |
Transparency | 0 or 1 |
These would be the ideal properties to have in every BasePart. If you’re making a simulator and detail isn’t required consider turning off CastShadow
and changing the CollisionFidelity
to box. In most cases, unless you really need Roblox’s physic calculations on your BasePart, Anchored
should always be set to true.
As for transparency, here’s a quote from colbert2677
from here
BasePart Material
If you’ve played games on Roblox, you may have seen certain games provide an option for lower end devices which basically changes all the material to SmoothPlastic and removes textures. Now, this is true that SmoothPlastic is much better as a material for performance. Materials such as Neon
and ForceField
will tend to be much more expensive. ForceField has extra functionality such as adding a texture to have a “ForceField” affect while Neon just has extra glow. Anything that has more functionality would be more expensive.
If you plan offering a lower graphics option to players, consider doing the following:
- Change the lighting to something less expensive locally
- Change all materials to SmoothPlastic locally
- Disable CastShadow for all BaseParts
Meshing and CSGs
Introduction To Meshing Performance Considerations
Since I’m not a modeler, I don’t know much about performance considerations on this topic. I’ve done some research and well meshing comes down to a few things. The post I used for research can be found here and is much more informative.
Triangles
Introduction To Triangles
Every BasePart
in Roblox has geometry to it and are conformed by triangles. Meshes and unions tend to have more triangles because of the more complex shape compared to Roblox parts. The less triangles you have the better.
Here’s a quote from here.
RenderFidelity Property
Introduction To RenderFidelity Property
If you haven’t checked out LevelOfDetail
property in the Building
category for models, I suggest you take a quick look at that.
RenderFidelity
is similar to LevelOfDetail
except it doesn’t require StreamingEnabled
. Instead of completely removing the Model, instead, it’ll drop in quality. This can be very beneficial to players with lower end devices. Setting your RenderFidelity
to Automatic
would be the best option for performance.
Collisions
Introduction To Collisions
I’ve already mentioned collisions in Building > BasePart Properties. Meshes and CSG’s are considered BaseParts so please refer to BasePart Properties in building.
LowPoly Vs HighPoly
Introduction To Lowpoly vs Highpoly
You’e probably heard of the term of Low Poly and High Poly before. What does it mean and how does this affect your world? Well, rather than explaining I’ve found a very informative article here that you can read about. Generally, simulators sticks to “Low Poly” because of how simple it looks as well as the best choice when creating a game across all platforms (Mobile, Console, PC) because of the performance benefits.
Animations
Introduction To Animation Performance Considerations
After some researching, I was unable to find anything that really should be considered for animations. We can probably assume the more unique animations there are along with the more keyframes each animation has the more memory it will consume.
My suggestion would be don’t bother with animations that much. If your game is lagging or having performance issues it’s more likely it’s another cause.
Gui
Introduction To GraphicalUserInterface (GUI) Performance Considerations
After researching upon this topic, I’ve found a few things that you should consider looking at to optimize your user interface.
GUI Visibility
Introduction To GUI Visibility
One common thing people do is like to tween their GUI. Usually, when people animate their UI, they animate it off the screen to hide it. This is good because it accomplishes what they want, BUT they usually do not toggle the visibility of the GUI.
So how does toggling the visibility of a GUI help? Well, you may have noticed already but turning the visibility of a GUI off means that you are disabling functionality of the GUI. As we know, the less functionality the better.
You can read more about GuiObject here, the article talks about other benefits to toggling the visibility such as disabling rendering for that time and etc.
Static GUI
Introduction To Static Graphical User Interface
Static GuiObjects will reduce rendering calculations which will in return benefit you.
Replies To Consider
You can find more information here.
ViewportFrames
Introduction To ViewportFrames
ViewportFrames were recently introduced Roblox allowing 3D objects to be rendered onto a 2D screen. ViewportFrames are now very popular among games and are a extremely powerful tool. That being said, you should consider how expensive it is rendering a 3D object onto a 2D screen.
This isn’t the end though, recently WorldModel
's were introduced allowing physic calculations to be done in the GUI. This allowed animations to be played and rendered as well as adding other functionality to the ViewportFrame. While this is awesome you should limit the amount of WorldModel
's used since these are very expensive.
UICorners
Introduction To UICorners
Like Viewportframes, UICorners are relatively new and come in very handy. Obviously, with this new tool, there are downsides. Roblox has listed the pros and cons which I will quote here:
So when should you use UICorner? Well, if you’re simply trying to make frames with smooth corners I suggest using 9-Slice. For cases where this is unavoidable (for example, needing to curve a ViewportFrame or ImageLabel’s Corner) you should use UICorner
's.
Resources And References
Scripting
Garbage Collection and Memory Leaks in Roblox - What you should know
PSA: Connections can memory leak Instances!
https://devforum.roblox.com/t/what-are-bad-programming-habits-that-you-see-often-by-scripters/761033
https://devforum.roblox.com/t/localizing-variables-but-not-functions/369038
How to use a Maid class on Roblox to manage state
Consume everything - how greedy meshing works
Algorithm efficiency and alternatives to table.find
PSA: Don't use Instance.new() with parent argument
Part Pooling - Increase performance with many parts
PartCache, for all your quick part-creation needs
GUI
Static UI Performance Improvements
Meshing
Differences between High Poly Vs Low Poly 3D models | by Arjun Patel | Medium
Levels of Detail for Mesh Parts
Quick Guide Into CSG: Increasing Performance of Unions & Meshes
Introducing Level of Detail for CSG Parts
Building
Introducing Level of Detail for CSG Parts
Building Optimisation | Tips and tricks!
BasePart
Credits
Contributors: @Mystifine // @EDmaster24 // @colbert2677 // @DragRacer31
Feel free to contact me with more information I can add onto this post.
Last Update: 2020-10-13T04:00:00Z