Check out my map voting system

I would like you to check out my map voting system and help give me some feedback and tell me what you think of it and or any bugs/problems with it

THIS IS NOT A TUTORIAL!!!

here’s the map voting system test place:
testing place.rbxl (138.7 KB)

its not completely finished but its getting there

i’ll explain it to you so you can get the idea or gist of what the map voting system is like

it is a map vote system that you step on a part to vote on the map of your choosing (not a gui)

well when i tried making i tried to make it as simple as possible

for adding maps all you have to do is to drag and drop your maps onto server storage in the maps folder and removing is just removing the map that you don’t want
image

this uses knit for the sending and receiving remote events for the client
the touch part of the voting system is uses a local script. im not sure local scripts and touch events together but i did go off of this topic here: Verifying part touches via the client for client-side interactions
not sure if i should switch to server or keep it local, and i thinking i’ll switch from using touch events cause well they aren’t the most reliable for hit detection

anyways, after the player touches the part it sends a remote function and the server checks for multiple things such as if they already voted or if they haven’t or maybe its not even time to vote.

well if its player hasn’t voted the pad will turn green, if they already have then the last pad that they touched will turn back to yellow and the part that they just touched will turn green, and if it’s not time to vote then the pads will remain yellow and the pad that you touched will remain yellow

for when the player votes it sends a remote function and if player has not voted then it increases the value by 1 for the map that they just voted for and if they already voted then it will decrease map that they last voted for by 1 and increase the value for the map that they just voted by 1 and when its not time to vote then it does not increase or decrease by any interval ( its basically the same thing like the local script but it just increases or decreases the map votes)

now here are the values for the server

--example
local mapsVotes = {

	["Players"] = {
		--PlayerName = mapIndex
	},

	["Votes"] = {
		--[1] = 0,
		--[2] = 0,
		--[3] = 0
	},

	["Maps"] = {
		--[1] = {["name"] = "mapName"}
		--[2] = {["name"[ = "mapName"}
		--[3] = {["name"] = "mapName"}
	},

}

so basically this is a dictionary for roblox(if you don’t know then go here)

and how this works it stores the map index as a number so map 1 would be [1] and map 2 will be [2] and map is [3] so for players, it stores the player and it equal the map index such as IceCreamPickels = 2, and then the votes are stores also using the map index so map and then the amount of votes in total such as [1] = 2, so map 1 has 2 votes, and then lastly for the maps, it will have the map index, then another value such as name will equal the map name, so map 1 could be [1] = {“name” = “desert”}
the reason why i use number indexes because it’s easier than trying to find the string value and since their numbers, the table will be organized in order by the index of the map

also i named the parts after the map indexes as well since i can find what part by just the map index and change it with ease, the script can look for the number
image

there are 2 main scripts for the server, 1 module script that has the functions and 1 server script that uses those functions from the module script
image

the first function gets 3 random maps that are different

module.getMaps = function()
	local mapChildren = maps:GetChildren()--table with all the maps
	local allmaps = {}

	for i,v in pairs(mapChildren) do
		allmaps[i] = v
	end

	for i = 1,amount do
		local randomMap = math.random(1,#allmaps)
		mapsVotes["Maps"][i] = {
			["name"] = tostring(allmaps[randomMap])
		}
		local mapName = tostring(mapsVotes["Maps"][i]["name"])
		mapNames[i].SurfaceGui.MapText.Text = mapName
		mapsVotes.Votes[i] = 0
		table.remove(allmaps, randomMap)
	end
	
	votingTime = true
end

so what it does, it gets all the maps from the map folder in serverstorage and then it puts them into a table called allmaps, and which that table is used to get random map, and it has a for loop that it grabs a map from allmaps and then removes it from the table and picks another map from the table allmaps it does it for 3 times and it also sets up the values for the dictionary for both votes and the maps

then the second function it basically resets everything

module.clearMaps = function()
	for _, pad in pairs(votepads:GetChildren()) do
		pad.Color = Color3.fromRGB(245, 205, 48)
	end
	for _, name in pairs(mapNames:GetChildren()) do
		name.SurfaceGui.MapText.Text = "None"
	end
	for _, vote in pairs(mapValues:GetChildren()) do
		vote.SurfaceGui.MapText.Text = 0
	end
	currentMap = nil
	votingTime = false
	mapsVotes["Maps"] = {}
	mapsVotes["Votes"] = {}
	mapsVotes["Players"] = {}
end

first it loops through the votepads and change them all back to yellow
second it loops through the map names and resets it
third it resets the map values
and lastly it clears the tables inside the dictionary

module.addVote = function(player,map)
	if not votingTime then return end --if not time to vote
	local votedMap = mapsVotes.Players[player]
	if votedMap then --if player already voted
		if map == votedMap then --if player voted for the same map
			--print(mapsVotes.Votes)
			return--does nothing
		else -- if player voted a different map
			mapsVotes.Votes[votedMap] -= 1 --finds the oldmap and minus 1 vote
			mapsVotes.Players[player] = map 
			mapsVotes.Votes[map] += 1
			updateVote(votedMap)
			updateVote(map)
			--print(mapsVotes.Votes)
			return "B", votedMap
		end

	else --if player hasn't voted
		mapsVotes.Players[player] = map
		mapsVotes.Votes[map] += 1
		updateVote(map)
		print(mapsVotes)
		return "A"
	end
end

thirdly then it tries to find if the player already has voted for the map, then if not then it’ll add the vote to the map that they first voted for, if they already voted for the map and picked a different map then it’ll subtract a vote from the map that the last voted for, and then it change the player map value to the map that they just picked, then it’ll add that value to the map that they just picked, for both functions it’ll just update the display for the maps

the last main function is picks the winner map

module.findWinner = function()
	local highestnumber = 0
	local highest

	--print(mapsVotes.Votes)
	for i, v in pairs(mapsVotes.Votes) do
		if v > highestnumber then
			highestnumber = v
			highest = mapsVotes.Maps[i]
		end
	end
	
	if not highest then highest = mapsVotes.Maps[math.random(1,#mapsVotes.Maps)] end

	currentMap = maps[highest.name]
	print(currentMap)
	
	votingTime = false

	return highest
end

it sets up 2 variables one for highest number, and two for the map index
then there is a for loop that loops through each map vote and compares the value with the highest number, if the value exceeds the highest number then it’ll replace it, it’ll go do this for each map, and if there isn’t a highest map then it’ll randomly select a random map
lastly it’ll set the current map with the map with the most votes

sorry for this to be a tad bit lengthy, but i’d just wanna clear things up, and also my explanations might not be the best so, i’ll try my best to correct myself, and also i just wanna make a map voting system that will be easy to use and will be versatile for when using for games and such, and thanks for reading this, and please let me know on some suggestions for me to help improve my map voting system

updated version: map vote system

4 Likes

Should be moved to Code Review rather than here.

1 Like

any idea what i need to fix or to improve?

1 Like

Try defining functions this way as it is more aesthetically pleasing.

function Module.clearMaps()
	for _, pad in ipairs(votepads:GetChildren()) do
		pad.Color = Color3.fromRGB(245, 205, 48)
	end
	for _, name in ipairs(mapNames:GetChildren()) do
		name.SurfaceGui.MapText.Text = "None"
	end
	for _, vote in ipairs(mapValues:GetChildren()) do
		vote.SurfaceGui.MapText.Text = 0
	end
	currentMap = nil
	votingTime = false
	mapsVotes["Maps"] = {}
	mapsVotes["Votes"] = {}
	mapsVotes["Players"] = {}
end

Use ipairs while looping through arrays, here u could use that instead of pairs, as it is more efficient.

why is that? it still does the same thing, and plus i don’t think the performance would be any better, and what makes it more efficient?

Its just more organised, seperates the functions out and makes it easier to modify later on.

what about the ipairs, do they make a difference on performance than just pairs?

In pairs is a form of iterration, it doesnt really matter where you do it as the code is still being run and adding memory usage regardless.

Little complicated but its cool :D, but when I try to review the script so that I can have an idea its little complicated lol but its cool :D.

1 Like