Performance can be a big issue in gaming. Lag and long loads can interrupt play and possibly dissuade players from playing again. Roblox is constantly working to improve game performance on its end, but there are things developers can do to improve how their games run as well.
Knowing where to focus your efforts when working on performance is very important. Your game may have a very inefficient piece of code, but if it is not run often or at critical times, fixing it will likely not improve the game experience and uses time that could have been spent fixing more important issues. Roblox offers several tools to monitor the status of your game to help determine where optimization might be useful.
One of the first steps to see where problems may lie is to use Studio’s Script Performance window. This window shows all of the scripts that are running in your game and how much processing power each script is using. In general, if a script’s activity is over 3%, it is probably worth checking to see if you can optimize it. The Script Performance window also helps let you know if changes you have made have indeed increased performance (or possibly decreased!).
Articles/Script Performance Window for more.
Another view that can help determine if your game is slowing down in certain areas are the Diagnostics windows. These windows can be brought up in Studio and even when you are running a game. The diagnostics windows provide a lot of information, much of which you will likely never need to be concerned about. There are a few however that can help identify that there may be problems. Note that these windows will not identify where problems are, but can show you that you need to search for the cause of certain slow behavoir:
Instances (under Shift + F1): Shows the total instance count. This lets you see if your number of Instances are remaining fairly stable. For most games, the number of instances will likely fluctuate, but should remain generally around one number. If the number of instance in your game is growing continuously, that could indicate a problem. Even if the game is adding Instances at a slow rate, this can eventually take a very large toll on performance. If this number is growing look around your game for a script that may be making more Instances than it should, or check to make sure that temporary Instances are being properly cleaned up (see the Destroy function).
FPS (under Shift + F5): Shows how quickly various Roblox game processes are running. Ideally the FPS, Physics, and Render should be running close to 60 fps. If they are not, try some of the optimization tricks below and see if they help increase these numbers.
A large contributer to poor performance can come from how a game is scripted. Not all code is written equally, and there are some ways of performing tasks in Lua that are faster and more efficient than others.
Use Local and avoid globals
In general it is better use local variables than global ones in your code. Making a variable local is very easy, simply include the name local before the variable when you are making it:
x = "test" local y = "test"
In the above example, the variable y is a local variable, the variable x is not. Because of the way Lua works, y will be much quicker to lookup than x when it is used later in the code. Granted, this lookup speed increase isn’t much if y is only looked up a couple of times, but if there is a loop that uses it thousands of times, that small increase in efficiency adds up.
Use Wait Responsibly
Sometimes it is useful for a game to check a condition periodically, or needs to repetitively repeat a function. Putting this code in a loop with a wait() call is the general solution, but one must be careful, especially if the code has expensive calls (such as accessing DataStores). If a script with a wait loop is causing performance problems, check to make sure that if that loop could be run less frequently by increasing the wait. This is explained in depth in this Roblox blog post.
Not all performance improvements are made in scripts. There are some things in places that can contribute to slow gameplay and lag.
Not all Roblox players are playing on top of the line machines. Some are using laptops or older desktops. They may also be playing on slower connections. One setting that can help is StreamingEnabled. With this on a client will not load the entire game, but will rather load the game while the player is playing. While content is streamed into the client as the player moves around the world, less important content will be streamed out which lowers the memory the game requires. For example, if a game has a large map, StreamingEnabled will only show the parts of the map that are close to the player, while very far away parts will not render.
Keep in mind that StreamingEnabled does have some limitations and restrictions on scripting. To learn more consult the StreamingEnabled guide.
Reduce Part Count
Large games with a lot of content can provide excellent gameplay experiences. Attention to detail can help with immersion and atmosphere. That said, there is a limit to how much a game can handle. There is no hard set rule on part count but suffice to say the more parts a game has, the slower it will run. This means you may have to be strategic to where you focus the detail and embellishments in your environments. Suppose a game takes place in a futuristic city with ships flying far overhead. If the player can never get close to these, there is not much point in making these ships out of hundreds of parts when perhaps a dozen or even fewer may suffice.
Very large worlds may also benefit from TeleportService. If a fantasy world has a several towns, a castle, a cave, a haunted forest, it is possible to put each of these environments in their own separate place, using teleports to move between them at specific points. This will allow each individual environment to have a higher level of detail with more parts. That said, teleporting does take time and introduces more complexity if persistent information is a concern (in which case Data stores may be useful).
Prefer parts that are not moving to parts that are moving by Anchoring them. An Anchored part is more efficient in regards to rendering and physics than a part that is not anchored and not welded to other parts.
Use Transparency on parts sparingly. Transparent bricks inhibit a lot of internal rendering optimizations, so only use it if you must. Additionally, avoid using many transparent layers (e.g. using one big transparent part is cheaper than using a stack of 10 big transparent parts).
Prefer using part Materials to Texture objects - materials are more efficient in regards to replication and rendering. The only drawback is that depending on the performance of your game, Roblox engine may decide to disable material rendering so not all users will see them.
Consider dynamic lighting. Lighting rendering cost depends on the cumulative volume of light objects in your level. Using several smaller lights may be cheaper than using a big light; using one light with high Brightness is cheaper than using many intersecting lights with lower Brightness.
Prefer lights that are not moving to lights that are moving.