local ServerScriptService = game:GetService("ServerScriptService")
local TycoonsFolder = workspace:WaitForChild("Tycoons")
local MoneyStorage = game:GetService("ServerStorage"):WaitForChild("MoneyStorage")

-- Helper function to get the player from a hit
local function getPlayerFromHit(hit)
	return game.Players:GetPlayerFromCharacter(hit.Parent)
end

-- Helper function to check if the player owns the tycoon
local function playerOwnsTycoon(player, tycoonModel)
	return player and tycoonModel.Owner.Value == player
end

-- Helper function to check if the character is alive
local function characterIsAlive(character)
	local humanoid = character:FindFirstChild("Humanoid")
	return humanoid and humanoid.Health > 0
end

-- Helper function to get the player's cash storage
local function getCashStorage(player)
	return MoneyStorage:FindFirstChild(player.Name)
end

-- Function to set up a tycoon
local function setupTycoon(tycoonModel)
	local objects = {}
	
	tycoonModel:WaitForChild("Buttons")
	game:GetService("ServerStorage"):WaitForChild("Assets"):WaitForChild("Purchases")
	local Essentials = tycoonModel:WaitForChild("Essentials")
	local Cash = tycoonModel:WaitForChild("Cash")
	local PurchasedObjects = tycoonModel:WaitForChild("PurchasedObjects")

	-- Connect to the collector touch event
	Essentials.Collector.Touched:Connect(function(hit)
		local cash = hit:FindFirstChild("Cash")
		if cash then
			Cash.Value += cash.Value
			game.Debris:AddItem(hit, 0)
		end
	end)

	-- Connect to the giver touch event
	Essentials.Giver.Touched:Connect(function(hit)
		local player = getPlayerFromHit(hit)
		if player and playerOwnsTycoon(player, tycoonModel) and characterIsAlive(hit.Parent) then
			local cashStorage = getCashStorage(player)
			if cashStorage then
				cashStorage.Value += Cash.Value
				Cash.Value = 0
			end
		end
	end)
	


	-- Set up each button in the tycoon
	for _, button in tycoonModel.Buttons:GetChildren() do
		local head = button:FindFirstChild("Head")
		if head then
			local objectName = button.Object and button.Object.Value
			local purchaseObject = objectName and game.ServerStorage.Assets.Purchases:FindFirstChild(objectName)
			if not purchaseObject then
				warn("Button: " .. button.Name .. " is missing its object and has been removed.")
				head.CanCollide = false
				head.Transparency = 1
			end

			if button:FindFirstChild("Dependency") then
				head.CanCollide = false
				head.Transparency = 1
				coroutine.wrap(function()
					while not PurchasedObjects:FindFirstChild(button.Dependency.Value) do
						task.wait()
					end
					head.CanCollide = true
					head.Transparency = 0
				end)()
			end

			-- Connect to the button head touch event
			head.Touched:Connect(function(hit)
				local player = getPlayerFromHit(hit)
				if player and head.CanCollide and playerOwnsTycoon(player, tycoonModel) and characterIsAlive(hit.Parent) then
					local cashStorage = getCashStorage(player)
					if cashStorage and cashStorage.Value >= button.Price.Value then
						cashStorage.Value -= button.Price.Value
						head.Transparency = 1
						head.CanCollide = false
						objects[objectName].Parent = PurchasedObjects
					end
				end
			end)
		end
	end
end


for _, tycoon in TycoonsFolder:GetChildren() do
	setupTycoon(tycoon)
end

-- Set up newly added tycoons
TycoonsFolder.ChildAdded:Connect(setupTycoon)


attempt to index 'nil' with Parent, line 92. it happens when i touch a button in my tycoon.