Script reading data does a lot of lags

Hello!
So I’ve been trying to make a infinite part terrain generation for about 5k block map size. (5000 * 5000 in total blocks) which i know that it will cause a super lag. First I tried out the 1k map size which doesnt make a lots of lag but it does when im trying to load other blocks


This is only a 1k map size and im worried that by doing more than this it’ll crash a game.

Please help!

1 Like

For this you should probably be doing what Minecraft does, and load it in regions (chunks in minecraft).
Alternatively, you can use StreamingEnabled on the player to do it.

Note that you would have to get the server to generate the whole map first, then let the client access the map

4 Likes

You mean like getting the same reading code but instead as a local script?

I’m note sure what you mean.

Have the server script generate the whole map, even if no player is near it. Then make sure that StreamingEnabled is on. This means the player will only see what is near to them

https://developer.roblox.com/en-us/api-reference/property/Workspace/StreamingEnabled

1 Like

I tried already and it crash. It pretty sure it was because it generates about 500k blocks which the game cannot handle.

Minecraft has a specially engineered method of optimizing a game with hundreds, if not thousands of tiles being loaded in at a time. It’s no easy task, and a game engine like Roblox probably isn’t able to handle it.

This video does a great job of covering it.

1 Like

So the problem isnt about reading the data. But because of rendering?

Correct. There’s only so much geometry you can load before it gets laggy.

1 Like

Not a particularly true statement, its most definitely possible but will most likely require a lot of work and hard thinking.

like what @PoppyandNeivaarecute said your best bet is probably loading the map in chunks, this would mean dividing the map into a grid and only loading sections that are in close proximity to the player. In terms of how to store these chunks, there’s lots of different ways and each have their pros and cons so don’t be afraid to experiment with what you think might work. It would also help to load all the blocks in a chunk incrementally (or even load them in chunks themselves) and not all at once. You could combine all this with a caching system that only records the positions of chunks and change the transparency of all the blocks in unloaded chunks to 1 instead of deleting them so that way you wont have to waste memory creating new Instances.

1 Like

Thanks, I’ve got other info. I changed the map size of 200 and 2000. Because Im curious that it might be a problem from reading a data. A 200 map size doesnt does lags when loading a map. While a 2000 map size does a 5-7 seconds freeze before loading a map. Both of these generations have a limit load distance of 30. Which I think it might be a problem about a data reading too

Minecraft uses a system called “face culling” in its mesh generation. This pretty much means that only the faces of blocks that need to be shown are rendered. If you have two blocks next to each other, the faces touching each other aren’t visible and hence Minecraft doesn’t even render them. The same goes for whole blocks that can’t be seen, such as blocks two or three layers in the ground.

You might be able to emulate this in Roblox in conjunction with a “chunk” system as others in this thread have described. Start by just hiding blocks that aren’t visible, and then you could probably move on to face-culling if that doesn’t reduce lag enough.

Hope this helps, feel free to ask for any clarification.

Good luck.

1 Like

I made a raycast system. I’ll improve that and I’ll report the result!

1 Like

For this situation i would load a customizable chunk radius around the player and only render the blocks that are visible ie not loading in the blocks underneath and only loading them when they are needed (block is broken)

When you load the map are you creating the instances for every block in the map? Because if so that isn’t the most optimal way to do it, what you should do is load the location of every block as a Vector3 or CFrame and only load the instances in chunks within close proximity around the player.

No First I loaded a map first then delete the parts that is out of range or not in sight

That’s probably why your having the lag issue, try the method I mentioned and lmk if it helped.

1 Like

So I tried out but it didnt work. I think i forgot to mention the code too

function Reload()
	local player = game.Players:WaitForChild("bookgamery555gta")
	--print(#datatable)
	for i,v in pairs(game.Workspace.Maps:GetChildren()) do
		if v:IsA("Part") then
			local direction = (player.CamCFrame.Value.Position - v.Position).Unit * 9999
			local ray = Ray.new(player.CamCFrame.Value.Position,direction)
			local hit = workspace:FindPartOnRayWithIgnoreList(ray,{player.Character})
			local distance = (player.Character.PrimaryPart.Position - v.Position).Magnitude
			if distance >= game.Workspace.MaxLoadedDistance.Value/2 then
				for i,a in pairs(v:GetChildren()) do
					if a:IsA("Texture") or a:IsA("Decal") then
						a.Transparency = 1
					end
				end
			else
				for i,a in pairs(v:GetChildren()) do
					if a:IsA("Texture") or a:IsA("Decal") then
						a.Transparency = 0
					end
				end
			end
			if distance >= game.Workspace.MaxLoadedDistance.Value - 10 and (hit ~= v) then
				v.Name = "Deleted:"..distance.." studs"
				v.Parent = nil
			end
		end
	end
	for i,v in pairs(game.Workspace.Trees:GetChildren()) do
		if v:IsA("Model") then
			local distance = (player.Character.PrimaryPart.Position - v.PrimaryPart.Position).Magnitude
			if distance >= game.Workspace.MaxLoadedDistance.Value - 10 then
				v:Destroy()
			end
		end
	end
	for i,v in pairs(datatable) do
		local distance = (player.Character.PrimaryPart.Position - v).Magnitude
		if distance < game.Workspace.MaxLoadedDistance.Value then
			local alreadyexist = false
			for i,v in pairs(game.Workspace.Maps:GetChildren()) do
				if v:IsA("BasePart") then
					if v.Position == v then
						alreadyexist = true
						break
					end
				end
			end
			if alreadyexist == false then
				local detected = false
				local part = Instance.new("Part",game.Workspace.Maps)
				part.Anchored = true
				part.Size = Vector3.new(displacement,displacement,displacement)
				part.Position = v
				for i,v in pairs(game.Lighting.BlockTexture.Grass:GetChildren()) do
					v:Clone().Parent = part
				end
			end
		end
	end
	for i,v in pairs(treedatatable) do
		local distance = (player.Character.PrimaryPart.Position - v).Magnitude
		if distance < game.Workspace.MaxLoadedDistance.Value then
			local tree = game.Lighting.Tree:Clone()
			tree:SetPrimaryPartCFrame(CFrame.new(v))
			tree.Parent = game.Workspace.Trees
		end
	end
	player.Character.PrimaryPart.Anchored = false
end

I think most of the lag are cause by the data reading. Or Am I wrong?

Yea if a for-loop takes too long it will timeout. Not sure on the specifics though.

1 Like