Why is this nil?

Are you adding the votes from a LocalScript or Script? It looks like you’re voting using a GUI.

Heres the full script of it up until the end of voting.

local RS = game.ReplicatedStorage
local SS = game.ServerStorage
local Maps = SS:WaitForChild("Maps")
local Status = RS:WaitForChild("Status")
local intermissionLength = 15
--local Timer = game.ReplicatedStorage.Timer
--local data = require(game.ReplicatedStorage["Questions/Answers"])
local StatusMap = RS:WaitForChild("StatusMap")
local highestNumber = 0
local chosen = nil
local MS = game:GetService("MarketplaceService")

--[[local function findLowest()
	local t = {99999,game:GetService("Players"):GetPlayers()[1]}

	for _,v in pairs(game:GetService("Players"):GetPlayers()) do
		if v.leaderstats.Letters then
			if v.leaderstats.Letters.Value < t[1] then
				t[2] = v
				t[1] = v.leaderstats.Letters.Value
			end
		end
	end

	return(t)
end
]]

--Status.Value = "Waiting for enough players (1/3)"
--if not (#game.Players:GetPlayers() > 1) then repeat task.wait() until game.Players.NumPlayers >=3 end
Status.Value = "Intermission:"

task.wait(3)

Status.Value = "15"
for i=1,intermissionLength do
	task.wait(1)
	local new = tonumber(Status.Value)-1
	Status.Value = tostring(new)
	game.ReplicatedStorage.SafeVoting:FireAllClients(true)
end
game.ReplicatedStorage.SafeVoting:FireAllClients(false)
--END OF INTERMISSION

local plrs = {}

for i,player in pairs(game.Players:GetPlayers()) do
	if player then
		table.insert(plrs,player) --add plr
	end
end

local padVotes = {
	["Bedroom"] = game.ReplicatedStorage.Votes.Bedroom,
	["MrBeast"] = game.ReplicatedStorage.Votes.Mrbeast,
}

local padVotes = {
	["Bedroom"] = game.ReplicatedStorage.Votes.Bedroom,
	["MrBeast"] = game.ReplicatedStorage.Votes.Mrbeast,
}
-- I removed .Value at the end

for i, v in pairs(padVotes) do
	local number = v.Value
	if number > highestNumber then
		highestNumber = number
		-- as mentioned you're not accounting for ties, you should think of a system to account for ties, maybe write a few functions to account for these scenarios.
	else if number == highestNumber then
			print('tie')
		end
	end
end

local ChosenMap = tostring(chosen)
print(chosen)
print(ChosenMap)

task.wait(1)
if ChosenMap == nil or ChosenMap == "0" or ChosenMap == "nil" then
	StatusMap.Value = "no map has been chosen!"
	local AvailableMaps = Maps:GetChildren()
	ChosenMap = tostring(AvailableMaps[math.random(1,#AvailableMaps)])
	task.wait(2)
	StatusMap.Value = "Map voted: " ..ChosenMap.. "!"
else
	StatusMap.Value = "Map voted: " ..ChosenMap.. "!"
end

task.wait(1)

Status.Value = "Game starting!"

It waits for the player to vote for 15 seconds.

Yes its a gui and im adding the votes from a local script.

is the local script managing adding votes, or is that the server?

There you go, that’s the problem! You’re adding votes from a LocalScript manually. The server cannot see any changes the LocalScript makes.

In order for the votes to count, you must send the vote from the client to the server using RemoteEvents and RemoteEvent:FireServer().

1 Like

I am not sure what you mean by that i’m so sorry, but I can explain to you what the local script does. The local script checks if its been clicked, and it +1’s the intvalue of the voted map. Here is the entire script if I didn’t explain it properly or if you got confused lol:

while task.wait() do
	game.ReplicatedStorage:WaitForChild("Votes"):FindFirstChild(script.Parent.Parent.Name).Value = script.Parent.Value
end

What frozen said above. Local scripts only affect what the clients game individually. That means on each individual client sees what that individual player voted for, and the server never sees it because it doesn’t receive the changes to the client. The server is just going based on the fact it found the value nil.
I would add it would be better if you preset the votes to a value of 0, as that is another reason why the system is not working. You need to account for the fact there will be round players might not vote at all.

Does not change anything, not sure if I am doing it wrong. Here is my code incase I am doing something wrong:

--local script
script.Parent:GetPropertyChangedSignal("Value"):Connect(function()
	game.ReplicatedStorage.VotingTransfer:FireServer(script.Parent.Parent.Name)
end)

--server script inside of SSS.
game.ReplicatedStorage.VotingTransfer.OnServerEvent:Connect(function(player,votetoaddto)
	game.ReplicatedStorage.Votes:FindFirstChild(votetoaddto).Value +=1
end)

I have accounted for those last 2 things. If noone votes, the game will automatically pick one itself, and at the end of every round, the values all go back to 0.

I’d make sure it prints the value when you test if it’s still not working. Might be good to double-check.
I think you’re overcomplicating it as well. when the player presses a button, instead of changing the value client side, just fire the change remove event, and send the string of the button option over instead.

Is that a StringValue you’re using to store the map that the player voted for?

No it is an IntValue;

Not sure what you’re trying to accomplish here then. You should be firing the server when the button is clicked. So, use MouseButton1Click instead, on the map buttons to fire when the button is clicked.

script.Parent.map_button_name_here.MouseButton1Click:Connect(function()
	game.ReplicatedStorage.VotingTransfer:FireServer(script.Parent.Parent.Name)
end)
1 Like

The local script inside of there also -1’s the vote if they choose somewhere else. How would I make sure that it also tells the remote event to do that aswell?

local plr = game.Players.LocalPlayer

script.Parent.MouseButton1Click:Connect(function()
	if plr.Character:FindFirstChild("VotingTag") then
		local tag = plr.Character:FindFirstChild("VotingTag")
		if tag.Value ~= script.Parent.Parent.Name then
			if tag.Value == "" or tag.Value == nil then
				script.Parent.Parent.NumVotes.Value +=1
				tag.Value = script.Parent.Parent.Name
			else
				local t = plr.PlayerGui.Round.MFrame.ScrollingFrame:FindFirstChild(tag.Value)
				t.NumVotes.Value -=1
				script.Parent.Parent.NumVotes.Value +=1
				tag.Value = script.Parent.Parent.Name
			end
		end
	end
end)

Store on the client side the vote you have already, and send that over as an additional parameter. Also, add a check to whether the player voted already. The check tells the server if it needs to remove a vote, and if it does, it finds the additional parameter and removes a vote from it.

script.Parent.map_button_name_here.MouseButton1Click:Connect(function()
	game.ReplicatedStorage.VotingTransfer:FireServer(script.Parent.Parent.Name, script.Parent.Parent.Parent.Voted.Value, script.Parent.Parent.Parent.PreviousVote.Value)
end)

Voted should be a boolean, and PreviousVote a string. At this point tho just find the container all these values are in instead of finding directly from the part. It will save your sanity.

Edit: You can also have these pre-existing in the local script somewhere too.

1 Like

Here’s what I did:

  • Store a StringValue in the client to store the map the player voted for
  • When player clicks on a map button, compare the StringValue’s value and the button’s name
  • If it’s not equal, then subtract a vote from the old map and add a vote from the new map
  • When everything is done, set the StringValue’s value to the button’s name

Example

map_vote_example.rbxl (49.4 KB)

1 Like