How do i make the game not go to 0.5 frames per sometimes when loading a map

so i have decided to change how map loading works in my game to be akin to that of ue4’s

a map group is loaded (basically an area with more maps in it, example below):
image
and then the client will check if the map fully loaded before telling the server to continue.

however, when you load a map the game slows until loading is finished and this doesn’t look too good
(also additional note: the fps is capped to 30 in this recording. the cap is toggleable)

is there any way to improve performance?

here’s the main code (i warn you though it is incredibly messy, this is because i suck at coding)

local module = {}

if game:GetService("RunService"):IsClient() then
	error("You can only load maps on the server.")
end

function module:LoadMap(MapName: string, Checkpoint:Part, OverheadText:string?)
	local plr = game.Players:GetPlayers()[1] --//it's a singleplayer game i know this is horrible but i am NOT passing a player argument every time.
	local OldMap = workspace.LoadedMaps:GetChildren()[1]
	workspace.Technical.DataValues.CurrentCheckpoint.Value = Checkpoint.Name
	workspace.Technical.Events.RemoteEvents.FadeScreen:FireAllClients(true)
	task.wait(1)
	workspace.Technical.DataValues.CurrentMap.Value = MapName
	local copy = game.ServerStorage.Maps[MapName]:Clone()
	copy.Parent = workspace.LoadedMaps
	workspace.Technical.GameValues.CurrentMap.Value = copy
	plr.Character.HumanoidRootPart.Anchored = true
	plr.Character.HumanoidRootPart.Position = Checkpoint.Position --//moveto makes you float for a sec :(
	workspace.Technical.Events.RemoteEvents.LoadMapOnClient:FireAllClients(copy, #copy:GetDescendants())
	workspace.Technical.Events.RemoteEvents.LoadMapOnClient.OnServerEvent:Wait()
	plr.Character.HumanoidRootPart.Anchored = false
	workspace.Technical.Events.RemoteEvents.FadeScreen:FireAllClients(false)
	if OverheadText ~= nil then
		workspace.Technical.Events.RemoteEvents.OverheadText:FireAllClients(OverheadText)
	end
	OldMap:Destroy()
end

return module

as for the client:

workspace.Technical.Events.RemoteEvents.LoadMapOnClient.OnClientEvent:Connect(function(map, PartCount)
	local number = 0
	if #map:GetDescendants() >= PartCount then
		workspace.Technical.Events.RemoteEvents.LoadMapOnClient:FireServer()
	else
		local connection = Map.DescendantAdded:Connect(function()
			number += 1
			if number >= PartCount then
				workspace.Technical.Events.RemoteEvents.LoadMapOnClient:FireServer()
			end
			connection:Disconnect()
		end)
	end
end)

thanks, and i’m sorry you had to read that.

1 Like

You could try loading in increments instead of all at once. Load on object, wait a 1/20th of a second, repeat until finished.

I would also have suggested to turn off GlobalShadows when loading as well, but it seems that’s off anyways.

1 Like

that’s not possible with my current game structure because there is no way for me to parent them correctly, and i would have to run recursive loops and it’s genuinely not worth it. this isn’t even taking into account the fact that there aren’t always just submaps in map groups, there are scripts parented directly because it’s related to the general area (this being an example)
image

is there a reason to clone the map rather than setting its parent to workspace/replicatedstorage ?

1 Like

you could load everything at the same time and then turn on streamingenabled so roblox does the loading/unloading for you which is probably much faster

and it also loads only the parts of the map close to the player

Are you really letting the Client decide if the Server can continue…?

Did I read that right?

1 Like

you should keep all the maps in serverstorage, and instead of cloning them (which is probably whats lagging the place), you should just move them

the above code just clones every object of the map which is extremely poor for performance

so instead you should do

HEIRARCHY:

ReplicatedStorage
L Maps
  L MapA (eg: crossroads)
    L Map A OBJECTS (just pretend this is the maps folders)
  L MapB (eg: Roblox HQ)
    L Mab B OBJECTS (also just pretend this is the maps folders)

CODE:

local ServerStore = game:GetService("ServerStorage")
local MapsFolder = ServerStore:WaitForChild("Maps")

local LoadedMaps = workspace:WaitForChild("LoadedMaps")

local Maps = {
     MapA = MapsFolder .<map a name>
     MapB = MapsFolder .<map b name>
}

------------ just skipping to where you set the map

MapsFolder[MapName].Parent = LoadedMaps 
LoadedMaps[OldMap].Parent = MapsFolder



you dont need to clone/delete the map every time as that is most likely whats lagging your game. you can just parent the main map to the needed folder and change the value of MapA or MapB (so on so forth) to whatever its parent is

obviously there will be issues here as im not testing any of this, but that shouldnt be majorly hard to fix/change depending on your needs

i wanted to avoid that originally because i wanted the maps to fully reset however i realized there really isn’t a reason to and because in the wider scheme of things it probably will make my job easier.

(@GE_0E tagging you too since you asked)

1 Like

it’s a single player game, i forgot to mention in the post but there is a comment that mentions it in the code

i did use streaming until i realized:

  1. it ruined the atmosphere that was already frail because you can just unload half the map by putting your graphics below 5
  2. it broke every local script and i wanna use a lot of local scripts for non-important stuff since it is a singleplayer game