My module makes the game very laggy

My module script is getting more and more laggy with more lines of code in it
How should i make the script less laggy

local TERRAIN_HEIGHT_COLORS = {
	[-100] = Color3.fromRGB(216, 204, 157); -- sand yellow
	[-50] = Color3.fromRGB(72, 113, 58); -- grassy green
	[0] = Color3.fromRGB(72, 113, 58); -- grassy green
	[75] = Color3.fromRGB(227, 240, 255); -- stone grey mountain
}
local X, Z = 4, 4
local WIDTH_SCALE = 15
local HEIGHT_SCALE = 100
local TERRAIN_SMOOTHNESS = 50
local MIN_TREE_SPAWN_HEIGHT = -20
local MAX_TREE_SPAWN_HEIGHT = 20
local TREE_DENSITY = 2
local MODEL_DENSITY = .1
local MODEL_DENSITY = 100000000
local SEED = workspace.SEED.Value

local wedge = Instance.new("WedgePart");
wedge.Anchored = true;
wedge.TopSurface = Enum.SurfaceType.Smooth;
wedge.BottomSurface = Enum.SurfaceType.Smooth;

local function draw3dTriangle(a, b, c)
	local ab, ac, bc = b - a, c - a, c - b;
	local abd, acd, bcd = ab:Dot(ab), ac:Dot(ac), bc:Dot(bc);

	if (abd > acd and abd > bcd) then
		c, a = a, c;
	elseif (acd > bcd and acd > abd) then
		a, b = b, a;
	end

	ab, ac, bc = b - a, c - a, c - b;

	local right = ac:Cross(ab).unit;
	local up = bc:Cross(right).unit;
	local back = bc.unit;

	local height = math.abs(ab:Dot(up));

	local w1 = wedge:Clone();
	w1.Size = Vector3.new(0, height, math.abs(ab:Dot(back)));
	w1.CFrame = CFrame.fromMatrix((a + b)/2, right, up, back);
	w1.Parent = workspace;

	local w2 = wedge:Clone();
	w2.Size = Vector3.new(0, height, math.abs(ac:Dot(back)));
	w2.CFrame = CFrame.fromMatrix((a + c)/2, -right, up, -back);
	w2.Parent = workspace;

	return w1, w2;
end

local function getHeight(chunkPosX, chunkPosZ, x, z)
	local height = math.noise(
		(X/TERRAIN_SMOOTHNESS * chunkPosX) + x/TERRAIN_SMOOTHNESS,
		(Z/TERRAIN_SMOOTHNESS * chunkPosZ) + z/TERRAIN_SMOOTHNESS,
		SEED
	) * HEIGHT_SCALE

	if height > 20 then
		local difference = height - 20
		height += (difference * 1.2)
	end

	if height < -20 then
		local difference = height - -20
		height += (difference * 1.2)
	end

	return height
end

local function getPosition(chunkPosX, chunkPosZ, x, z)
	return Vector3.new(
		chunkPosX*X*WIDTH_SCALE + x*WIDTH_SCALE,
		getHeight(chunkPosX, chunkPosZ, x, z),
		chunkPosZ*Z*WIDTH_SCALE + z*WIDTH_SCALE
	)
end

local function paintWedge(wedge)
	local wedgeHeight = wedge.Position.Y

	local color
	local lowerColorHeight
	local higherColorHeight

	for height, heightColor in pairs(TERRAIN_HEIGHT_COLORS) do
		if wedgeHeight == height then
			color = heightColor
			break
		end

		if (wedgeHeight < height) and (not higherColorHeight or height < higherColorHeight) then
			higherColorHeight = height
		end

		if (wedgeHeight > height) and (not lowerColorHeight or height > lowerColorHeight) then
			lowerColorHeight = height
		end
	end

	if not color then
		if higherColorHeight == nil then
			color = TERRAIN_HEIGHT_COLORS[lowerColorHeight]
		elseif lowerColorHeight == nil then
			color = TERRAIN_HEIGHT_COLORS[higherColorHeight]
		else
			local alpha = (wedgeHeight - lowerColorHeight) / (higherColorHeight - lowerColorHeight)
			local lowerColor = TERRAIN_HEIGHT_COLORS[lowerColorHeight]
			local higherColor = TERRAIN_HEIGHT_COLORS[higherColorHeight]

			color = lowerColor:lerp(higherColor, alpha)
		end
	end

	wedge.Material = Enum.Material.Grass
	wedge.Color = color
end








local function addWater(chunk)
	local cframe = CFrame.new(
		(chunk.x + .5) * chunk.WIDTH_SIZE_X,
		-70,
		(chunk.z + .5) * chunk.WIDTH_SIZE_Z
	)

	local size = Vector3.new(
		chunk.WIDTH_SIZE_X,
		20,
		chunk.WIDTH_SIZE_Z
	)

	workspace.Terrain:FillBlock(cframe, size, Enum.Material.Water)

	chunk.waterCFrame = cframe
	chunk.waterSize = size
end

local function addTrees(chunk)
	local posGrid = chunk.positionGrid
	local instances = chunk.instances
	local chunkPosX = chunk.x
	local chunkPosZ = chunk.z

	for x = 0, X-1 do
		for z = 0, Z-1 do
			local pos = posGrid[x][z]

			if pos.Y >= MIN_TREE_SPAWN_HEIGHT and pos.Y <= MAX_TREE_SPAWN_HEIGHT then
				local random = math.random(1, 5)
				math.randomseed(x * (chunkPosX+SEED) + z * (chunkPosZ+SEED))
				if random < TREE_DENSITY then
					local tree = game.ReplicatedStorage.Tree:Clone()
					local cframe = CFrame.new(pos)
						* CFrame.new(
							math.random() * math.random(-10, 10),
							0,
							math.random() * math.random(-10, 10)
						)
						* CFrame.Angles(0, 2 * math.pi * math.random(), 0)

					tree:SetPrimaryPartCFrame(cframe)
					tree.Parent = workspace

					table.insert(instances, tree)
				end

			end
		end
	end
end

local function addModels(chunk)
	local posGrid = chunk.positionGrid
	local instances = chunk.instances
	local chunkPosX = chunk.x
	local chunkPosZ = chunk.z

	for x = 0, X-1 do
		for z = 0, Z-1 do
			local pos = posGrid[x][z]

			if pos.Y >= MIN_TREE_SPAWN_HEIGHT and pos.Y <= MAX_TREE_SPAWN_HEIGHT then
				local random = math.random()
				math.randomseed(x * (chunkPosX+SEED) + z * (chunkPosZ+SEED))
				if random < MODEL_DENSITY then
					local tree = game.ReplicatedStorage.Camp:Clone()
					print(random)
					local cframe = CFrame.new(pos)
						* CFrame.new(
							math.random() * math.random(-10, 10),
							0,
							math.random() * math.random(-10, 10)
						)
						* CFrame.Angles(0, 2 * math.pi * math.random(), 0)

					tree:SetPrimaryPartCFrame(cframe)
					tree.Parent = workspace

					table.insert(instances, tree)
				end

			end
		end
	end
end

local Chunk = {}
Chunk.__index = Chunk

Chunk.WIDTH_SIZE_X = X * WIDTH_SCALE
Chunk.WIDTH_SIZE_Z = Z * WIDTH_SCALE

function Chunk.new(chunkPosX, chunkPosZ)
	local chunk = {
		instances = {};
		positionGrid = {};
		x = chunkPosX;
		z = chunkPosZ;
	}

	setmetatable(chunk, Chunk)

	local positionGrid = chunk.positionGrid

	for x = 0, X do
		positionGrid[x] = {}

		for z = 0, Z do
			positionGrid[x][z] = getPosition(chunkPosX, chunkPosZ, x, z)
		end
	end

	for x = 0, X-1 do
		for z = 0, Z-1 do
			local a = positionGrid[x][z]
			local b = positionGrid[x+1][z]
			local c = positionGrid[x][z+1]
			local d = positionGrid[x+1][z+1]

			local wedgeA, wedgeB = draw3dTriangle(a, b, c)
			local wedgeC, wedgeD = draw3dTriangle(b, c, d)

			paintWedge(wedgeA)
			paintWedge(wedgeB)
			paintWedge(wedgeC)
			paintWedge(wedgeD)

			table.insert(chunk.instances, wedgeA)
			table.insert(chunk.instances, wedgeB)
			table.insert(chunk.instances, wedgeC)
			table.insert(chunk.instances, wedgeD)
		end
	end

	addWater(chunk)
	addTrees(chunk)
	addModels(chunk)
	return chunk
end

function Chunk:Destroy()
	for index, instance in ipairs(self.instances) do
		instance:Destroy()
	end

	workspace.Terrain:FillBlock(self.waterCFrame, self.waterSize, Enum.Material.Air)
end

return Chunk

I see that your using @okeanskiy code. Well there is probably nothing you can do about it as its meant to be laggy like its a procedural terrain generator there is nothing you can do about it.

1 Like

It sure is something he can do about it. Such as using Parallel Luau to ease the computation in parallel and increasing or decreasing (not sure which one increases the performance) the X and Z value

Ah yes, I forgot about parallel lua. Maybe because I don’t use it? But yea I suppose OP can use it but would potentially be hard for OP.

1 Like

personally, i think that its easy to learn but it also has some strict limitations; you could assign every 4 chunks to be handled by 1 actor or so with the task of computing in parallel and adding the wedges in serial

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.