Preventing a script timeout here?


function serialiser.Load(data)
	local b = Instance.new("BoolValue")
	b.Name = "WorldSaving"
	b.Parent = game.ReplicatedStorage.Files.Temp

	local function deserialiseInstance(data)
		local blockType = game.ReplicatedStorage.Files.BlockTypes:FindFirstChild(data.Name)
		local instance

		if blockType then
			instance = blockType:Clone()
		else
			instance = Instance.new(data.ClassName)
		end

		instance.Name = data.Name

		local parent = nil
		local success = pcall(function()
			for propertyName, propertyData in pairs(data.Properties) do
				local propertyValue
				if propertyData.Type == "BrickColor" then
					propertyValue = BrickColor.new(propertyData.Value)
				elseif propertyData.Type == "Vector3" then
					propertyValue = Vector3.new(unpack(propertyData.Value))
				elseif propertyData.Type == "Color3" then
					propertyValue = Color3.new(unpack(propertyData.Value))
				elseif propertyData.Type == "Vector2" then
					propertyValue = Vector2.new(unpack(propertyData.Value))
				elseif propertyData.Type == "UDim2" then
					propertyValue = UDim2.new(unpack(propertyData.Value))
				elseif propertyData.Type == "CFrame" then
					propertyValue = CFrame.new(unpack(propertyData.Value))
				elseif propertyData.Type == "UDim" then
					propertyValue = UDim.new(unpack(propertyData.Value))
				elseif propertyData.Type == "Number" then
					local convertedValue = tonumber(propertyData.Value)
					if convertedValue then
						propertyValue = convertedValue
					else
						propertyValue = propertyData.Value
					end
				elseif propertyData.Type == "EnumItem" then
					local enumType = Enum[propertyData.EnumType]
					if enumType then
						propertyValue = enumType[propertyData.Value]
					else
						warn("Failed to find Enum type: " .. propertyData.EnumType)
					end
				elseif propertyName == "Parent" then
					parent = propertyData.Value
				else
					propertyValue = propertyData.Value
				end
				if instance[propertyName] ~= nil and propertyName ~= "Parent" and propertyName ~= "DataCost" and propertyName ~= "ClassName" and propertyName ~= "className" then
					local success, errorMsg = pcall(function()
						instance[propertyName] = propertyValue
					end)
					if not success then
						if not string.find(errorMsg, "read only") then
							--warn("Failed to set property: " .. propertyName .. " - " .. errorMsg)
						end
					end
				elseif propertyName ~= "DataCost" and propertyName ~= "ClassName" and propertyName ~= "className" and propertyName ~= "Parent" then
					if propertyName ~= "Parent" then
						warn("Property not found: " .. propertyName)
					end
				end
			end
		end)

		if not success then
			warn("Failed to set properties for " .. data.Name)
		end

		for _, childData in ipairs(data.Children) do
			local childInstance = deserialiseInstance(childData)
			if instance.Name == "SpawnLocation" then
				if instance:FindFirstChild("SpawnDecal") then
					local a = 0
					for _, decal in pairs(instance:GetChildren()) do
						if instance:FindFirstChild("SpawnDecal") then
							a = a + 1
						end
						if a == 2 then
							instance:FindFirstChild("SpawnDecal"):Destroy()
							a = a - 1
						end
					end
				end
			end
			childInstance.Parent = instance
		end

		if instance:IsA("TextLabel") then
			instance.TextTransparency = 0
		end
		if instance.Name == "Cube" or instance.Name == "Ball" or instance.Name == "Wheel" or instance.Name == "VehicleSeat" or instance.Name == "Pin" then
			coroutine.wrap(function()
				instance.Anchored = true
				--print("E")
				repeat
					task.wait()
				until game.Workspace.Blocks:FindFirstChild("WorldConfig")
				repeat
					task.wait()
				until game.Workspace.Blocks:FindFirstChild("WorldConfig"):FindFirstChild("LoadingComplete")
				instance.Anchored = false
				if instance:FindFirstChild("AntiCloner") then instance:Destroy() return end
				local a = Instance.new("BoolValue")
				a.Parent = instance
				a.Name = "AntiCloner"
			end)()
		end

		if parent then
			local parentInstance = game.Workspace:FindFirstChild(parent)
			if parentInstance then
				instance.Parent = parentInstance
			else
				if instance:IsA("Folder") then
					if instance.Name == "Blocks" then
						instance:Destroy()
						instance = game.Workspace.Blocks
					else
						instance.Parent = game.Workspace.Blocks
					end
				else
					instance.Parent = game.Workspace.Blocks
				end
				instance.Parent = game.Workspace.Blocks
			end
		else
			instance.Parent = game.Workspace.Blocks
		end

		return instance
	end

	local deserialisedInstance = deserialiseInstance(HttpService:JSONDecode(data))
	local a = Instance.new("BoolValue")
	if not game.Workspace.Blocks:FindFirstChild("WorldConfig") then
		local c = Instance.new("Folder")
		c.Parent = game.Workspace.Blocks
		c.Name = "WorldConfig"
	end
	a.Name = "LoadingComplete"
	a.Parent = game.Workspace.Blocks:FindFirstChild("WorldConfig")
	b:Destroy()
	game.ReplicatedStorage.Files.Temp.WorldLoading:Destroy()
	return deserialisedInstance
end

This code loads a world, based off assembled data. Now, everything else is fine, HOWEVER due to the way it works, if you have about 150k instances, it will script timeout. How would I fix this?


Please note, adding a small task.wait() heavily slows down the speed of the script. For reference, about 5k instances would take FOREVER to load.

I couldn’t find which part of the script is loading instances but i guess that you are doing that in a for loop

you can use a loop inside the main loop with task.Wait() to load multiple instances per frame
example:
loads 100 parts per frame:

for i=1, 50 do

  for i=1, 100 do
     LoadInstance()
  end

task.wait()
end
1 Like

is that chatgpt’d

[works in studio, not in main game]

@GE_0E for your response, im testing it right now

Here

	local function deserialiseInstance(data)
		local blockType = game.ReplicatedStorage.Files.BlockTypes:FindFirstChild(data.Name)
		local instance

		if blockType then
			instance = blockType:Clone()
		elseif pcall(function() Instance.new(data.ClassName) end) then
			instance = Instance.new(data.ClassName)
		else
			warn("Invalid ClassName:", data.ClassName)
			return
		end

		instance.Name = data.Name
		local parentName = nil

		local success = pcall(function()
			for propertyName, propertyData in pairs(data.Properties) do
				local propertyValue
				if propertyData.Type == "BrickColor" then
					propertyValue = BrickColor.new(propertyData.Value)
				elseif propertyData.Type == "Vector3" and typeof(propertyData.Value) == "table" then
					propertyValue = Vector3.new(unpack(propertyData.Value))
				elseif propertyData.Type == "Color3" and typeof(propertyData.Value) == "table" then
					propertyValue = Color3.new(unpack(propertyData.Value))
				elseif propertyData.Type == "Vector2" and typeof(propertyData.Value) == "table" then
					propertyValue = Vector2.new(unpack(propertyData.Value))
				elseif propertyData.Type == "UDim2" and typeof(propertyData.Value) == "table" then
					propertyValue = UDim2.new(unpack(propertyData.Value))
				elseif propertyData.Type == "CFrame" and typeof(propertyData.Value) == "table" then
					propertyValue = CFrame.new(unpack(propertyData.Value))
				elseif propertyData.Type == "UDim" and typeof(propertyData.Value) == "table" then
					propertyValue = UDim.new(unpack(propertyData.Value))
				elseif propertyData.Type == "Number" then
					propertyValue = tonumber(propertyData.Value) or propertyData.Value
				elseif propertyData.Type == "EnumItem" then
					local enumType = Enum[propertyData.EnumType]
					if enumType then
						propertyValue = enumType[propertyData.Value]
					else
						warn("Invalid Enum type:", propertyData.EnumType)
					end
				elseif propertyName == "Parent" then
					parentName = propertyData.Value
				else
					propertyValue = propertyData.Value
				end

				if instance[propertyName] ~= nil and propertyName ~= "Parent" and propertyName ~= "DataCost" then
					local propSuccess, errorMsg = pcall(function()
						instance[propertyName] = propertyValue
					end)
					if not propSuccess then
						warn("Error setting property", propertyName, ":", errorMsg)
					end
				elseif propertyName ~= "Parent" then
					warn("Property not found:", propertyName)
				end
			end
		end)

		if not success then
			warn("Failed to set properties for", data.Name)
		end

		for _, childData in ipairs(data.Children) do
			local childInstance = deserialiseInstance(childData)
			if instance.Name == "SpawnLocation" then
				local spawnDecals = {}
				for _, decal in ipairs(instance:GetChildren()) do
					if decal.Name == "SpawnDecal" then
						table.insert(spawnDecals, decal)
					end
				end
				while #spawnDecals > 1 do
					spawnDecals[#spawnDecals]:Destroy()
					table.remove(spawnDecals)
				end
			end
			childInstance.Parent = instance
		end

		if instance:IsA("TextLabel") then
			instance.TextTransparency = 0
		end
		
		if instance.Name == "Cube" or instance.Name == "Ball" or instance.Name == "Wheel" or instance.Name == "VehicleSeat" or instance.Name == "Pin" then
			coroutine.wrap(function()
				instance.Anchored = true
				repeat task.wait() until game.Workspace.Blocks:FindFirstChild("WorldConfig") and game.Workspace.Blocks.WorldConfig:FindFirstChild("LoadingComplete")
				instance.Anchored = false
				if instance:FindFirstChild("AntiCloner") then 
					instance:Destroy()
					return
				end
				local antiCloner = Instance.new("BoolValue")
				antiCloner.Name = "AntiCloner"
				antiCloner.Parent = instance
			end)()
		end

		if parentName then
			local parentInstance = game.Workspace:FindFirstChild(parentName)
			if parentInstance then
				instance.Parent = parentInstance
			else
				local blocksFolder = game.Workspace:FindFirstChild("Blocks") or Instance.new("Folder", game.Workspace)
				blocksFolder.Name = "Blocks"

				if instance:IsA("Folder") and instance.Name == "Blocks" then
					instance:Destroy()
					instance = blocksFolder
				else
					instance.Parent = blocksFolder
				end
			end
		else
			local blocksFolder = game.Workspace:FindFirstChild("Blocks") or Instance.new("Folder", game.Workspace)
			blocksFolder.Name = "Blocks"
			instance.Parent = blocksFolder
		end

		return instance
	end

is the function that generates the instance.
How am I meant to implement the “for” loop?

Just make it for every 1000th object, add a task.wait() to relieve pressure in the workload.

Something like

count += 1
if count % 1000 == 0 then
task.wait()
end

during this process
Its impossible for you to want to run all of this all ar once thus you gotta have a slight delay before running certain segments, if it was possible we’d be way past the need to do this lol

Hello There!

I think that using actors to load the parts in parallel is a good way to solve this.
I’m a beginner at proggraming so i don’t know exactly how to use actors, but the Actor Page and the Exemple in the Roblox’s API might help

SkibidiVonKoo’s Idea can also be helpfull in this situation