Device-dependent script timeout for not so laggy script

I have a moderately performance costing script which has 3 nested for loops and instantiates a bunch parts in them. The parts are only parented to the workspace every time about 1600 or so are created, after which the script does task.wait(0.5).

The script works perfectly fine, with only a slight stutter when creating the first batch of parts, followed by almost silky smooth performance for the rest of the loop.
The problem is that on the other developer’s desktop PC (which, mind you, is much more powerful than my laptop in every way imaginable) the script crashes during the second of the five batches of 1600 parts. While the parts are being created, his studio also lags awfully, the game window becoming unplayable while the rest of the studio is usable.
After the script crashes, it gives out a “Script timeout: exhausted allowed execution time” error.

An attempted solution was to set the script timeout setting in studio to -1, but that did not fix anything.
But what did work was to play the game on roblox’ servers, having it published. When the dev joined the public, roblox-hosted game server, the game worked perfectly fine, without any crashes or stutters.

Another thing worth mentioning is that if the guy joins the team create server after the heavy script has loaded, he still crashes! It seems like playing in studio is what causes this to happen, but i am absolutely clueless as to what could be causing this.

I can try sharing the script, but it contains references to other modules, so i’ll write the important stuff here:

local TILE_SIZE = 5 -- tile size, in studs
local TILE_PADDING = 0.2 -- padding between tiles, in studs
local LAYER_SIZE = 40 -- layer size, in tiles (TILE_SIZE * MAP_SIZE studs)
local LAYER_COUNT = 5 -- amount of layers
local LAYER_PADDING = 69 -- the space between layers, in studs
local OFFSET = (LAYER_SIZE * TILE_SIZE + (LAYER_SIZE + 1) * TILE_PADDING + TILE_SIZE) / -2

function generate(map)
	print("Begin generation for map " .. map.name)
	
	local TilesFolder = Instance.new("Folder")
	TilesFolder.Name = "Tiles"
	TilesFolder.Parent = workspace
	
	local height = 100
	for i=1,LAYER_COUNT do
		
		-- create layer
		local LayerFolder = Instance.new("Folder")
		LayerFolder.Name = tostring(i)
		
		local tiles = {}
		for xPos=1,LAYER_SIZE do
			wait(0.1) -- wait after creating row of tiles, used in desperate attempt to fix the crash
			for zPos=1,LAYER_SIZE do
				-- returns a tile based on weighted chance
				local tile:BasePart = map:getRandomTile() 
				if tile ~= nil then
					tile:PivotTo(CFrame.new(
						xPos * TILE_SIZE + OFFSET + xPos * TILE_PADDING,
						height, 
						zPos * TILE_SIZE + OFFSET + zPos * TILE_PADDING
						))
					tile.Parent = LayerFolder
				else
					warn("Tile on layer " .. i .. " at (" .. xPos .. ", " .. zPos .. ") generated nil")
				end
			end
		end
		
		LayerFolder.Parent = workspace
		height += LAYER_PADDING -- prepare height for the next layer
		
		task.wait(0.1)
		print("Layer " .. i .. " loaded!")
	end
end

Any ideas or fixes? Thanks in advance :smile:

2 Likes

WRONG category move to #help-and-feedback:scripting-support please and thank u.

:warning:

1 Like

My bad, i didn’t notice the second part of the category. Just changed it, should be right now

After fully reinstalling the studio multiple times, the problem still persists. It’s making the development of the game almost impossible.

After trying the solution in this response, the game no longer crashed, however the map generation broke, because spawn() is async. To try to fix that, i added a repeat wait() until threads <= 0, but this made the game crash again and the error to come back.

Here’s the code:

function MapManager.generate(map)
	print("Begin generation for map " .. map.name)
	
	-- create the folder for the layers/tiles and parent it to workspace
	-- that way, each layer gets replicated immediately after its creation (because it's parented)
	local TilesFolder = Instance.new("Folder")
	TilesFolder.Name = "Tiles"
	TilesFolder.Parent = workspace
	
	local height = START_HEIGHT
	for i=1,LAYER_COUNT do
		
		-- create layer
		local LayerFolder = Instance.new("Folder")
		LayerFolder.Name = tostring(i)
		
		local threads = 0
		
		local tiles = {}
		for xPos=1,LAYER_SIZE do
			for zPos=1,LAYER_SIZE do
				while threads > 10 do
					wait()
				end
				spawn(function()
					threads += 1
					
					-- tiles
					local tile:BasePart = map:getRandomTile()
					if tile then
						tile:PivotTo(CFrame.new(
							xPos * TILE_SIZE + OFFSET + xPos * TILE_PADDING,
							height, 
							zPos * TILE_SIZE + OFFSET + zPos * TILE_PADDING
							))
						tile.Parent = LayerFolder
					else
						warn("Tile on layer " .. i .. " at (" .. xPos .. ", " .. zPos .. ") generated nil")
					end
					
					threads -= 1
				end)
			end
		end
		
		repeat wait() until threads <= 0
		
		-- add the layer to the workspace
		LayerFolder.Parent = TilesFolder
		height += LAYER_PADDING -- prepare height for the next layer
		
		print("Layer " .. i .. " loaded!")
		task.wait(0.2)
	end
end

Any ideas for fixes?