How would I make a voting system?

So, I was making a Voting system for maps to be chosen the Problem is I don’t know how would I do it (Idea).

This is my Current system

  • Player Presses the Queue Button the Client checks a value in the Player that is Named InGame is equal to false (Meaning the player isn’t in game) and checks if the Player is already Queued up or not (Value inside of the Player) if he does it will fire a Remote event, The Server will check everything that the client checks incase they are exploiting after that it will add them into a table named Queue and setting the Queued Up Value to true and InGame to false After that it will connect to a new function called voting Checking if the Players in the queue are more or less than required if it is it will start the Voting, The problem is I don’t know how would I make the voting system.

Here are my full Scripts
Client

MainGui.QueueButton.MouseButton1Click:Connect(function()
	if Player.StatsFolder.InGame.Value == false and Player.StatsFolder.ReadyUp.Value == false then
		RemoteEvents.QueuedUp:FireServer()
		MainGui.LookingForPlayersFrame.Visible = true
		MainGui.QueueButton.Visible = false
		MainGui.LeaveQueueButton.Visible = true
	end
end)

Server Script

	if #InQueue <= MaxPlayers then
		for i = 10, 1, -1  do

			Signals.Status.Value = "Voting Has Began (" .. i .. ")"
			task.wait(1)
		end
	end
end



 
RemoteEvents.QueuedUp.OnServerEvent:Connect(function(Player)
	if Player.StatsFolder.InGame.Value == false and Player.StatsFolder.ReadyUp.Value == false then
		
		Player.StatsFolder.ReadyUp.Value = true
		Player.StatsFolder.InGame.Value = false
		table.insert(InQueue, Player.UserId)
		Voting()
	end
end)
2 Likes

It depends on how you want the voting system to be. The player is only allowed to vote once (case 1) or change their vote (case 2):

  • Case 1: Keep a seperate table which stores all the players that voted. For the map vote counts, I find using ObjectValues easier, you can use those to keep track of vote count.

  • Case 2: Keep a seperate table (2D table) which stores all the players that voted along with their chosen map, so that the vote can be taken away if a player votes for something else. The rest stays the same as case 1.

3 Likes

You could make a remote event, then attach what the player voted for, then in the server script add a vote to the number of votes for each map , then see which one has the most.

Of course what the player voted for can be accessed in many ways such as firing () parameters and values.

Also making a check if the player has already voted server side so they can’t just spam the event, or if the player wants to vote many times make for ex a value of what the player voted for or a server side table of the people who voted for what, and then see if they already voted for the same one, else it would just pass their vote to the other map option

2 Likes

Yeah, I know all of that but could you explain more like add a value inside replicated storage for choice 1, etc???

2 Likes

Could someone help me and go into details???

1 Like

Could someone help? it has been 4 hrs

1 Like

im not sure what everyone else had in mind but you could have a RemoteEvent for voting following roughly this idea:
Server → Clients : list of choices
Client displays choices
Clients → Server : player choice
Server stores players’ choices
Continue allowing Clients to send choices, overwrites previous choice until timer runs out

Here’s just a very simple example of some code to get user choice, store it, and then total it up
Note: it doesn’t handle invalid map choices or other bad data from the user
(This is untested)

local VoteEvent = ReplicatedStorage.VoteEvent

local MapChoices = {}


VoteEvent.OnClientEvent:Connect(function(player, choice)
  -- You might want to check if user choice is a legit map
  MapChoices[player.UserId] = choice
end)

function StartVoting(maps)
  MapChoices = {}
  VoteEvent:FireAllClients(maps)
end

function TotalVotes() --  There is probably a more efficient way to total votes, this was just the first way I thought of
  local sums = {}
  for plr, vote in pairs(MapChoices) do
    if sums[vote] == nil then
      sums[vote] = 1
    else
      sums[vote] += 1
    end
 end
 local highestval = -1
 local highest = nil
 for map, votes in pairs(sums) do
   if votes > highestval then
     highest = map
   end
 end
 MapChoices = {}
 return highest
end
2 Likes

Ok, Thanks before I try it I have a question, How do I make a random map that is never the same as the other it’s a bit hard to explain I’ll give you an example

function VotingStarted()
     local RandomMap1 = Maps:GetChildren[math.random(1,#Maps:GetChildren()]
      local RandomMap2 = Maps:GetChildren[math.random(1,#Maps:GetChildren()]
     local RandomMap3 = Maps:GetChildren[math.random(1,#Maps:GetChildren()]
 -- how would i make it that randommap1 never equals to randommap2 and also same with RandomMap3
end
1 Like

A simple method is to just keep choosing until its different
For example

function VotingStarted()
  local RandomMap1 = Maps:GetChildren[math.random(1,#Maps:GetChildren()]
  local RandomMap2 = Maps:GetChildren[math.random(1,#Maps:GetChildren()]
  while RandomMap2 == RandomMap1 do
    RandomMap2 = Maps:GetChildren[math.random(1,#Maps:GetChildren()]
  end

  local RandomMap3 = Maps:GetChildren[math.random(1,#Maps:GetChildren()]
  while RandomMap3 == RandomMap1 or RandomMap3 == RandomMap2 do
    RandomMap3 = Maps:GetChildren[math.random(1,#Maps:GetChildren()]
  end
end
2 Likes

Could someone help it has been 8 hours.

2 Likes