Optimization Tips for 300+ Player Sessions

Hiya.

I am helping out on an event game that is capable of getting roughly ~300 real players in a single session.

Optimizing hasn’t always been my field and, obviously, given the size of the game, I need some tips on how to optimize the place. Mostly, networking. Thanks.

1 Like

you need to be very efficient in the way you manage server and client. so like client should only handle visuals and stuff and server only handles things that really need to be synced… to put it simply

2 Likes

Could you tell us more about what features the game has and how much experience you have with scripting?

General

I’m an optimization freak and recently finished two game optimization commissions, so I hope my words hold some weight.

But just some general advice, if you go to the Learn section in the Creator Hub, Roblox has some great videos on optimization and good practices for less memory.

Here we go…

Optimizing a game stems from the system’s architecture. Ensuring clean communication between scripts by having a modular system, using frameworks (i.e., Knit/module loaders, your own framework) will reduce tangled/spaghetti code.

Also I like to use libaries like Signal for easier cross-script communication, Packet as a RemoteEvent replacement, Maid to handle connections in the same scope/entire script, and certainly use a data library like ProfileStore for your Datastores. And the reason why I recommend these is that they really just make your work so much easier.

You’ll learn to optimize scripts and systems overtime (if you choose to, and you probably should). A lot of free models/kits/whole systems made by other people could have deprecated functions and outdated code. If your game has these, you should replace or look into these scripts and look for optimization opportunities there too. Also checking the output will show dead giveaways of broken/dated functionality.

Understanding and implementing concepts like OOP/ECS, modular programming, client-server replication are also game-changing. Refactoring some parts of the game to implement these will help with ease of use, future scalability, and performance.

The final caveat is that sometimes it’d just be best to rewrite parts, if not the whole game, but that may not be feasible if the game is too big already and you don’t call the shots.

Specific Tips

  • If your game has a lot of instances being created (i.e., bullets, sounds, and anything else temporary), consider looking into object pooling.
  • Use dictionaries instead of large elseifs. A rule I have is to not use elseifs at all.
  • Turn commonly typed things into variables as much as possible. For instance:
if player.leaderstats.XP >= 10 then
end

if player.leaderstats.XP >= 20 then
end

could be turned to

local xpValue = player.leaderstats.XP.Value
if xpValue >= 10 then
end

if xpValue >= 20 then
end
  • Also apply the same concept to copy-pasted blocks of code and turn them into reusable functions.
  • Use the Find in Place tool (ctrl + shift + S) to search for variables, etc, within all of the game’s scripts and see which scripts use certain module functions/variables, etc. This also makes it easier to debug large systems. It’s basically the script Find tool (ctrl + F) but searches every script in the game.
  • Compare snapshots in the DevConsole to find scripts that degrade performance (source)
  • Somtimes, you’ll see the same TweenInfo in every TweenService:Create() line, so just turn that into a variable and reuse it. I like to just define all my TweenInfos as variables for this purpose.
  • Understand when to use WaitForChild and spot signs of redundant uses in the game (source).
  • When creating a new instance, parent it last separately from the Instance.new() function. (source 4:05-6:54).
  • Never do while wait(x) do (source)

This is just all I can write off the top of my head right now, but yeah. Hope this helps!

2 Likes

I am not the creator of the game, rather got a contract work for it. Optimisation is just a part of that.

Correct, that is step 1. Let me expand on what this is about so yall can tell me how to properly do it.

This is an event game (community-driven game-night like) where a host makes players participate in minigames. Simple enough.

On a good day and for about half an hour, a single server instance can reach upwards of 300 concurrent players. What I am mostly looking to fix is server health and networking because, clearly, this absurd amount of players isn’t gonna do well.

Again, I do not own the game, I am simply tasked with fixing it.

Problem 1: Replication

The game is currently using standard humanoids. Everyone has the freedom to move around and jump.. except when they don’t. Yes, we are talking about 200+ players constantly moving and jumping.

Problem 2: Server authority

I have considered switching to Chickynoid, or any other server based humanoid, that would allow us to reduce replication packets sent. Problem is that this is probably overkill for a simple party game where competition isn’t really prioritised in comparison to actual competitive games that would benefit from server authority.

Problem 3: Proposed solution

My proposed solution was to split the main game instance into a master-slave server architecture: Host would be in the master server, sending commands, killing players, etcetera. This isn’t a masterfully crafted party game; how it works is via three Admin modules, these being HD, Kohl’s (primarily and largely), and Adonis. Kills are performed using a standard sword that damages on contact. This would still bring back the replication issue; MessagingService has a very low rate at which I can replicate to and from, and not sure if MemoryStores can do the trick.

Main symptoms are low server response speeds; sometimes the server can take upwards of 7 seconds to return a reply.

1 Like

Minimize networking overhead - seriously. Use client ↔ server communication only when it actually matters, and send as little data as possible each time (that includes setting properties of an instance on server)

“Networking libraries” often get it wrong. Having multiple RemoteEvents is actually good - it reduces dispatch overhead since you’re not shoving arguments into one event for the server to sort through.
Pack data using bit32 or tight binary buffers - algorithmically, not with “serializer” libraries. Nothing is magic. If you treat something as magic, you’re already losing optimization you don’t understand yet.

Take parallel into consideration (especially on a server if it has so many people in it); honestly, parallel would be your highest priority to take for almost everything when you don’t do write-on instance operations.
For computation or buffer operations (or bit shifting), consider using native code generation.
Consider using micro-optimizations; even 0.1-10% adds up a bit when you have such a huge server.

If you’re serious about performance, learn bytecode - it’s the only way to see what’s actually optimized under the hood.

And yeah, avoid bloatware modules or “single script architectures.” Those patterns look “enterprise-y” but perform like a brick. Only trust what you can prove through profiling and benchmarks.

Oh, and yes - StreamingEnabled is a must, but that’s the easy part.

Final tip: move any repetitive read operations off serial execution to parallel if possible.

There is a post I made where I and other people had sent some optimizations you may need https://devforum.roblox.com/t/code-optimizations-sharing/3882214


Maid and Signal is literally the opposite of optimization; what are you talking about?

Well, your best bet is to ditch humanoids entirely.
2D clothing can be applied (even if with a little quality loss due to Roblox’s tendency to destroy <1024 images), and 3D clothing can be replicated with cage setups.
There is a resource for 2D clothing UV unwrapping, and it’s very easy to do if you know Blender at least a little bit.
You do have to wait for SurfaceAppearance to be creatable at runtime, though, for it to work well.
This is for humanoid UV:

Use regular shirt template UV from Roblox if you want it to work outside of humanoids.

Character controlling will have to be written entirely from scratch, and I myself have never written one, so I can’t say much.

Also, Roblox’s server isn’t that bad, as people say; it would be most of the time better than the “host” player’s computer, and the fact that players will have to talk to the host through the server anyway eliminates any benefit.