Code issues - Vote system

Hello, I need to make my voting system take only 1 vote per player on each button and if you change your vote, the previous vote is 0, how can I do that?

Project Organization

image

Localscript:

-- Click on vote 1

script.Parent.Vote1.MouseButton1Click:Connect(function()

script.Parent.Con1:FireServer()

end)

-- Click on vote 2

script.Parent.Vote2.MouseButton1Click:Connect(function()

script.Parent.Con2:FireServer()

end)

-- Click on vote 3

script.Parent.Vote3.MouseButton1Click:Connect(function()

script.Parent.Con3:FireServer()

end)

ServerScript:

-- If click on vote 1
local vote1 = {}
local vote2 = {}
local vote3 = {}

-- function to switch their vote
local function RemovePreviousVote(player, current: string) : boolean
	local verdict = false

	for index, id in pairs(vote1) do
		if id == player.UserId and current ~= "vote1" then
			table.remove(vote1, index) -- remove the vote
			verdict = true
			break -- end the loop
		end
	end

	for index, id in pairs(vote2) do
		if id == player.UserId and current ~= "vote2" then
			table.remove(vote2, index) -- remove the vote
			verdict = true
			break -- end the loop
		end
	end

	for index, id in pairs(vote3) do
		if id == player.UserId and current ~= "vote3" then
			table.remove(vote3, index) -- remove the vote
			verdict = true
			break -- end the loop
		end
	end

	return verdict
end

script.Parent.Con1.OnServerEvent:Connect(function(player)
	local didRemove = RemovePreviousVote(player, "vote1") -- remove any other votes

	if not table.find(vote1, player.UserId) then -- the player already voted
		table.insert(vote1, player.UserId) end-- add the player to a table

	local votecount = script.Parent.Count -- don't do ".Value" because it won't update anything

	if didRemove then
		votecount.Value -= 1
	else
		votecount.Value += 1
	end
	print(votecount.Value)

	local counter = script.Parent.VoteCount1
	counter.Text = "vote number: "..tostring(votecount.Value)
end)

-- If click on vote 2
script.Parent.Con2.OnServerEvent:Connect(function(player)
	local didRemove = RemovePreviousVote(player, "vote2") -- remove any other votes

	if not table.find(vote2, player.UserId) then -- the player already voted
		table.insert(vote2, player.UserId) end -- add the player to a table

	local votecount = script.Parent.Count -- don't do ".Value" because it won't update anything

	if didRemove then
		votecount.Value -= 1
	else
		votecount.Value += 1
	end
	print(votecount.Value)

	local counter = script.Parent.VoteCount2
	counter.Text = "vote number: "..tostring(votecount.Value)
end)

-- If click on vote 3
script.Parent.Con3.OnServerEvent:Connect(function(player)
	local didRemove = RemovePreviousVote(player, "vote3") -- remove any other votes

	if not table.find(vote3, player.UserId) then -- the player already voted
		table.insert(vote3, player.UserId) end -- add the player to a table

	local votecount = script.Parent.Count -- don't do ".Value" because it won't update anything

	if didRemove then
		votecount.Value -= 1
	else
		votecount.Value += 1
	end
	print(votecount.Value)

	local counter = script.Parent.VoteCount3
	counter.Text = "vote number: "..tostring(votecount.Value)
end)

How it looks in workspace

You don’t need three remotes for this purpose. This is not complete code, but the idea might perform better than what you have currently.

On the client:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local myRemote = ReplicatedStorage.Events.MyRemote

local vNum = 0
for _,  button in pairs({Vote1, Vote2, Vote3}) do
       vNum = vNum + 1
       button.MouseButton1Click:Connect(function()
              myRemote:FireServer(vNum)
       end)
end

On the server:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local myRemote = ReplicatedStorage.Events.MyRemote

local voteTable = {
        [1] = {}
        [2] = {}
        [3] = {}
}

myRemote.OnServerEvent:Connect(function(plr, voteNum)
     if not voteNum or voteNum > 3 or voteNum < 1 then return end
     
     for _, tab in pairs(voteTable) do
           local ind = table.find(tab, plr)  
           if  ind then
                  table.remove(tab, ind)
                  break
           end
     end

     table.insert(voteTable[voteNum], plr)
end)

3 Likes

I think it doesn’t work for me, how should I implement this in my code? I got a little confused :frowning: sorry about that

No worries!

The basic concept behind the script is to create one remote that fires which item the player votes for. From there, the server reads this value from the player and adjusts the table accordingly.

Something like this on a conceptual level:

  • Player → myRemote(voteNum) → Server, then server stores the new vote

The vote number can easily be found. If you look on the example code I posted earlier, I just use a counter for this purpose (the variable vNum on the local script).

The server can read the player and the vote number when the remote event is fired. The adjustment to the table is pretty logical from there.

The way I created the votesTable is with one table that has three different subtables each indexed according to the vote number.

The server reads through the table when the remote is fired and removes any instances where the player is found.

After that, the player is added again into the appropriate table within the voteTable (corresponding to their vote).

You may want to create another remote which supplies updates of the voteTable to the player. This way you can update the UI based on the latest information from the server.

1 Like

I really don’t understand how to add this to my script, could you help me with that please? :frowning: