Can't Seem To Make A Gui Voting System

I am a little confused on how to make a voting system. Basically I have 3 choices, one is a bot mode, second is a player mode, and third is a player and bot mode just like the game Piggy. I have tried searching for tutorials, but I can’t seem to understand how to do it with a Gui. I know this is probably a lot to explain to me, since I don’t really have any experience on a voting system, but if you can then please give me as much detail as possible and anything that will help me figure this out.

Thanks For Reading! :grin:

4 Likes

Usually, people utilise a RemoteEvent from a Script and when voting starts they’ll use the FireAllClients method.

In the LocalScript you’ll want to Connect on OnClientEvent and open up the UI, there you’ll listen for clicks on the UI and FireServer back

Of course, you’ll have a OnServerEvent on the server that’ll handle each of the votes and add to a count mattering on the passed choice. Once all choices are made or the voting time is over you can Disconnect the OnServerEvent Connection and evaluate the collected votes.

Ensure to add a sanity check so Players cannot vote more than once (perhaps add their UserId to a dictionary.

4 Likes

What you can do is have any number of choices, we’ll define them as OPTION_x where x is the choice number. These will be stored in a LocalScript, and the actual instance will be any kind of GuiButton.

local VOTE_REMOTE --RemoteEvent instance that will be used to cast votes and display them to other clients

local MENU_OPTIONS = { --table where our option buttons are stored
    ['OPTION_1'] = --gui button option 1 instance
    ['OPTION_2'] = --gui button option 2 instance
    ['OPTION_3'] = --gui button option 3 instance
}

--now we will iterate through the table above using a k,v loop, and detect which option is chosen
for k,v in pairs(MENU_OPTIONS) do
    v.Activated:Connect(function()
        print('client chose option:',k)
        VOTE_REMOTE:FireServer(v) --send the player's choice to the server
    end)
end

now this will be a Script inside of ServerScriptService:

local VOTE_REMOTE --this is the same remote that is used by the localscript

local STORED_VOTES = {} -- an empty dictionary that will store all player votes
local VALID_OPTIONS = { -- table that contains all valid vote types
    ['OPTION_1'] = true;
    ['OPTION_2'] = true;
    ['OPTION_3'] = true;
}

function StoreVote(PLAYER,VOTE)
    if not VALID_OPTIONS[VOTE] then return end -- will discontinue function if the vote option isn't valid (basically a sanity check)
    STORED_VOTES[PLAYER] = VOTE

    --iterate through all votes for debugging purposes
    for k,v in pairs(STORED_VOTES) do
        print(k,'voted for:',v)
    end
end

function ProcessVotes() --call to choose an option among the votes cast
    local VOTE_RESULTS = {
        RESULT_OPTION_1 = 0
        RESULT_OPTION_2 = 0
        RESULT_OPTION_3 = 0
    }
    local MAX_TABLE = {} -- will explain this later
    for k,v in pairs(STORED_VOTES) do --k,v loop to tally votes
        local KEY = 'RESULT_'..(tostring(v))
        if VOTE_RESULTS[KEY] then
            VOTE_RESULTS[KEY] = VOTE_RESULTS[KEY] + 1
        end
    end
    for k,v in pairs(VOTE_RESULTS) do
        table.insert(MAX_TABLE,#MAX_TABLE+1,v)
    end

    local TOP_VOTE = math.max(unpack(MAX_TABLE)) --extremely hacky way to get the max value of a k,v dictionary, but it somehow works for me
    local CHOSEN_OPTION; --empty variable that will be defined in the loop below
    for k,v in pairs(VOTE_RESULTS) do
        if TOP_VOTE == v then
            CHOSEN_OPTION = k
        end
    end
    print(CHOSEN_OPTION,'was chosen')
    return CHOSEN_OPTION --in case it'll be used later
end

function ResetVotes() --call this function when the round ends or whatever
    STORED_VOTES = {} --sets all stored votes into an empty table
end

VOTE_REMOTE.OnServerEvent:Connect(StoreVote)

I wrote this in a bit of a hurry in-between classes so please let me know if any problems arise.

Hope this helped! :smiley:

7 Likes

It seems to always pick the third option and never the one with the most votes. Could you help me with this? And also where you said “gui button option 1 instance” that is where I define my gui button correct? Sorry I am just starting to understand this, Thanks So Much For The Help!

Yes, that’s where you define your button.

After re-reading my code, I think that the FireServer() function may have an error. Try sending the k variable rather than the v variable.

1 Like

Nope it is still choosing option 3 every time

Edit: It is also not printing this print(k,'voted for:',v) so something is either wrong with the table or function, because the function seems to not fire

This is because I didn’t call the function. You’ll have to adjust the code a bit so that the function actually fires.

I have set it up though, it still doesn’t fire, yes I did adjust the code to match my needs

Edit: nvm I got it to work

1 Like

Sooo question, basically just apply this to any gui button and it will work? Like that’s the whole system?

As long as the local script can define the buttons, it should work about anywhere.

If you correctly store your GuiButtons inside of the table MENU_OPTIONS, then yes, it should work with any system. Remember to store the two scripts in the right places.

Moving forward from this, it’s pretty important to make modular code; it becomes more flexible and in many cases can be re-used in other projects. I seldom hard-code parts of my game because it would be much, much easier to use a module from a previous game and improve it, rather than have to re-write the same script over and over again. Also, having modular scripts/code is more comprehensible and prevents you from having unintelligible spaghetti code when your game’s code reaches thousands of lines and beyond.

1 Like