You can write your topic however you want, but you need to answer these questions:
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.
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.
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)
'''
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
-- 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)
'''
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.
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.