Hello, I am currently trying to figure out why my game is having massive lag spikes when their are about 30+ people in the game, It’s been about 2ish days and I still haven’t found the reason.
I conducted multiple tests, one in the main game, one in the basic no map game and another game that is similar with no issues with 80 players.
The 2 clips with our game had about 40 players each nearing the end, you can easily tell when the lag starts.
We also noticed that when a bunch of players join at the same time, a massive lag spike happens. I looked into MicroProfiler and noticed this when the player joins (not sure if it means anything or not)
Hard to tell from just the info given, but the most likely cause of this is that the server starts to lag out because you got players probably running server scripts and what happens is that each player that joins then makes a duplicate of that server script they are running which puts more load on the server, if you can think of any script with maybe loops inside the startercharacter that is a server script or maybe when the player joins you have a loop start running on the server or anything not just a loop really. If you want to make a performant game with lots of players take the load off of the server and start working on transferring code that is run by the player into client scripts (local scripts) instead of server scripts. This include, remote events.
Everything is pretty much client sided unless it’s supposed to be on the server such as data, etc. Pretty much when each player joins, there is a PlayerManager module in ServerScriptService which creates a new player module for each player, this holds things such as requesting teams, assigning overhead tags, etc. As far as I’m aware, there aren’t any loops within those 2 scripts, so I really have no clue.
When I was tracking them, I didn’t really see anything out of the blew but I’m also not an expert on it so I’m not sure if anything was bad or not, which is also why I provided the clips.
This is the playeradded function in PlayerManager if you woud look to see it
function PlayerManager:PlayerAdded(player : Player)
if self.clients[player] then
return self.clients[player]
end
if not player then
repeat task.wait(.1) until player
end
local loaded = Instance.new("BoolValue", player)
loaded.Name = "_LOADED"
self.clients[player] = playerModule.new(player)
local client = self.clients[player]
if not client then
player:Kick("Could not get client. Please rejoin")
return
end
task.wait(1)
--/ Datastore check
local dataStore = DataService:Retrieve(player)
if not dataStore then
local maxAttempts, attempts = 5, 0
for i = attempts, maxAttempts do
if dataStore then
break
end
task.wait(5)
dataStore = DataService:Retrieve(player)
attempts += 1
end
if not dataStore then
local str = string.format("Could not retrieve %s data within %s attempts", player.Name, attempts)
warn(str.." | Player Manager")
player:Kick(str)
return
end
end
--/ Connections
player.CharacterAdded:Connect(function(character)
srv.run.PostSimulation:Wait()
Collision.Set(character)
local team = player.Team and player.Team.Name
local isMenu = team and team == "Menu"
if isMenu then
task.spawn(function()
local hrp = character:WaitForChild("HumanoidRootPart", 4)
if not hrp then
return
end
hrp.Anchored = true
end)
end
local humanoid = character:WaitForChild("Humanoid")
humanoid.Died:Connect(function()
task.wait(4.5)
if character and character:IsDescendantOf(workspace) then
character:Remove()
end
end)
task.spawn(function()
self:UpdateSpawnLocation(player)
--/ Give players their teams tools
client:AssignLoadout()
end)
client:AssignTag()
end)
player.CharacterAppearanceLoaded:Connect(function(char)
for _,child : BasePart? in char:GetChildren() do
if child:IsA("CharacterMesh") then
child:Destroy()
elseif child:IsA("Accessory") then
local Handle: BasePart? = child:FindFirstChild("Handle") :: BasePart
if Handle then
Handle.CanQuery = false
end
end
end
end)
--/ Robux Spent
client.robuxSpent = dataStore.RobuxSpent
--/ Setup leaderstats
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local kills = Instance.new("IntValue")
kills.Name = "KOs"
kills.Parent = leaderstats
local money = Instance.new("IntValue")
money.Name = "Cash"
money.Parent = leaderstats
money.Value = dataStore.Cash
self.PlayerLoaded:Fire(player, dataStore, client)
self.Client.PlayerLoaded:Fire(player)
loaded.Value = true
end
I see than it can be either some sort of memory leak or the player data is too much for the server.
example of a memory leak would be not disconnecting things like connections or not cleaning up after players leaves if the players had anything associated to them.
you can look up more examples of memory leaks if needed, a lot of times it goes unnoticed and can cause a pile up. Which common after either a lot of people are in the game and the longer the server is up.
This is also pretty sure shown in the 2 clips, I would very much recommend scanning through them because you’re just telling me stuff I am already aware of.
In the second clip, you can see when a bunch of people join in, a bunch of Total Data KB/s get spammed.
Yes I also saw that, but I have no idea what scripts those are. I know roblox just displays random scripts it can’t display as Unknown. Any idea what they could be?
Honestly, it could be from some sort of free model or “backdoor” from a plugin, this includes plugins for everyone work on the game. (I would absolutely not go full terminator mode) this is just a worst case scenario. It could also be that maybe your map has some unanchored parts, its also know that having a lot of humanoids together causes lag.
I’ll send you a link of a guide that goes over most performance impacting practices.
In our game, we pretty much have a bunch of free model vehicles but as far as I am aware they’re fine as they were in our previous game which ran fine with 60 people. I do not believe it’s the map as in the clip with no map, it also has unknown spiking a ton.
Yeah, no clue if your other games were working fine with the same assets thats a real head scratcher. The first topic explains what unknown could be, so good luck, sorry I couldn’t be of more help
Gaps in graph indicate too much data is being sent and some has to be dropped.
Possible causes of high replication bandwidth are server-sided part position, attribute, property etc. updates.
Make sure to check your scripts for constant (every frame) updates to properties. Those are automatically replicated to every client by the engine.
I think I found what it was, it was a module I was using for the weapons called SecureCast, I think it was just too much for every client. I did a 30 player test like 10 minutes ago and it went pretty well, no lag at all. Later I’ll try and get a test with 50