Problem: Accessing Server From Client with Value (Solved)

Let me explain from the start, I have made a folder called Gamemodes in ServerStorage, in the Gamemodes folder there are a bunch of other folders that are like maps/game modes. In those other folders I have added a NumberValue to determine the amount of time that you get to complete each map. Now I have tried to make it work, but I just can’t, I will send my Client-Sided script as well as my Server-Sided script and maybe one of you can help me debug this.

-- Server-Sided Script --
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local Events = ReplicatedStorage.Events
local GamemodeRandomize = Events.GamemodeRandomize
local TimeValue = Events.TimeValue

local GamemodesFolder  = ServerStorage:WaitForChild("Gamemodes")

GamemodeRandomize.OnServerEvent:Connect(function()
	local folders = {}
	for _, item in pairs(GamemodesFolder:GetChildren()) do
		if item:IsA("Folder") then
			table.insert(folders, item)
		end
	end

	if #folders == 0 then
		warn("No folders found in Gamemodes.")
		return
	end

	local randomIndex = math.random(1, #folders)
    chosenFolder = folders[randomIndex]

	local clonedFolder = chosenFolder:Clone()
	clonedFolder.Parent = workspace.Modes
end)

TimeValue.OnServerEvent:Connect(function(player)
	if chosenFolder then
		local Time = chosenFolder:FindFirstChild("Time")
		if Time and Time:IsA("NumberValue") then
			TimeValue:FireClient(player, Time)
		else
			warn("Time object not found in the chosen folder.")
		end
	else
		warn("No chosen folder available")
	end
end)
-- Client-Sided Script 
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local Events = ReplicatedStorage.Events
local TimeValue = Events.TimeValue

		TimeValue:FireServer()
		TimeValue.OnClientEvent:Connect(function(Time)
			if Time and Time:IsA("NumberValue") then
				for i = Time.Value, 1, -1 do
					Info.Text = tostring(i)
					if i == 4 then
						Sounds.Countdown:Play()
					end
					if i == 1 then
						Sounds:WaitForChild("Suspense"):Stop()
					end
					task.wait(1)
				end
			else
				warn("Received Time is not valid or not an NumberValue.")
			end
		end)
-- this is not all the script but the part I need help with --
3 Likes

Before I start analyzing this, what outputs do you get? you can add break points or just print (if you don’t know how to use breakpoints.) that would be highly appreciated!

3 Likes

Hello, thank you for responding, I have added a lot of Debugs like prints, warns etc… and it warned me with the message “Received Time is not valid or not a NumberValue. - Client - MainScript:177”

2 Likes

Ok I’ll look into it. It takes at least 30 mins to understand and look for bugs. fortunately you’ve already refactored your code.

2 Likes

Okay, thank you, I appreciate it, I’ll see you in 30 then!

You must be writing a long message because I’ve seen you typing for like almost 10 minutes

I had to go eat, I did find a few issues…

Oh okay, so what are the issues?

Since I’m not given the full script(s), my final conclusion may not be too accurate.


Concerns

  1. On the server-side script, you call the value chosenFolder, which is not there so I set it to nil for now. (assuming that you eventually get a “chosenFolder”)
  2. I also want you to look into UnreliableRemoteEvents because you heavily use RemoteEvents, please know RemoteEvents should be used to send large amounts of data, in order, and this takes time…

Issues (Focus here!)

  1. Also I think you should use RemoteFunctions instead of remote events, because your doing a client to server to client. (asking for value from server.)

Please let me know if you still encounter issues.

I’m sorry but I didn’t understand anything you said…

So basically the same scripts but just instead of using RemoteEvent logic I use remotefunction logic?

Remote Functions vs Remote Events
As you know, Remote Events use FireServer and FireClient/FireAllClients, which is one-way communication. BUT, Remote Functions is two-way meaning it can be used to ask for an output, like in your case, your asking the server to give you the time value.

0d20f9cb5d71ceaed43a378b4ebd639e6c876723_2_550x500

Yes, use remote functions instead.

Alright thank you for helping me understand better

		local timeValue = TimeFunction:InvokeServer()

		if type(timeValue) == "number" then
			for i = timeValue, 1, -1 do
				Info.Text = tostring(i)
				if i == 4 then
					Sounds.Countdown:Play()
				end
				if i == 1 then
					Sounds:WaitForChild("Suspense"):Stop()
				end
				task.wait(1)
			end
		else
			warn("Received Time is not a number.")
		end

–client side

TimeFunction.OnServerInvoke = function(player)
	if chosenFolder then
		local Time = chosenFolder:FindFirstChild("Time")
		if Time and Time:IsA("NumberValue") then
			return Time.Value
		else
			warn("Time object is not valid or not a NumberValue.")
			return 0
		end
	else
		warn("No chosen folder available.")
		return 0
	end
end

– server side

Does this work, I see you changed Time to Time.Value, im testing it out and im getting nil. are you intially trying to just get the time and not edit it or the other way around?

Yeah no it doesn’t work and at this point I’m just thinking of re-writing it.

This “TimeValue” is exactly parented where, I’m finding out that remote functions yield/wait. The folder has to be inside a place that will load as soon as the client does, like replicatedStorage or replicatedFirst, or you can use this Module

Wait, cant you just get the value from doing the original way you used to do it? you are just using a for loop to get the value.

Server Script

TimeValue:FireClient(player, Time.Value)

Local Script

TimeValue.OnClientEvent:Connect(function(Time:number)
	if Time and tonumber(Time) then
		for i = Time, 1, -1 do
			Info.Text = tostring(i)
			if i == 4 then
				Sounds.Countdown:Play()
			end
			if i == 1 then
				Sounds:WaitForChild("Suspense"):Stop()
			end
			task.wait(1)
		end
	else
		warn("Received Time is not valid or not an number.")
	end
end)

I’ll be waiting, If this still doesn’t work. recommend you start self debugging (finding ways to look for problems in your code), and researching about what your using.

Hello, sorry for not responding! I had to go do something and then forgot about this. Anyhow I implemented your code in the game, the time kinda works, but it mixed with the other maps, that’s why the “local chosenFolder = nil” so you can use the folder to know which timer goes on which chosen map. Now the timer does work but it’s always 90 seconds, 90 seconds was the original time.

TimeValue.OnServerEvent:Connect(function(player)
	if chosenFolder then
		local Time = chosenFolder:FindFirstChild("Time")
		if Time and Time:IsA("NumberValue") then
			TimeValue:FireClient(player, Time.Value)
		else
			warn("Time object is not valid or not a NumberValue.")
		end
	else
		warn("No chosen folder available.")
	end
end)

this is my entire ServerScript code, is that what you mean?