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 @SeargentAUS 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

This is 100% Possible to do with chunk generation. However the code will be very complex.

step1: Create a block map entirely by hand and turn the cframe and texture data into a table dictionary. or use noise to generate a map (im not sure how to do this but it is possible)

step2: on client side load in the chunk the player is in

step3: any action taken by the player on the client needs to be checked by the server.
EX: breaks a block check server if block exists, moves to a certain position make sure that area doesnt clip the player into blocks/is it possible for the player to reach that area from previous location.

that is a very simplified version of what you need to do. as to do this there will need to be many checks and with robloxs engine performance, lower end devices would struggle. there is a youtuber who has been creating this and he has a very good base start for it.

The problem I remember is in a getting data step. Lets imagine a scenario where you want to load a chunk on Position 0,0. The first think you would need to do is to get the data table on the serverside script. The problem is that there is a lot of datas that needs to be read it will make a sudden lag before giving the data back to the player.