# How do I optimize this script?

I made an infinite mining generation script from a tutorial for my mining game, but it’s horribly optimized and I don’t know how exactly to optimize it. If someone mines for a bit eventually the amount of existing blocks and values start lagging the game for every block you mine.

So far I’ve looked into occlusion culling but that wouldn’t work as it would probably not help with performance if it keeps checking what objects are on screen, another thing I’ve tried is changing how the blocks and values get stored, but that ended up causing more lag, and so I’m just kind of stumped at this point I don’t know how to optimize this.

This is my code right now

``````local RS = game:GetService("ReplicatedStorage")
local positions = {
Vector3.new(6,0,0);
Vector3.new(-6,0,0);
Vector3.new(0,6,0);
Vector3.new(0,-6,0);
Vector3.new(0,0,6);
Vector3.new(0,0,-6);
}

local oreTable = {}
for i, v in ipairs(game.ServerStorage.Ores:GetChildren()) do
if v:IsA("Part") then
table.insert(oreTable, {ore = v, chance = v.Chance.Value})
end
end

local rollTable = {}
for _, data in ipairs(oreTable) do
for i = 1, data.chance, 1 do
table.insert(rollTable, data)
end
end

function Generate(pos)
if pos then
for _,pos2 in pairs(positions) do
local newPos = pos+pos2
local previouslyGenerated
for _,generated in pairs(workspace.Cubes.Generated:GetChildren()) do
if generated.Value == newPos then
previouslyGenerated = true
end
end
if newPos.Y > 0 then
previouslyGenerated = true
end
if not previouslyGenerated then
local random = math.random(1, #rollTable)
local ore = rollTable[random].ore:Clone()
ore.Position = newPos
ore.Parent = workspace.Cubes
RS.BlockGen.OnServerEvent:Connect(function(plr, rPart)
Generate(rPart.Position)
rPart:Destroy()
end)
local val = Instance.new("Vector3Value")
val.Value = newPos
val.Parent = workspace.Cubes.Generated
end
end
end
end

for i,cube in pairs(workspace.Cubes:GetChildren()) do
if cube:IsA("Part") then
local val = Instance.new("Vector3Value")
val.Value = cube.Position
val.Parent = workspace.Cubes.Generated
RS.BlockGen.OnServerEvent:Connect(function(plr, rPart)
Generate(rPart.Position)
rPart:Destroy()
end)
end
end
``````

There’s a lot of things to optimize in this script that only you can do. With only little knowledge of your script, all I can really do is make it pretty:

``````-- services
local ReplicatedStorage = game:GetService("ReplicatedStorage")

-- tables
local Positions = {
Vector3.new(6,0,0);
Vector3.new(-6,0,0);
Vector3.new(0,6,0);
Vector3.new(0,-6,0);
Vector3.new(0,0,6);
Vector3.new(0,0,-6);
}

local OreTable = {}
local RollTable = {}

-- for loops
for Index, Inst in ipairs(game.ServerStorage.Ores:GetChildren()) do
if Inst:IsA("Part") then
table.insert(OreTable, {ore = Inst, chance = Inst.Chance.Value})
end
end

for Index, Data in ipairs(OreTable) do
for i = 1, Data.chance, 1 do
table.insert(RollTable, Data)
end
end

-- main functions
function Generate(Position)
if Position then
for _, Position2 in pairs(Positions) do
local NewPosition = Position+Position2
local previouslyGenerated

for _, Generated in pairs(workspace.Cubes.Generated:GetChildren()) do
if Generated.Value == NewPosition then
previouslyGenerated = true
end
end

if NewPosition.Y > 0 then
previouslyGenerated = true
end

if not previouslyGenerated then
local random = math.random(1, #RollTable)
local ore = RollTable[random].ore:Clone()

ore.Position = NewPosition
ore.Parent = workspace.Cubes

ReplicatedStorage.BlockGen.OnServerEvent:Connect(function(plr, rPart)
Generate(rPart.Position)
rPart:Destroy()
end)

local Vector = Instance.new("Vector3Value")
Vector.Value = NewPosition
Vector.Parent = workspace.Cubes.Generated
end
end
end
end

for Index,Cube in pairs(workspace.Cubes:GetChildren()) do
if Cube:IsA("Part") then
local Vector = Instance.new("Vector3Value")
Vector.Value = Cube.Position
Vector.Parent = workspace.Cubes.Generated
ReplicatedStorage.BlockGen.OnServerEvent:Connect(function(plr, rPart)
Generate(rPart.Position)
rPart:Destroy()
end)
end
end
``````
1 Like

Some mistakes upon first reading the code,

You shouldn’t connect this event in the for loop, this will repeatedly connect the same event even though it only needs to be connected once. Move it to the bottom of the script.

By the looks of it (assuming this is voxels) you aren’t implementing any form of greedy meshing, which means that you are rendering triangles for every block instead of greedy meshing it.

@/5uphi 's video explains greedy meshing pretty well

as well as this write-up by Elttob Consume everything - how greedy meshing works

1 Like

Could you elaborate on what you mean by there are things in the script that only I can optimize? Also thanks for that.

From what I understand by skimming through the tutorials, what this does is merge the blocks into one giant block as opposed to many tiny blocks, right? This isn’t what I’m looking for as the player might wanna go back into previous sections of the mine where presumably the blocks might be merged, and they can’t mine it anymore of course. Though you are correct it is voxels.

It did optimize my game a lot though by removing the event in the for loop. I still feel like the game lags just a little bit when I go past a certain point while mining.

I’m saying that if I were to optimize the script, I am surely to run into some errors due to my limited knowledge of other scripts / events you have.

You would just have to recalculate the greedy mesh for that specific area when the player mines/places a block. This is how every voxel game including Minecraft does it. Making and optimising a voxel game is a surprisingly complicated topic, I’d recommend you give these a read.