This tutorial is going to cover the generation aspect of an infinite mining game, think The Quarry/Azure Mines/Mining Simulator, however this will not include randomized ores. This is for those who can learn a bit better through a tutorial than through analyzing source code I suppose.
Now then, let’s start fresh in a new place by removing the baseplate.
First thing we are going to want to do is define how our blocks are going to generate, and to begin we want a perfect cube. Insert a part, anchor it, and give it a size of 6, 6, 6
. Let’s also make a new folder named “Ores” in ServerStorage
and a folder named “Cubes” in Workspace
. Lets put the cube inside of the “Cubes” folder.
We also want to make sure this part is positioned at the 0, 0, 0
origin, as that can simplify things in the future.
What we need to do first is visualize how the blocks will generate, and in this scenario we can use 6 cubes, one on each side of the original cube with the corners being left open.
Now’s the time where we can open our first script, lets insert a generic Script
into ServerScriptService
The best method in my experience is transcribing these “generation positions” in a table, then referencing that table whenever we need to generate a part. Since we already have these “generate positions” defined and the original cube is positioned at 0, 0, 0
, it’s very simple to copy them into the script.
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);
}
Now, let’s look at the actual generation itself. Whenever a block is mined, we can give that block’s position to a generation function, where we loop through our positions table and add them to the block’s position.
function Generate(pos)
if pos then
for _,pos2 in pairs(positions) do
local newPos = pos+pos2
local ore = game.ServerStorage.Ores.Part:Clone()
ore.Position = newPos
ore.Parent = workspace
end
end
end
Now an issue that some of the more astute among you may have picked up on, this system would cause parts to generate over each other and generate in spots where blocks have already been mined. I shall rectify the situation.
Let’s make another folder inside of the “Cubes” folder, we can name it “Generated”.
Now, whenever an ore generates we can add a Vector3 value to this “Generated” folder and cross-reference that with other ores that generate.
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 ore = game.ServerStorage.Ores.Part:Clone()
ore.Position = newPos
ore.Parent = workspace.Cubes
local val = Instance.new("Vector3Value")
val.Value = newPos
val.Parent = workspace.Cubes.Generated
end
end
end
end
Since we aren’t generating the first layer of our mine when the game starts, instead having them already manually placed, we also need to add those first layer cube’s positions to the “Generated” folder.
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
end
end
Now to move past this point, let’s give our cube a click detector that we can utilize to detect when it is mined. We can connect to this using a generic for loop we created before, and then connecting to a new one each time a child is added which we will do next. This is also the point where we should make a clone of our starting cube and move it into the “Ores” folder. All we need to do is connect the cube being clicked to the generate function and that’s a sealed deal.
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
cube.ClickDetector.MouseClick:Connect(function()
Generate(cube.Position)
cube:Destroy()
end)
end
end
And connecting the ClickDetector of a fresh ore when it is generated:
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 ore = game.ServerStorage.Ores.Part:Clone()
ore.Position = newPos
ore.Parent = workspace.Cubes
ore.ClickDetector.MouseClick:Connect(function()
Generate(ore.Position)
ore:Destroy()
end)
local val = Instance.new("Vector3Value")
val.Value = newPos
val.Parent = workspace.Cubes.Generated
end
end
end
end
Finished product:
Place file:
MiningTutorial.rbxl