local Module = {}

local TweenService = game:GetService("TweenService")
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local LocalRemotes = ReplicatedStorage:WaitForChild("LocalRemotes")

local MapsFolder = ServerStorage:WaitForChild("Maps")
local Workspace = game:GetService("Workspace")
local MAP = workspace:WaitForChild("Map")
local LDM = workspace:WaitForChild("LDM")
local MorphModule = require(ServerStorage.Assets.Morphs.MorphModule)

local Spawns = MAP:WaitForChild("CurrentMap"):WaitForChild("Spawns")
local GameSettings = workspace.GameSettings
local Seconds = GameSettings.RoundTime.Seconds
local Decrease = Seconds.Parent.Decrease
local CharactersFolder = workspace.Characters
local EnemyUI = script.EnemyUI
local PlayerUI = script.InformationUI

local SeekersAmounts = {1, 1, 2, 2, 3}
local IntermissionTime = 40
local SelectingTime = 15
local MatchTime = 240

local SeekerAura = ServerStorage:WaitForChild("Assets"):WaitForChild("Character"):WaitForChild("Auras"):WaitForChild("Seekers")

local Seekers = {}
local FirstSeeker
local SecondSeeker
local ThirdSeeker


local function SelectRandomMap()
	local Maps = MapsFolder:GetChildren()
	if #Maps == 0 then
		warn("No maps found")
		return
	end

	local Index = math.random(1, #Maps)
	local SelectedMap = Maps[Index]
	local CurrentMap = workspace.Map:FindFirstChild("CurrentMap")

	if CurrentMap then
		CurrentMap.Name = CurrentMap:FindFirstChild("DefaultName").Value
		CurrentMap.Parent = MapsFolder
	end

	while workspace.Map:FindFirstChild("CurrentMap") do
		task.wait(0.5)
	end

	print("Selected map: " .. SelectedMap.Name)
	SelectedMap.Parent = workspace.Map
	SelectedMap.Name = "CurrentMap"
end


local function ApplyMorph(Character, Gender)
	MorphModule:init()
	MorphModule:ApplyModel(Character, Character, Gender, false)
end

local function RemoveMorph(Character)
	MorphModule:RemoveModel(Character, Character)
end

local function ModeSelection(Player)
	Decrease.Value = false
	GameSettings.GameStatus.Value = "SelectingMode"
	task.wait(2)
	ReplicatedStorage.LocalRemotes.Visual.Selection:FireClient(Player, true)
	Seconds.Value = 15
	task.wait(0.5)
	Decrease.Value = true
	Seconds:GetPropertyChangedSignal("Value"):Connect(function()
		if Seconds.Value ~= 0 then return end
		if GameSettings.GameStatus.Value == "SelectingMode" then
			ReplicatedStorage.LocalRemotes.Visual.Selection:FireClient(Player, false)
			GameSettings.GameStatus.Value = ""
		end
	end)
end

local function SelectSeeker()
	if GameSettings.GameStatus.Value ~= "" then 
		return 
	end

	Seekers = {}    

	Seconds.Value = SelectingTime
	Decrease.Value = true
	GameSettings.GameStatus.Value = "Choosing"

	local PlaceHolder = LDM.Intro
	local SeekersFolder = GameSettings:WaitForChild("Seekers")
	local SeekersAmount
	local Selected = false

	repeat
		local NumSelected = #Seekers
		if NumSelected >= 2 and NumSelected <= 4 then
			SeekersAmount = 1
			SelectingTime = 10+5
		elseif NumSelected >= 5 and NumSelected <= 12 then
			SeekersAmount = 2
			SelectingTime = 21+5
		elseif NumSelected >= 13 and NumSelected <= 20 then
			SeekersAmount = 3
			SelectingTime = 29+5
		else
			SeekersAmount = 1
			SelectingTime = 10+5
		end

		local Potential = CharactersFolder:GetChildren()
		local PlayerSeekers = {}
		local DummySeekers = {}

		for _, Model in ipairs(Potential) do
			if Players:GetPlayerFromCharacter(Model) then
				table.insert(PlayerSeekers, Model)
			else
				table.insert(DummySeekers, Model)
			end
		end

		for i = 1, SeekersAmount do
			local model
			if i == 1 and #PlayerSeekers > 0 then
				local index = math.random(1, #PlayerSeekers)
				model = table.remove(PlayerSeekers, index)
			else
				local remainingSeekers = #PlayerSeekers > 0 and PlayerSeekers or DummySeekers
				local index = math.random(1, #remainingSeekers)
				model = table.remove(remainingSeekers, index)
			end

			model.Parent = SeekersFolder
			table.insert(Seekers, model)

			if i == 1 then
				FirstSeeker = model
			elseif i == 2 then
				SecondSeeker = model
			elseif i == 3 then
				ThirdSeeker = model
			end

			print("SEEKER NUMBER: " .. i .. " - NAME " .. model.Name)
		end

		task.wait(1)

		if #Seekers == SeekersAmount then
			Selected = true
		end
	until Selected

	for i, model in Seekers do
		local dummy = PlaceHolder:FindFirstChild(tostring(i))
		if dummy then
			if Players:FindFirstChild(model.Name) then
				local Player = Players:GetPlayerFromCharacter(model)
				if Player then
					local success, humanoidDescription = pcall(function()
						return Players:GetHumanoidDescriptionFromUserId(Player.UserId)
					end)

					if success and dummy:FindFirstChild("Humanoid") then
						dummy.Humanoid:ApplyDescription(humanoidDescription)
						if Player.Data.Gender.Value == "F" then
							ApplyMorph(dummy, "Female")
						else
							ApplyMorph(dummy, Player.Data.Gender.Value)
						end

						dummy.Torso:GetPropertyChangedSignal("Color"):Connect(function()
							repeat task.wait() until dummy:FindFirstChild("M")
							dummy:FindFirstChild("M").NewModel.Color = dummy.Torso.Color
						end)
					else
						warn("failed to get HumanoidDescription or apply it! are you in Studio doing a localtest?: ", humanoidDescription)
					end
				end
			end
		end
	end

	task.delay(5, function()
		local SeekersFolder = GameSettings:WaitForChild("Seekers")
		local numSeekers = #Seekers
		for _, character in ipairs(Seekers) do
			local player = Players:GetPlayerFromCharacter(character)
			if player then
				task.wait(1)
				LocalRemotes.Visual.CharacterCamera:FireClient(player, numSeekers, table.unpack(Seekers))
			end
		end
	end)

	task.wait(SelectingTime)
	Seconds.Value = 0
	Decrease.Value = false
	GameSettings.GameStatus.Value = "Prepare"
	local SeekerSpawn = MAP:WaitForChild("CurrentMap"):WaitForChild("SeekerSpawn").SpawnLocation
	SeekerSpawn.Transparency = 0
	SeekerSpawn.Information.Enabled = true
end

function Module.EndMatch(Winner)
	GameSettings.GameStatus.Value = "Ended"
	Winner = Winner or "NO ONE"
	print("The WINNER IS:", Winner)
	Seconds.Value = 0
	SelectingTime = 15
	workspace.Settings.Rain.Value = false
	workspace.Settings.Sunny.Value = true

	local function ResetPlayer(Player)
		local character = Player.Character
		if not workspace["LDM"].LoadingCharacters:FindFirstChild(Player.Name) then
			--ReplicatedStorage.LocalRemotes.Visual.Music:FireClient(Player, nil, false)

			local Humanoid = character:FindFirstChild("Humanoid")
			if Humanoid then
				Humanoid.WalkSpeed = 0
				Humanoid.JumpPower = 0
			end

			local Notification = Player:FindFirstChild("PlayerGui") and 
				Player.PlayerGui:FindFirstChild("UI") and 
				Player.PlayerGui.UI:FindFirstChild("Gameplay") and 
				Player.PlayerGui.UI.Gameplay:FindFirstChild("Main") and 
				Player.PlayerGui.UI.Gameplay.Main:FindFirstChild("Notification")
			if Notification then
				Notification.Frame.Object.Text = Winner .. " WON!"
				Notification.Start.Value = true
			end

			task.wait(4)
			GameSettings.GameStatus.Value = ""
			Player:LoadCharacter()
		end
	end

	for _, player in ipairs(Players:GetPlayers()) do
		pcall(ResetPlayer, player)
	end

	if Decrease.Value then
		Decrease.Value = false
		task.wait(0.5)
		Decrease.Value = true
	end
	Seconds.Value = IntermissionTime
	repeat task.wait(.5) until Seconds.Value == 0

	local GameManager = game:GetService("ServerScriptService"):FindFirstChild("GameManager")
	if GameManager then
		GameManager.Enabled = false
		wait(0.5)
		GameManager.Enabled = true
	end
end

local function SelectDay()
	print("SELECT DAY TEST")
	local TimesOfDay = {
		{Name = "Night", Hour = 3},
		{Name = "Day", Hour = 14},
	}

	local ChosenTime = TimesOfDay[math.random(1, #TimesOfDay)]

	if ChosenTime.Name == "Night" then
		workspace.Settings.Sunny.Value = false
		workspace.Settings.Rain.Value = true
	else
		workspace.Settings.Rain.Value = false
		workspace.Settings.Sunny.Value = true
	end

	game.Lighting.ClockTime = ChosenTime.Hour
end

local function PreparePlayer(player)
	SelectRandomMap()
	ModeSelection(player)
	repeat task.wait(.5) until GameSettings.GameStatus.Value == ""
	SelectDay()
	SelectSeeker()
	repeat task.wait() until GameSettings.GameStatus.Value == "Prepare"
	if player == nil then return end

	Seconds.Value = IntermissionTime
	Decrease.Value = true
	if not GameSettings.Seekers:FindFirstChild(player.Name) then
		local spawnIndex = math.random(1, #Spawns:GetChildren())
		player.Character.Parent = GameSettings.Humans
		player.Character.HumanoidRootPart.CFrame = Spawns:GetChildren()[spawnIndex].CFrame
		PlayerUI:Clone().Parent = player.Character.Head
	end

	local function TrackMatch()
		local SeekerSpawn = MAP:WaitForChild("CurrentMap"):WaitForChild("SeekerSpawn").SpawnLocation
		if Seconds.Value == 0 then
			if GameSettings.GameStatus.Value == "Prepare" then
				Seconds.Value = MatchTime
				for _, SeekerCharacter in GameSettings.Seekers:GetChildren() do
					local SeekerPlayer = Players:GetPlayerFromCharacter(SeekerCharacter)
					if SeekerPlayer then
						LocalRemotes.Visual.Caught:FireClient(SeekerPlayer, "A SEEKER!", Color3.fromRGB(255, 28, 28), "YOU ARE")

						local ToolName = SeekerPlayer.Data.Equipped.Value
						local Tool = ServerStorage.Tools:FindFirstChild("Fists")
						if Tool then
							if Tool:IsA("Tool") then
								Tool:Clone().Parent = SeekerPlayer.Backpack
							elseif Tool:IsA("Frame") then
								Tool:Clone().Parent = SeekerPlayer.PlayerGui.UI.Gameplay["Tools"]
							end
						end
					end

					SeekerCharacter.HumanoidRootPart.CFrame = SeekerSpawn.CFrame * CFrame.new(-1, 0, 1)
					EnemyUI:Clone().Parent = SeekerCharacter.Head
					if SeekerAura then
						for _, Particle in SeekerAura:GetChildren() do
							Particle:Clone().Parent = SeekerCharacter.Torso
						end
					end
				end
				task.wait(0.5)
				SeekerSpawn.Transparency = 1
				SeekerSpawn.Information.Enabled = false
				GameSettings.GameStatus.Value = "Active"
				for _, player in ipairs(Players:GetPlayers()) do
					if GameSettings.Humans:FindFirstChild(player.Name) then
						local PlayerGui = player:FindFirstChild("PlayerGui")
						if PlayerGui then
							local Main = PlayerGui:FindFirstChild("UI"):FindFirstChild("Gameplay"):FindFirstChild("Main")
							if Main then
								local Counter = Main:FindFirstChild("Counter")
								local PlayerFrame = Main:FindFirstChild("PlayerFrame")
								if Counter and PlayerFrame then
									Counter.Visible = true
									PlayerFrame.Visible = true
								end
							end
						end
						LocalRemotes.Visual.Caught:FireClient(player, "A HIDER!", Color3.fromRGB(255, 255, 127), "YOU ARE")
					end
				end

				if workspace.Settings.Sunny.Value then
					--ReplicatedStorage.LocalRemotes.Visual.Music:FireClient(player, "Sunny", true)
				elseif workspace.Settings.Rain.Value then
					--ReplicatedStorage.LocalRemotes.Visual.Music:FireClient(player, "Rain", true)
				end
			end
		end
	end

	Seconds:GetPropertyChangedSignal("Value"):Connect(TrackMatch)
end

function Module.SpawnPlayer(player)
	local character = player.Character
	if character and workspace.Characters:FindFirstChild(player.Name) then
		task.spawn(function()
			PreparePlayer(player)
		end)
	end
end

return Module



line 303 error: attempt to index nil with 'Parent'