Map voting system

So, I have made a map voting system following a @Spooks_HD tutorial from 2017 on YouTube, it should have removed your vote when you get off the voting platform but instead I got an error saying " ServerScriptService.Server:57: attempt to index local ‘c’ (a number value)". I have checked the video and my code multiple times without success, if anyone could help that would be great.

Explorer Tab

The code
Client
--Player--
local player = game.Players.LocalPlayer
local char = player.Character or player.CharacterAdded:wait()
local gui = player:WaitForChild("PlayerGui")
local ui = gui:WaitForChild("ui")

--Assets--
local rep = game.ReplicatedStorage
local assets = rep.Assets

--Maps--
local maps = assets.Maps

--Signals--
local signals = assets.Signals
local event = signals.Event
local fevent = signals.FEvent

--Game Variables--
local Game = workspace.Game
local stats= Game.Stats

--Static Variables--
local vars= {
	currentVote = nil;
	services = {};	
}

--Primary Events--
event.OnClientEvent:connect(function(variables)
	 if variables.reason == "startVoting" then
		table.insert(vars.services, game("GetService","RunService").RenderStepped:connect(function()
			local ray = Ray.new(char.PrimaryPart.CFrame.p, Vector3.new(0,-1000,0))
			local object = workspace:FindPartOnRay(ray, char, false, false)
			if object and object.Name:match("VotingPad") then
				local votingPadNum = tonumber(object.Name:match("%d+"))
				if vars.currentVote==nil then
					vars.currentVote = votingPadNum
					event:FireServer({reason="voteOnMap"; itemNum=votingPadNum;})
				elseif vars.currentVote~=votingPadNum then
					vars.currentVote = votingPadNum
					event:FireServer({reason="voteOnMap"; itemNum=votingPadNum;})
				end
			elseif vars.currentVote~=nil then
				vars.currentVote=nil
				event:FireServer({reason="removeFromVote"})
			end
		end))
	elseif variables.reason == "endVoting" then
		for a,b in pairs(vars.services) do
			b:disconnect()
		end
		vars.services={}
	end
end)

--Initial Title Updater--
game("GetService","RunService").RenderStepped:connect(function()
	ui:WaitForChild("Title").Text = stats.Status.Value
end)
Server
--Assets--
local rep = game.ReplicatedStorage
local assets = rep.Assets

--Maps--
local maps = assets.Maps

--Signals--
local signals = assets.Signals
local event = signals.Event
local fevent = signals.FEvent

--Static Variables--
local mapVotes = {}

--Game Variables--
local Game = workspace.Game
local stats= Game.Stats
local settings = {
	mapVoteTime = 15;
	mapVoteDelay = 3;
	playersRequired = 1;	
}

--Primary Events--

--[[
	ARRAY = mapVotes
		MapArray
			Id
			mapName
			players
				player = userId

--]]

event.OnServerEvent:connect(function(player, variables)
	if variables.reason == "voteOnMap" then
		--First check if a player already voted, if so change vote
		for a,b in pairs(mapVotes) do
			for c,d in pairs(b.players) do
				if c.player == player.UserId then
					table.remove(b.players, d)
					break
				end
			end
		end
		--Add player to the map votes.
		for a,b in pairs(mapVotes) do
			if b.id == variables.itemNum then
				table.insert(b.players, {player = player.UserId})
			end
		end
	elseif variables.reason == "removeFromVote" then
		for a,b in pairs(mapVotes) do
			for c,d in pairs(b.players) do
					if c.player == player.UserId then
					table.remove(b.players, d)
					break
				end
			end
		end
	end
end)

function getMap()
	local randomMap = maps:GetChildren()[math.random(1,#maps:GetChildren())]
	for a,b in pairs(mapVotes) do
		if b.mapName == randomMap.Name then
			return getMap() 
		end
	end
	return randomMap.Name
end

while wait() do
	if #game.Players:GetPlayers() < settings.playersRequired then
		local playersNeeded = settings.playersRequired-#game.Players:GetPlayers()
		stats.Status.Value = playersNeeded..""..((playersNeeded==1 and " Player") or " Players").." needed to play!"
	else
		--Assign maps
		mapVotes={}
		for a,b in pairs(Game.Special.VotingPads:GetChildren()) do
			table.insert(mapVotes, {id = tonumber(b.Name:match("%d+")); mapName = getMap(); players = {};})
		end
		
		--Fire clients, start sending in votes.
		event:FireAllClients({reason="startVoting"})
		
		-- Do main loop
		local start = tick()
		while wait() do
			if tick()-start >= settings.mapVoteTime then break end
			local secondsLeft = math.floor(settings.mapVoteTime-(tick()-start))
			stats.Status.Value = secondsLeft.." "..((secondsLeft==1 and "Second") or "Seconds").. " Left to Vote!"
			for a,b in pairs(Game.Special.VotingPads:GetChildren()) do
				local playersVoting, mName
				for d,c in pairs(mapVotes) do
					if c.id == tonumber(b.Name:match("%d+")) then
						playersVoting=#c.players
						mName=c.mapName
						break 
					end
				end
				b.sGui.Title.Text = mName.." - "..playersVoting..""..((playersVoting==1 and " Voter") or " Voters")
			end
		end
		
		--Get winner
		table.sort(mapVotes, function(a,b) return #a.players>#b.players end)
		
		for a,b in pairs(Game.Special.VotingPads:GetChildren()) do
			if tonumber(b.Name:match("%d+")) == mapVotes[1].id then
				b.sGui.Title.Text = "Winner!"
				stats.Status.Value = mapVotes[1].mapName.." was chosen!"
			else
				b.sGui.Title.Text  = "Lost Vote!"
			end
		end
		wait(settings.mapVoteDelay)
	end
end

PS: I am new to the dev forum so if I have done anything wrong please tell me.

3 Likes

In the server script, line 57, replace c.id with d.id. c is the index of the player in the table, d is the value you’re looking for. It is also very important to learn how to debug (fix) errors on your own. Errors are very self-explainable;.Server.57:attempt to index local 'c' (a number).
It tells you what script and where exactly the error is in: Server line 57, which helps a lot, you can even click the error message and it will tranport you there. And it tells you what’s wrong: attempt to index local c (a number value), attempt to index something means you were trying to index (doing table[value] or table.c) a value that wasn’t a table. With that information at hands, you can very simply realise that c is a number, it clicks in your brain.

4 Likes

@starmaq already pointed out the problem but I would like to add that in the future you should rename your variables to be more descriptive. The variables “a”, “b”, “c” and “d” tell me nothing about them. It would also help yourself in future debugging.

2 Likes

Instead of using c, try to use d, maybe that will work.

1 Like

@starmaq I tried it and got another error, at line 58 saying ServerScriptService.Server:58: bad argument #2 to 'remove' (number expected, got table), this time I tried to debug it using the error message but again nothing worked. :confused:

Line 58 ^ ^ ^

Ok, good job on finding which line the error comes from, try reading:it siad it expected a number, it got a table. This is the same problem, you need to switch d with c. Check for other things like this in your script, and make the switches

1 Like