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.
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