Generating Floors For A Row Of Elves Not Working

Hello there,

I am currently working on a project which is a tycoon game. The basic premise is that the player can buy elves, which then are neatly aligned in a little shelter/building with an open front. The idea is that there can be 9 elves on each floor, and there should only be a new floor duplicated and created once needed. I want it so that there can be an infinite number of floors at the moment, but I may add a cap later due to lag and optimization.

The following is the script that I have been working on which addresses the general system of duplicating these elves, and creating new floors. The problem is that it seems that tons and tons of floors are created, when only one needs to be created. Is there a way to fix this, or just a better way to make this system in general? Help is appreciated!

Code:

local elvesFolder = script.Parent.Elves
local elfValues = script.Parent.ElfValues
local tycoonLevel2 = script.Parent["Tycoon Level 2"]

local repStorage = game:GetService("ReplicatedStorage")

local tycoonRoof = script.Parent["Tycoon Roof"]

local currentNumberOfFloors = 1
local currentLevel = 2

local function ResetElves()
	for i,v in pairs(elvesFolder:GetChildren()) do
		v:Destroy()
	end

	local counter = 0
	for i = 1,elfValues.T1.Value do
		if counter+1 >= 9 and (counter+1) % 9 == 0 then
			if currentNumberOfFloors == math.floor((counter) / 9) + 1 then
			else
				tycoonRoof.Position += Vector3.new(0,7.9,0)
				currentNumberOfFloors = math.floor((counter) / 9) + 1
				print("Level ".. tostring(currentNumberOfFloors))

				local newLevel = tycoonLevel2:Clone()
				newLevel.Parent = script.Parent
				newLevel.Name = "Tycoon Level ".. tostring(currentLevel)
				newLevel:MoveTo(Vector3.new(newLevel.PrimaryPart.Position.X,newLevel.PrimaryPart.Position.Y + 7.9 * currentNumberOfFloors, newLevel.PrimaryPart.Position.Z))
				currentLevel = currentLevel + 1
			end

			local newElf = repStorage["T1 Elf"]:Clone()
			newElf.Parent = elvesFolder
			newElf.Name = "T1 Elf"

			for a,b in pairs(newElf:GetDescendants()) do
				if b:IsA("Part") or b:IsA("MeshPart") then
					b.Position += Vector3.new(0,7.9*currentNumberOfFloors,0)
				end
			end
		else
			if #elvesFolder:GetChildren() == 0 then
				local newElf = repStorage["T1 Elf"]:Clone()
				newElf.Parent = elvesFolder
				newElf.Name = "T1 Elf"
			else
				local newestElf = nil
				for i,v in pairs(elvesFolder:GetChildren()) do
					newestElf = v
				end

				local newElf = newestElf:Clone()
				newElf.Name = "T1 Elf"
				newElf.Parent = elvesFolder

				for i,v in pairs(newElf:GetDescendants()) do
					if v:IsA("Part") or v:IsA("MeshPart") then
						v.Position += Vector3.new(6,0,0)
					end
				end
			end
		end

		counter += 1
	end
end

for i,v in pairs(elfValues:GetChildren()) do
	v.Changed:Connect(function()
		ResetElves()
	end)
end


Whereever your creating floors before you create once check if there is already one

What do you mean? Check if a floor already exists with the specified name?

1 Like

Well im not sure about the specified name part but you said only 1 floor should be created so just check if one floor has been created

I am sorry, I must not have clarified very well.

I want 1 floor to be created for each 9 elves. So if a player has 9 elves, there should only be the first floor, but if they get another one, making it 10, there should be a second floor containing one elf. This would repeat for infinity.

The problem with the current code is that tons of floors are being creating at the same time when only 1 has to be created for example.

Could you show the problem cause its hard visualing this

As you can see in the screenshot, the script duplicated way more levels than what is needed for the elves. (The current elf is a placeholder, and is thus just a character model)

This might be bad practice for me to answer this since I didn’t read the script you send (since it’s too long for me to read), but I can provide a pseudocode that might work for you to this problem.
Let’s assume all the floors are the same.

local totalElves = --total elves
local totalFloor = --total floors

local function upgrade()
     -- add elf
     if totalElves % 9 == 0 then
          totalFloor += 1
          --clone floor here
          --set position of floor times total floor
     end
end

If I understand this, your floor is duplicated way too many times than what is expected. Let me know if this is something you wanted.

So its only supposed to be one row of noobs?

I will refer to the noob-like characters as elves since that is what they are going to be once completed.

I am looking to have a non-limited amount of elves that a player can purchase. The problem that I am having is with aligning these elves on their dedicated floors. There should be 9 elves for each floor, but if the number exceeds 9, a second floor should be created. Similarily, if the number of elves becomes 19, a third floor should be created. This should repeat forever. At the moment I am having no troubles with the elves aligned in their correct and allocated rows, I am just having trouble with duplicating and creating more floors when needed.

Hopefully this explaination makes sense! I appreciate the help that you guys are trying to provide!

1 Like

Ohhhh I believe I understand now, so basically a floor for every 9 elves?

Correct. The only difficult thing is making these floors duplicate only when the previous floor has filled.

so like do you specify how many elves there are going to be?

There will eventually be a cap in hopes of preventing lag, but the script should function with the intention that there is an infinite amount.

No I mean do you have like a variable that youll feed the script that tells it how many elves are going to be created?

Defined at the top of the script is an “ElfValues” folder. This folder contains a few integer values for the different tiers of elves, so combining all of the values would give you the number of elves altogether. Don’t worry about the different tiers, I know how i am going to program those.

So if I were to feed it 50 elves it would create 5 floors correct?
@CadenDevelops

Here is a script that does what you wanted

@CadenDevelops

local elves = 60
local spacing = 5
local number_of_floors = math.floor(elves/9)

for i = 1, number_of_floors do
    local newFloor = Instance.new("Part")
    newFloor.Parent = game.Workspace
    newFloor.Size = Vector3.new(50, 0.5, 2)
    newFloor.Position = Vector3.new(0,(i-1)*9, 0)
    newFloor.BrickColor = BrickColor.new("Dirt brown")
    newFloor.Anchored = true
    newFloor.Name = "Floor " .. i

    for j = 1, 9 do
        local newPart = Instance.new("Part")
        newPart.Parent = game.Workspace
        newPart.Size = Vector3.new(1, 1, 1)
        newPart.BrickColor = BrickColor.Green()
        newPart.Position = newFloor.Position + Vector3.new((j-1) * spacing, 0.5, 0)
        newPart.Position = newPart.Position - newPart.CFrame.RightVector * (newFloor.Size.X / 2 - spacing)
        newPart.Anchored = true
        newPart.Name = "Part " .. (j + (i-1)*9)
    end
end

60 Elves

100 Elves

Do this but instead of parts, clone the elves from your path and used Elve:MoveTo() to this position @CadenDevelops

So I re-wrote the script with your suggestions in mind, and now I am faced with a new problem. The floor creation works perfectly, but for some reason the script never detects when it should move the elves up to the next floor, thus resulting in a long line of 60 elves with no breaks when there is a multiple of 9.

local elvesFolder = script.Parent.Elves
local elfValues = script.Parent.ElfValues
local tycoonLevel2 = script.Parent["Tycoon Level 2"]

local repStorage = game:GetService("ReplicatedStorage")

local tycoonRoof = script.Parent["Tycoon Roof"]

local currentNumberOfFloors = 1
local currentLevel = 2

local elves = 60
local spacing = 5
local number_of_floors = math.floor(elves/9)

local function ResetElves()
	for i = 1,number_of_floors do
		local newFloor = tycoonLevel2:Clone()
		newFloor.Name = "New Tycoon Level"
		newFloor.Parent = script.Parent
		
		newFloor:MoveTo(Vector3.new(tycoonLevel2.PrimaryPart.Position.X,tycoonLevel2.PrimaryPart.Position.Y + 7.9 * i,tycoonLevel2.PrimaryPart.Position.Z))
	end
	
	for i = 1,elves do
		print(tostring(i+1 % 9))
		
		if i >= 9 and i+1 % 9 == 0 then
			local newElf = repStorage["T1 Elf"]:Clone()
			newElf.Name = "T1 Elf"
			newElf.Parent = elvesFolder
			
			print("Moved up a floor.")
			
			for a,b in pairs(newElf:GetDescendants()) do
				if b:IsA("Part") or b:IsA("MeshPart") then
					b.Position += Vector3.new(0,7.9*(i / 9),0)
				end
			end
		else
			if i ~= 1 then
				local newestElf = nil
				for i,v in pairs(elvesFolder:GetChildren()) do
					newestElf = v
				end

				local newElf = newestElf:Clone()
				newElf.Name = "T1 Elf"
				newElf.Parent = elvesFolder
				
				for a,b in pairs(newElf:GetDescendants()) do
					if b:IsA("Part") or b:IsA("MeshPart") then
						b.Position += Vector3.new(6,0,0)
					end
				end
			else
				local newElf = repStorage["T1 Elf"]:Clone()
				newElf.Name = "T1 Elf"
				newElf.Parent = elvesFolder
			end
		end
	end
end

ResetElves()