A Roblox experience network performance is often ignored by beginner devs.
Who am I?
I am Wolo, the main scripter of the Roblox RTS game [( ✦ ) [RUSSIA] Conquest: Napoleonic Wars] ([RUSSIA] Conquest: Napoleonic Wars [Pre-Alpha] - Roblox) and ( ✦ ) Ages Of Iron 2: Punic Wars [Early Alpha]. I have been interested in RTS from 13. Over 2+ years of experience in Roblox scripting and 3+ years as freelancer.
I also have a short video about my experience as a Roblox RTS developer: My experience as a Roblox RTS games developer - YouTube
Important
This guide is aimed to help scripters, as there is not much other developer roles can do to optimize network usage, aside from reducing part count, compressing audio size… but this mostly helps loading time.
Essential thing to understand
When we talk about “bits” or “bytes” in this guide, we refer to the data size, less bits, less size.
A byte has 8 bits.
When talking about “replication”, we mean the server sending data to the clients / players for their devices to duplicate in their games
---------------------------------------------------------------------------------
Introduction: what do we mean by “network performance”?
When we talk about network performance of a Roblox experience, we mean how well the server is performing when sending data, how quick it sends the data, how fast it process the received data and how much it needs to send; the more data the server has to send to the clients, more time it will take, and therefore the laggier the game will feel.
This also includes making sure the server has enough resources to handle everything else, aside from sending and receiving data from the players. If the server CPU is at 100% usage and is completely occupied with other things, that means it will have to finish previous tasks before being able to send the data. Needing to send the data later means players wont see the game updating smoothly, meaning the game will feel laggy for them
Why is it important to have a good network performance / bandwith usage?
The reason was explained above, but basically, the longer the time the server needs to receive / send data to the players, the later will be the game updated for everyone.
But it also depends on the players internet connection!
Sure, but you can optimize your server network usage to still make a smoother experience for every player. Remember, if the network performance is bad, then does not matter how good the player internet is, the game will feel laggy.
How do I notice if my game has network performance issues?
This topic will be explained further in a section of this post, but you can notice it by seeing how much it takes for the server to do stuff. For example, clicking to move an object, and the game needing too much time to even start moving it. (In this example, it can also be very bad performance of the server in general)
---------------------------------------------------------------------------------
The Bandwith Art principle: less data, less processing time
The bigger the size of the data, the longer it will take the server to process and receive / send it, meaning more time before the game server continues. With this knowledge, the response is simple: just send your data compressed!.
Compressing the data that is sent to the server from players or the data that the server sends allows it to be smaller in size, meaning faster processing.
How do I compress the data?
I strongly recommend to make a modulescript that allows you to compress and decompress the data everytime with its functions.
But how do I compress!
There are different ways, some more effective than others. The most basic one and also probably the most ineffective is using arrays instead of dictionaries to send the data
From
{
Health = 120
}
To
{
120
}
Sure it reduces readability, but this basically removes a good part of the size of the sent data. But there is something better.
Buffers and bit32
(Bit32 is a complicated matter, here is a tutorial to learn it: [ADVANCED] Binary in Luau: Tutorial on Basic Computer Logic & Bit32 - Resources / Community Tutorials - Developer Forum | Roblox)
Buffers and bit32 allow you to compress the data even more, basically reducing the number of bits sent (understand bits as the size the data has). For example, if you want to send a number that is less than 128, it is pointless to send it the normal way.
Why?
Because Roblox assigns way more size / bits than necessary to send a number like that. Instead, we can make Roblox assign less using buffers / bit32. Learn this
{
--REMEMBER, A BYTE HAS 8 BITS
local NewBuffer: buffer = buffer.create(4) --The number in the parenthesis represents the bytes / size.
--buffer.write(BufferVariable, Data location in the buffer (in bits), value)
-- Remember, pay attention to the "i". buffer.writei8 is not the same to buffer.writeu8!
--The "i" stands for "signed", numbers that can only go from 0 to the max positive limit.
--The "u" stands for "unsigned", numbers that can go both positive and negative,
--but its max capacity is cut by half for positive numbers
--For example, a number of 8 bits can store 256 max. when signed, but only -128 to 128
--when unsigned
buffer.writei8(NewBuffer, 0, 10) --Write 10 as a value in the "0" offset / location in
--the buffer we created
-- When asigning more data, remember to account about previous values assigned size (in bytes!)
buffer.writeu8(NewBuffer, 2, 10)
RemoteEvent:FireAllClients(NewBuffer)
-----------------------------------------------------
--Reading the data!
local BufferToRead: buffer = NewBuffer
--The letter has to match! You cant read the values as unsigned if you wrote them as
--signed
local Value = buffer.readi8(BufferToRead, 0) --buffer to read, the location of the data
-- you wanna get
Buffers have way more methods, bigger numbers capacity than what was demostrated here, but with this simple example you should understand how to use it. The documentation is here:
buffer | Documentation - Roblox Creator Hub
How do I know how much bytes do I have to assign when using buffer.create()?
Divide the number bits by 8. For example, if you want to write a number of 64 bits:
64 / 8 = 8 bytes!
This is too complicated! Is there an easier way???
Of course there is, some users have made modules that help with all of this of compressing / decompressing data!
Packet - Networking library - Resources / Community Resources - Developer Forum | Roblox - (made by @5uphi, probably the best networking module!)
ByteNet Max | Upgraded networking library w/ buffer serialisation, strict Luau and RemoteFunction support | v0.2.1 - Resources / Community Resources - Developer Forum | Roblox - (made by @Lightning_Game27)
Send less number! You do not need to send everything
Lets say you have this dictionary
{
WeaponType = “Sword”,
Price = 120,
Damage = 200,
Speed = 20
}
And now lets say you want to send WeaponType only. Some beginners developers may send all the table values, when 3 of the values it has are not necessary.
Imagine a CFrame and you need to send only the position to the client. Why send the entire CFrame when you can send CFrame.Position?
You should not be sending CFrame data like that unless you are using one of the modules mentioned, preferably use one buffer and store the position numbers in i16-i32 values if necessary.
Unreliable remote events
One variant of remote events that the server allows itself to ignore in order to save system resources if necessary. Most of the time you wont need this, but in some specific ocasions it may be useful. Remember, it has a 1000 bytes limit! Remote events do not have a size hard-limit!
Lets put a random example; lets say you wanna send a event for players devices to make X fire particles emit in a location. In this case, its better to use unreliable remote events, as it does not matter that much if the server decides to ignore and cancel the event.
Server simulates, client creates the visuals
Lets say you have a shooter game where the bullets are physical objects (plasma guns, for example). The server does not need to have the physical objects, it just needs to know where the bullet is, the direction, speed and origin.
Taking this in mind, you can just make the bullets objects appear phisically for players, and destroy them if the server detects they hit something. That way, you save the data of replicating the objects from the server to the client. It can really help when you have a lot of bullets
Its not only limited to this. Particles? RTS 3D Units?
If there is no need to have something physical on the server, dont do it. Let the clients make a replication themselves. Your server network performance will thank you.
Checking bandwith usage
Simple, using developer console (open it in the menu, typing /console in the Roblox default chat or pressing F9). To check the bandwith usage in the developer console, go to ServerStats, and check for the property called “Total Data KB/s”.
How do I know if there is too much bandwith usage / bad network performance?
Generally, if Total Data KB/s is over 100, you will probably need to optimize a few
--------------------------------------------------------------------------
Extra
Remember, compressing data will not do much for your game if the code is unoptimized and the game runs like shit because of it. Make sure to optimize your code!
Things like spawning a lot of moving objects in the server will lag the game due to the amount of data about the objects needing to be replicated to the clients.
---------------------------------------------------------------------------
End
Thank you for reaching the end of this guide. I may add more details in the future! If you wish to support me, you can do so by joining this game and donating: Wolo - Donation Place - Roblox
Other posts of mine:
