Confusion of Duplication

Hi, there

Am making a Bomberman game that uses an array to make the map. But when I generate the map I experience lag. I’ve made a cleanup function but instead of it cleaning up duplicates it destroys all it’s objects. Is there anyway I can fix it?

Heres my code -

local tileType = {}

local blocks = script:WaitForChild("Blocks")
local defaultBlock = blocks:WaitForChild("Default")
local breakableBlock = blocks:WaitForChild("Breakable")
local unBreakable = blocks:WaitForChild("Unbreakable")

local dunderman = workspace:WaitForChild("Dunderman")
local files = dunderman:WaitForChild("Files")
local fileBlocks = files:WaitForChild("Blocks")

local tabBlocks = {}

function tileType:AirType(array)
	for _, v in pairs(array) do
		defaultBlock:Clone().Parent = fileBlocks:WaitForChild("Tiles")
		defaultBlock.Position = Vector3.new(4*_,0,0)
		for i,j in pairs(v) do
			defaultBlock:Clone().Parent = fileBlocks:WaitForChild("Tiles")
			defaultBlock.Position = Vector3.new(4*_,0,4*i)
			table.insert(tabBlocks,defaultBlock.Position)
		end
	end
end

function tileType:Unbreakable(array,num)
	if tabBlocks[num] then
		local pos = tabBlocks[num]
		local block= unBreakable:Clone()
		block.Parent = fileBlocks:WaitForChild("Unbreakables")
		block.Position = pos + Vector3.new(0,4,0)
	end

	for i, v in pairs(array) do
		for _, j in pairs(v) do
			if tabBlocks[_/2] then
				local pos = tabBlocks[num]
				local block= unBreakable:Clone()
				block.Parent = fileBlocks:WaitForChild("Unbreakables")
				block.Position = pos + Vector3.new(4*_,4,0)
			end
		end
	end
end


function tileType:Breakable(array,num)
	if tabBlocks[num] then
		local pos = tabBlocks[num]
		local block= breakableBlock:Clone()
		block.Parent = fileBlocks:WaitForChild("Breakables")
		block.Position = pos + Vector3.new(4,4,0)
	end

	for i, v in pairs(array) do
		for _, j in pairs(v) do
			local pos2 = tabBlocks[num]
			local block= breakableBlock:Clone()
			block.Parent = fileBlocks:WaitForChild("Breakables")
			block.Position = pos2 + Vector3.new(4*num,4,0)
		end
	end
end

function tileType:cleanup()
	local fileBreakables = fileBlocks:WaitForChild("Breakables")
	local fileUnbreakables = fileBlocks:WaitForChild("Unbreakables")

	for i,v in pairs(fileUnbreakables:GetChildren()) do
		for i,v2 in pairs(fileUnbreakables:GetChildren()) do
			local found = 0
			
			if v2 == v then
				if found == 0 then
					found+=1
					print("found")
				else
					v:Destroy()
					print("deleted")
				end
			end
		end
	end
end

return tileType

All ideas appreciated!

I think it might be because you use fileUnbreakables twice and fileBreakables not once.
But it’s hard to tell without knowing what they are.

I’ve put my entire script in the text now.

I’m still not quite sure what you want the cleanup() function to do exactly,
but currently it loops through every fileUnbreakable and checks if it’s inside of fileUnbreakables (it always is) and then destroys all fileUnbreakables that come after.

The cleanup function is meant to cleanup all the duplicates but instead of it doing that it deletes all unbreakables.

How do you know if 2 unbreakables are duplicates?

Because v2 == v checks if v2 and v are the same thing, not if one is a duplicate of the other.

Try this

if v2.Name == v.Name and v2 ~= v then

What is the usage of the found variable?

Every time it goes to each object in the interior loop, it goes back to 0, rendering it useless.

If you intend on using it properly, I’d suggest defining it as 0 before you iterate through the objects, not during it.

I’d suggest the following:

function tileType:cleanup()
	local fileBreakables = fileBlocks:WaitForChild("Breakables")
	local fileUnbreakables = fileBlocks:WaitForChild("Unbreakables")
	local found = 0 -- Defines the variables

	for i, v in pairs(fileUnbreakables:GetChildren()) do
		found = 0 -- Resets the variable for each "original" object
		for i, v2 in pairs(fileUnbreakables:GetChildren()) do
			-- Now, because you are not resetting it every time, it has a level of usefulness to it.
			-- If you did what you did previously, "if found == 0 then" would always return true.
			if v2 == v then
				if found == 0 then
					found += 1
					print("Found")
				else
					v:Destroy()
					warn("Deleted.")
				end
			end
		end
	end
end

I tried that it doesn’t work. The found variable is practically useless and I don’t really need it.

Sorry, this doesn’t work.It still give me lag

I did that to fix the duplicate part, to stop lag add task.wait() after starting the for loop

That doesn’t work. also you said this

if v2.Name == v.Name and v2 ~= v then

Pretty much what your saying is that. If the object doen not equal the object then the code shouldn’t go through which is wrong. Because I loop through the folder twice.

1 Like

What do you mean by ‘duplicates’?

When i create unbreakables it creates to many.

What is meant when you say ‘unbreakables’?

I mean objects in the script I create objects.

If you are creating too many unbreakables it would be best to create less, instead of destroying excess.

You already sent tileType:Unbreakable() but could you show where you use it?

this is it

local tileType = require(script.Parent:WaitForChild("TileType"))

function createArray(rows, cols, defualtVal)
	local arr = {}
	
	for x = 1, rows do
		arr[x] = {}
		for y = 1, cols do
			arr[x][y] = defualtVal
		end
	end
	
	return arr
end

function breakables(array)
	for j, v in pairs(array) do
		if j % 2 == 1 then
			tileType:Unbreakable(array,j)
		elseif math.random() > .25 then
			tileType:Breakable(array,j)
		end
	end
end

local array = createArray(15,15,0)

tileType:AirType(array)
breakables(array)
tileType:cleanup()

you could setup your array different so when you iterate through it gives you back the X and Y coords easier with them being the main key to access the value this will be eaiser to read through with just 1 loop and produce the blocks only once
something like below

function createArray(rows, cols, defualtVal)
	local arr = {}
	for x = 1, rows do
		for y = 1, cols do
			arr[x .. ':' ..y] = defualtVal  -- setup like this using X : Y as key   example would be    4:20
		end
	end
	return arr
end


local array = createArray(15,15,0)

would setup the table like

                  ["10:1"] = 0,
                  ["10:10"] = 0,
                  ["10:11"] = 0,
                  ["10:12"] = 0,
                  ["10:13"] = 0,
                  ["10:14"] = 0,

and you can read it using something like this

for PositionKey, Value in pairs(array) do
	local PosTable = string.split(PositionKey,':')
	local X = PosTable[1]
	local Y = PosTable[2]
	print('X' .. X, 'Y' .. Y, 'Val ' .. Value)
end

which would print out something like this

 03:39:36.465  X14 Y8 Val 0  -  Server - Script:21
  03:39:36.465  X12 Y3 Val 0  -  Server - Script:21
  03:39:36.465  X14 Y6 Val 0  -  Server - Script:21
  03:39:36.465  X10 Y15 Val 0  -  Server - Script:21
  03:39:36.465  X12 Y7 Val 0  -  Server - Script:21
  03:39:36.465  X14 Y2 Val 0  -  Server - Script:21
  03:39:36.465  X14 Y1 Val 0  -  Server - Script:21
  03:39:36.465  X10 Y11 Val 0  -  Server - Script:21
  03:39:36.465  X13 Y13 Val 0  -  Server - Script:21
  03:39:36.465  X13 Y12 Val 0  -  Server - Script:21

Do you want to get rid of extra maps and just have one map, but when you try to get rid of the extra map it destroys all the maps?