Voting via GUI system

You can write your topic however you want, but you need to answer these questions:

  1. I have built a Screen GUI system that all players see at the end of a round. Each player can Vote on another players submission.

  2. I am trying to get input on the best way to do this. I’ve already scripted it many ways and with my current GUI system it is not working exactly correct that I can tell. The GUI button gets pressed which applies a vote which is specific to a player. A remote event fires to the server. The server receives this info via a parameter and stores it into a table called VOTES. In this same remote event the winner is the highest Vote count. Currently it appears to be reporting the wrong player with the highest Vote. When I test 2 Players, I will have player 1 vote for player 2 and I do not give any votes to player 1 at all, yet it announces player 1 as the Winner.


  1. I have written the code in a lot of various ways through the last couple weeks, yet every time I end with something wonky and not quite right. I have a pretty complex round system built that this works along side.

Local Script inside of the GUI button

local button = script.Parent
local voteEvent = game.ReplicatedStorage.Voting


button.MouseButton1Click:Connect(function(playerWhoVoted)
	local playerWhoVoted = button.Parent.Name
	print(playerWhoVoted)
	local voteObjects = script.Parent.NumberVotes:GetChildren()
	for i, v in pairs(voteObjects) do
		if v:IsA("NumberValue") then						
			local playerGotVotes = v.Name							
				v.Value = v.Value + 1
				script.Parent.NumberVotes.Text = v.Value
				local VoteValue = v.Value
				print(VoteValue)		
				voteEvent:FireServer(playerWhoVoted, playerGotVotes, VoteValue)					
		end
	end	
end)

part of my Script inside of Server Script Service that handles the Voting/Winner

ResetVoting()

VoteEvent.OnServerEvent:Connect(function(playerWhoVoted, playerGotVotes)		
	-- Check if the player who is voting has already voted
	if table.find(PLAYERSwhoVOTED, playerWhoVoted) then
		print(playerWhoVoted)
		warn(playerWhoVoted.Name .. " tried to vote again!")
		return -- Exit the function, don't process the vote
	end
	table.insert(PLAYERSwhoVOTED, playerWhoVoted) -- Add the player to the list of voters
	if VOTES[playerGotVotes] then
		VOTES[playerGotVotes] = VOTES[playerGotVotes] + 1
	else		
		VOTES[playerGotVotes] = 1 
		print(VOTES)
	end
	print("Current votes:", VOTES)
	local winnerName = nil
	local highestVotes = 0	

	print(VOTES)
	for playerName, voteCount in pairs(VOTES) do
		print(voteCount)
		if voteCount > highestVotes or voteCount == highestVotes then
		
			highestVotes = voteCount
			winnerName = playerName
			print(winnerName)
			print(highestVotes)
			local playersonmap = Players:GetPlayers()
			for i, v in pairs(playersonmap) do
				print(v)
				local plrgui = v.PlayerGui
				local topic = plrgui.TimerGui.ImageLabel.Frame.topic
				topic.Text = "WINNERS:" .. winnerName ..  "VOTES: " .. highestVotes 							
				WinnerEvent:FireAllClients(topic.Text)
			end	
		end
	end	
end)
'''
3 Likes

I’m assuming playerWhoVoted is always the local player.

When calling FireServer, you don’t need to provide the local player as an explicit parameter - it is already provided. Try removing playerWhoVoted from the FireServer (but not from the OnServerEvent) and see if it resolves your issue

I recommend using this code:

-- LocalScript
local player = game.Players.LocalPlayer
local button = script.Parent
local voteEvent = game.ReplicatedStorage:WaitForChild("Voting")

button.MouseButton1Click:Connect(function()
	local voteObjects = script.Parent.NumberVotes:GetChildren()
	for _, v in pairs(voteObjects) do
		if v:IsA("NumberValue") then					
			local playerGotVotes = v.Name						
				v.Value += 1
				script.Parent.NumberVotes.Text = v.Value
				local VoteValue = v.Value	
				voteEvent:FireServer(playerGotVotes, VoteValue)					
		end
	end	
end)
-- Script
ResetVoting()

VoteEvent.OnServerEvent:Connect(function(playerWhoVoted, playerGotVotes, VoteValue)		
	-- Check if the player who is voting has already voted
	if table.find(PLAYERSwhoVOTED, playerWhoVoted) then
		print(playerWhoVoted)
		warn(playerWhoVoted.Name .. " tried to vote again!")
		return -- Exit the function, don't process the vote
	end
	table.insert(PLAYERSwhoVOTED, playerWhoVoted) -- Add the player to the list of voters
	if VOTES[playerGotVotes] then
		VOTES[playerGotVotes] = VOTES[playerGotVotes] + 1
	else		
		VOTES[playerGotVotes] = 1 
		print(VOTES)
	end
	print("Current votes:", VOTES)
	local winnerName = nil
	local highestVotes = 0	

	print(VOTES)
	for playerName, voteCount in pairs(VOTES) do
		print(voteCount)
		if voteCount > highestVotes or voteCount == highestVotes then
		
			highestVotes = voteCount
			winnerName = playerName
			print(winnerName)
			print(highestVotes)
			local playersonmap = Players:GetPlayers()
			for i, v in pairs(playersonmap) do
				print(v)
				local plrgui = v.PlayerGui
				local topic = plrgui.TimerGui.ImageLabel.Frame.topic
				topic.Text = "WINNERS:" .. winnerName ..  "VOTES: " .. highestVotes 							
				WinnerEvent:FireAllClients(topic.Text)
			end	
		end
	end	
end)
'''

The player parameter is already added by default, so the playerWhoVoted is being taken as the playerGotVotes.

Oh youre already doing that keystrokes

if voteCount > highestVotes or voteCount == highestVotes then

This means if two players have the same vote count, the last player in the loop becomes the winner.

And, you calculate and announce the winner inside the voting event immediately after a vote WHILE the voting phase is still open, this will repeatedly change the “winner” and announce it prematurely.

I was wondering about that being the issue and before i simply had it as

if voteCount > highestVotes then

end

So every time a vote is cast, the event will keep changing the winner. But what I want is to announce the winner when voting ends all the way around. I’m thinking of how to do this and I did feel this would cause an issue.

Ok yes I see, I keep forgetting that player is an explicit parameter, already there. Make sense what your saying on removing it if its not necessary.

1 Like

I’m thinking of using a bindable event, which I have never used before.

This worked. I moved the winner tallying outside of the remote event that was for the Voting. I used a bindable event between two scripts to determine the winner and push the data as necessary. It is now working well.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.