My tycoon game's bases/tycoons don't set-up properly

My game uses object-oriented programming to create and setup tycoon objects that players will interact with.

The way this works is, I have a central script that goes through a folder that has all the base plots. It then takes a copy of the base/tycoon from somewhere in ServerStorage, sets up the base to be unique to the team (aka set up the flag and name), and then call tycoon.new(baseModelHere) to initialize the tycoon. This then sets up a copy of the base in a unique-named folder, which includes all the objects to be bought, the base itself so it can be re-initialized when a player rebirths/leaves, etc. 90%+ of the time, it does this successfully and without any issue whatsoever.

Over the last week or so, I have been noticing a glitch that has been getting more and more common, in where the bases/tycoons do not set-up correctly upon the game initializing. The set-up script places the base, sets up its respective flag, but the tycoon.new() constructor either never gets called or breaks somehow, and the base is never properly initialized - meaning a copy of the full base just sits there, and cannot be claimed by a player.

This only happens for one or two tycoons. The other tycoons (which range from a total of 8-16 tycoons per server depending on if you are in the two-player or single-player mode) boot up and get set up fine.

This has been a very difficult problem to try and replicate. It is very inconsistent and seems very rare. I have never experienced this glitch “in the wild” playing my game normally, I have only seen it when it gets reported to me a few times a day out of the tens of thousands of players who play my game. I have tried server-hopping to try and spot it myself, to no avail.

I really have no idea why this happens. I have tried using the developer console to find information on this bug, but I cannot find even the original setup output statements for the other bases/tycoons, due to this bug happening at the server’s creation, and a server can be hours if not days old, so that information does not show, even if I try searching for it.

All I know is, the base/tycoon never sets up right. The clone model for the base never gets created, as, in this picture, you can see there are 6 of them, when there need to be 8 - the last two never initialized properly.
image

Here is the code I use:

---setting up code
local gameInfo = game.ReplicatedStorage.gameInfo
repeat 
	print("initializing in progress, please wait...")
	task.wait(1)
until gameInfo:GetAttribute("initialized") == true
print("gameInfo has initialized, proceeding")
--- this is just for determining if the game is single-player or two-player.

local tycoons = game:GetService("ServerStorage"):WaitForChild("tycoons")
local tycoonLocation = tycoons.singlePlayer --- default
local tycoonModule = require(game:GetService("ServerScriptService").tycoons.tycoonModule)

if gameInfo:GetAttribute("maxPlayers") == 2 then
	tycoonLocation = tycoons.twoPlayer
end

local basePlates = workspace.BasePlots
local axisPlot = basePlates.Axis:GetChildren()
local alliedPlot = basePlates.Allies:GetChildren()

---- placement
for _,team in next,game:GetService("Teams"):GetChildren() do
	if team.AutoAssignable == false then
		local clone = tycoonLocation:Clone()
		clone.Parent = workspace.tycoons
		for _,spawns in pairs(clone:GetDescendants()) do
			if spawns:IsA("SpawnLocation") then
				spawns.TeamColor = team.TeamColor
			end
		end
		if team:GetAttribute("Faction") == "Allies" then
			local placeMent = alliedPlot[math.random(1,#alliedPlot)]
			if clone.PrimaryPart ~= nil then
				clone:SetPrimaryPartCFrame(placeMent.CFrame)
			else
				clone:MoveTo(placeMent.Position)
			end
			placeMent:Destroy()
			alliedPlot = basePlates.Allies:GetChildren()
		else
			local placeMent = axisPlot[math.random(1,#axisPlot)]
			if clone.PrimaryPart ~= nil then
				clone:SetPrimaryPartCFrame(placeMent.CFrame)
			else
				clone:MoveTo(placeMent.Position)
			end
			placeMent:Destroy()
			axisPlot = basePlates.Axis:GetChildren()
		end
		clone.Part:Destroy()
		clone.infoBoard.Parent = workspace.goalBillBoards
		local flagBrick = clone.flagBrick
		flagBrick.flag.img.Image = team.flag.Texture
		flagBrick.Name = team.Name.." Flag"
		flagBrick.Parent = game.Workspace.mainTerrain.teamFlags
		if team:GetAttribute("abbr") ~= nil then
			flagBrick.flag.img.TextLabel.Text = team:GetAttribute("abbr")
		end
		task.spawn(function()
			if gameInfo:GetAttribute("maxPlayers") == 2 then
					if clone:FindFirstChild("leftSide") ~= nil then
						local leftSide = clone:FindFirstChild("leftSide")
						leftSide.Name = team.Name.."TycoonLeft"
						leftSide.Parent = workspace.tycoons
						leftSide.values.team.Value = team
						if leftSide:FindFirstChild("chest") ~= nil then
							leftSide.chest.Parent = workspace.donationRadios
						end
						tycoonModule.new(leftSide)
					end
					if clone:FindFirstChild("rightSide") ~= nil then
						local rightSide = clone:FindFirstChild("rightSide")
						rightSide.Name = team.Name.."TycoonRight"
						rightSide.Parent = workspace.tycoons
						rightSide.values.team.Value = team
						if rightSide:FindFirstChild("chest") ~= nil then
							rightSide.chest.Parent = workspace.donationRadios
						end
						tycoonModule.new(rightSide)
					end
					clone:Destroy()
			else
				clone.Name = team.Name.."Tycoon"
				clone.values.team.Value = team
				if clone:FindFirstChild("chest") ~= nil then
					clone.chest.Parent = workspace.donationRadios
				end
				tycoonModule.new(clone)
			end
		end)	
	end
end
print("game loaded in successfully.")

It gets to the part where it sets up the flag of the base/tycoon, it’s name, etc. successfully. Once it hits tycoon.new(), it, for some reason, breaks.

The “clone” that gets destroyed is the holding model that has the tycoons/bases in them for placing them correctly.

Here’s the constructor code snippet:

---tycoon.new constructor. I won't be sharing the whole code, as I don't think it's necessary (and it's pretty long) and it never gets to execute properly

function tycoons:makeClone(model)
	local folder = Instance.new("Folder")
	folder.Parent = game.ServerStorage.tycoons.playerBases
	local folder2 = Instance.new("Folder")
	folder2.Name = "forSale"
	folder2.Parent = folder
	local folder3 = Instance.new("Folder")
	folder3.Name = "wholeThang"
	folder3.Parent = folder
	local newName = false
	while newName == false do
		local name = random_string(6)
		if not game.ServerStorage.tycoons.playerBases:FindFirstChild(name)then
			newName = true
			folder.Name = name
		end
	end
	model:Clone().Parent = folder3
	for a,b in ipairs(self.objects.forSale:GetChildren()) do
--		wait() -- Zraix Added
		b.Parent = folder2
	end
	return folder
end

function tycoons.new(model)
	warn("currently in process of creating tycoon...")
	local self = setmetatable({
		_janitor = Janitor.new(),
		copy = nil,
		actualModel = model,
		events = model:WaitForChild("events",3),
		objects = model:WaitForChild("objects",3),
		values = model:WaitForChild("values",3),
		collection = model:WaitForChild("collectorMoney",3),
		rebirthBoard = model:WaitForChild("rebirthBoard",3),
		claimDevice = model:WaitForChild("claimDevice",3),
		rebirthEvent = nil,
		autoCollect = false,
		ownerBoard = model:WaitForChild("ownerBoard"),
	},tycoons)
	self.copy = self:makeClone(model)
	self.rebirthEvent = self.events:WaitForChild("rebirth")
end
1 Like

Could you show the code that allows the player to claim a tycoon?

Edit: Nevermind I see the “team” pairs loop now

1 Like

I can, but I don’t think it will help much.

self._janitor:Add(
		self.claimDevice.ProximityPrompt.Triggered:Connect(function(player) --- claim base framework.
			local check = player:WaitForChild("tycoons");
			if player.Team ~= self.values.team.Value then return; end; --- to prevent being colonized by other teams (don't remove comment until ready)
			if not check.Value or gameInfo:GetAttribute("vipServer") == true then
				if check.Value == hasTwo then
					notificationRemote:FireClient(player,"Base Claim Failure","You already have TWO bases. Don't be greedy!");
				else
					self:claimBase(player); --mainFrame.claimBase(player,values,claimDevice,whoOwns,TycoonBase,baseFolder); --mainFrame.claimBase(player,TycoonBase,baseFolder);
					self.values.itemsLeft.Value = self:checkItems();
					task.wait(.1)
					local clone = script.rebirths:Clone()
					clone.Parent = self.values.owner.Value.PlayerGui
					clone.Adornee = model.rebirthBoard.main
					clone.frame.main.connection.Value = self.values.itemsLeft
					clone.frame.main.connection2.Value = self.objects.buttons
					clone.frame.main.Enabled = true
					if model:FindFirstChild("rebirthInfoBoard") ~= nil then
						local clone2 = script.rebirthInfo:Clone()
						clone2.Parent = model.rebirthInfoBoard.main
						rebirthInfoBoard.addBoard(clone2)
					end	
				end;
			else
				notificationRemote:FireClient(player,"Base Claim Failure","You already have a base!");
			end;
		end), "Disconnect");

That obviously doesn’t work, as the base doesn’t get set up right, so the connection is never established.

I believe something must be wrong with either the game calling the tycoon.new constructor or it never gets called period

1 Like

This is still happening and still super rare.

1 Like