Make a map voting work for new players

So I’m trying to make a map voting system, however a big issue has arose where when a new player joins, this script doesn’t account for them and show certain guis or update some of their stuff.

I’ve tried a lot but could never get it to work.

local sss = game:GetService("ServerScriptService")
local players = game:GetService("Players")
local rs = game:GetService("ReplicatedStorage")
local mapvotes = rs.MapVotes
local mapFolders = rs.Maps
local mapImages = {
	["Artic 2"] = "rbxassetid://102039944173630",
	["Rough Lands"] = "rbxassetid://46170065",
	["Crossroads"] = "rbxassetid://46175067",
}
local isGame = false
local updateLobbyStatus = rs:WaitForChild("UpdateLobbyStatus")

-- Store player votes in a table
local playerVotes = {}

-- Function to get a random set of 3 unique models
local function getRandomModels(mapFolders, count)
	local models = mapFolders:GetChildren()
	local selectedModels = {}

	if #models < count then
		warn("Not enough models in the folder to select " .. count)
		return selectedModels
	end

	while #selectedModels < count do
		local randomIndex = math.random(1, #models)
		local randomModel = models[randomIndex]

		if not table.find(selectedModels, randomModel) then
			table.insert(selectedModels, randomModel)
		end
	end

	return selectedModels
end

local function getMapWithHighestVotes()
	local map1Votes = mapvotes.Map1.Value
	local map2Votes = mapvotes.Map2.Value
	local map3Votes = mapvotes.Map3.Value

	local highestVotes = math.max(map1Votes, map2Votes, map3Votes)

	if highestVotes == map1Votes then
		return 1, highestVotes
	elseif highestVotes == map2Votes then
		return 2, highestVotes
	elseif highestVotes == map3Votes then
		return 3, highestVotes
	end
end

local randomModels = getRandomModels(mapFolders, 3)

local function setMapGUI()
	for _, v in pairs(players:GetDescendants()) do
		if v.Name == "Vote" then
			v.MainFrame.Map1.MapName.Text = tostring(randomModels[1])
			v.MainFrame.Map1.Thumbnail.Image = mapImages[tostring(randomModels[1])]
			v.MainFrame.Map2.MapName.Text = tostring(randomModels[2])
			v.MainFrame.Map2.Thumbnail.Image = mapImages[tostring(randomModels[2])]
			v.MainFrame.Map3.MapName.Text = tostring(randomModels[3])
			v.MainFrame.Map3.Thumbnail.Image = mapImages[tostring(randomModels[3])]
			v.MainFrame.Map1.Visible = true
			v.MainFrame.Map2.Visible = true
			v.MainFrame.Map3.Visible = true
			v.Enabled = true
		end
	end
end

-- Reset function to clear votes, GUI, and map
local function resetGameState()
	for _, v in pairs(players:GetDescendants()) do
		if v.Name == "Lobby" then
			v.Value = true
		end
	end
	mapvotes.Map1.Value = 0
	mapvotes.Map2.Value = 0
	mapvotes.Map3.Value = 0

	-- Clear player votes from the previous round
	playerVotes = {}

	-- Reset player GUI and votes
	for _, player in pairs(players:GetChildren()) do
		local voteGUI = player:FindFirstChild("Vote")
		if voteGUI then
			voteGUI.MainFrame.Map1.Visible = true
			voteGUI.MainFrame.Map2.Visible = true
			voteGUI.MainFrame.Map3.Visible = true
			voteGUI.MainFrame.SelectedMap.Visible = false

			voteGUI.MainFrame.Map1.MapName.Text = ""
			voteGUI.MainFrame.Map2.MapName.Text = ""
			voteGUI.MainFrame.Map3.MapName.Text = ""
			voteGUI.Enabled = false
		end
	end

	-- Clear any existing maps from the workspace
	for _, obj in pairs(workspace:GetChildren()) do
		if obj:IsA("Model") and mapFolders:FindFirstChild(obj.Name) then
			obj:Destroy()
		end
	end
	game.Lighting:FindFirstChildOfClass('Sky'):Destroy()
end


-- Example usage: Get 3 random models from the folder


-- Output the names of the selected models
for _, model in pairs(randomModels) do
	print("Selected model:", model.Name)
end

players.PlayerAdded:Connect(function(player)
	if isGame then
		-- Fire the event to the client to disable the lobby
		updateLobbyStatus:FireClient(player, false)
	else
		-- Fire the event to the client to enable the lobby
		updateLobbyStatus:FireClient(player, true)
	end
end)


while true do
	for _, v in pairs(players:GetDescendants()) do
		if v.Name == "Lobby" then
			v.Value = true
		end
	end
	isGame = false
	mapvotes.Map1.Value = 0
	mapvotes.Map2.Value = 0
	mapvotes.Map3.Value = 0

	-- Reset player votes for the new round
	playerVotes = {}

	task.wait(10)
	



	rs.VoteEvent.OnServerEvent:Connect(function(player, number, mapVotedFor)
		local playerId = player.UserId

		-- Check if the player has voted before, and if so, for which map
		local previouslyVotedMap = playerVotes[playerId] or 0

		-- Decrease the vote count for the previously voted map, if applicable
		if previouslyVotedMap > 0 then
			if previouslyVotedMap == 1 then
				mapvotes.Map1.Value -= 1
			elseif previouslyVotedMap == 2 then
				mapvotes.Map2.Value -= 1
			elseif previouslyVotedMap == 3 then
				mapvotes.Map3.Value -= 1
			end
		end

		-- Increase the vote count for the newly selected map
		if number == 1 then
			mapvotes.Map1.Value += 1
		elseif number == 2 then
			mapvotes.Map2.Value += 1
		elseif number == 3 then
			mapvotes.Map3.Value += 1
		end

		-- Update the player's current vote
		playerVotes[playerId] = number
	end)

	task.wait(15)
	for _, v in pairs(players:GetDescendants()) do
		if v.Name == "Vote" then
			local mapNumber, voteCount = getMapWithHighestVotes()
			v.MainFrame.SelectedMap.Text = tostring(randomModels[mapNumber]) .. " has the highest votes with " .. voteCount .. " vote(s)."
			v.MainFrame.Map1.Visible = false
			v.MainFrame.Map2.Visible = false
			v.MainFrame.Map3.Visible = false
			v.MainFrame.SelectedMap.Visible = true
		end
	end

	-- Spawn the map
	local mapNumberToGet = getMapWithHighestVotes()
	local map = rs.Maps:FindFirstChild(tostring(randomModels[mapNumberToGet])):Clone()
	map.Parent = workspace
	map:FindFirstChildOfClass("Sky").Parent = game.Lighting
	for _, v in pairs(map:GetChildren()) do
		if v.Name == "SPAWN" then
			v.Enabled = true
		end
	end

	task.wait(5)

	workspace:FindFirstChild("SPAWN").Enabled = false
	for _, v in pairs(players:GetDescendants()) do
		if v.Name == "Lobby" then
			v.Value = false
		end
	end
	isGame = true
	for _, v in pairs(players:GetDescendants()) do
		if v.Name == "SelectedMap" then
			v.Visible = false
		end
	end

	-- Reset player health and game state
	for index,player in pairs(game:GetService("Players"):GetPlayers()) do -- gets all the players
		player:LoadCharacter() -- forces the respawn
	end
	
	-- Call reset function to reset game state after the map spawns
	rs.ResetEvent:FireAllClients()
	task.wait(900)
	resetGameState()
	for index,player in pairs(game:GetService("Players"):GetPlayers()) do -- gets all the players
		player:LoadCharacter() -- forces the respawn
	end
end

players.PlayerAdded:Connect(function(player)
	print(player)
	if isGame then
		player.PlayerGui.Tools.MainFrame.ScrollingFrame.Lobby = false
	else
		player.PlayerGui.Tools.MainFrame.ScrollingFrame.Lobby = true
	end
end)
3 Likes

what type of script is this code in

server script in serverscriptservice

alright so what im getting is everything works, but if a player joins while the game is running, it doesnt work? or is it while the map is being chosen it doesnt work for new players

1 Like

while the map is being chosen and someone new joins it doesnt work and if someone joins during a match the tool gui doesnt appear

1 Like

im not too good on scripting, ive only recently learned scripting, but as far as i can tell i cant find anything, sorry