Need help with this RemoteFunction based data grabber

Hello, I’m using a RemoteFunction so the client can request it’s data. I’m pretty sure it’s because it is not getting the “player” variable, but I don’t understand why.

Client, narrowed down to the part that is having an issue.

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local eventsFolder = ReplicatedStorage:WaitForChild("Events")
local requestNightDataEvent = eventsFolder:WaitForChild("RequestNightData")

local localPlayer = game.Players.LocalPlayer
local maxUnlockedNight = requestNightDataEvent:InvokeServer("MaxNightUnlocked")

Server

local DataStoreService = game:GetService("DataStoreService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")

local database = DataStoreService:GetDataStore("data")
local sessionData = {}

local eventsFolder = ReplicatedStorage:WaitForChild("Events")
local requestNightDataEvent = eventsFolder:WaitForChild("RequestNightData")

function PlayerAdded(player)
	
	local success = nil
	local playerData = nil
	local attempt = 1
	
	repeat
		success, playerData = pcall(function()
			return database:GetAsync(player.UserId)
		end)

		attempt += 1
		if not success then
			warn(playerData)
			task.wait(3)
		end
	until success or attempt == 5
	
	if success then
		print("Connected to database")
		if not playerData then
			print("Assigning default player data")
			playerData = {
				["MaxNightUnlocked"] = 1,
				["Wins"] = 0
			}
		end
		sessionData[player.UserId] = playerData
	else
		warn("Unable to get data for", player.UserId)
		player:Kick("Unable to load your data. If this problem persists try again at a later time.")
	end
	
	-- add leaderstats here
end
Players.PlayerAdded:Connect(PlayerAdded)

function PlayerRemoving(player)
	if sessionData[player.UserId] then
		local success = nil
		local errorMessage = nil
		local attempt = 1
		
		repeat
			success, errorMessage = pcall(function()
				database:SetAsync(player.UserId, sessionData[player.UserId])
			end)
			
			attempt += 1
			if not success then
				warn(errorMessage)
				task.wait(3)
			end
		until success or attempt == 5
		
		if success then
			print("Data saved for", player.Name)
		else
			warn("Unable to save for", player.Name)
		end
	end
end
Players.PlayerRemoving:Connect(PlayerRemoving)

function ServerShutdown()
	if RunService:IsStudio() then
		return
	end
	
	print("Server is shutting down, saving data!")
	for i, player in ipairs(Players:GetPlayers()) do
		task.spawn(function()
			PlayerRemoving(player)
		end)	
	end
end
game:BindToClose(ServerShutdown)

local function GetNightData(player, dataType)
	if dataType and player then
		local maxNightUnlocked = sessionData[player.UserId][dataType]

		return maxNightUnlocked
	else
		warn("Player or DataType is invalid.")
		return nil
	end
end
requestNightDataEvent.OnServerInvoke = GetNightData
5 Likes

You did not pass any arguments when calling the function

2 Likes

Remove the Parenthesis (), they are not needed and indicate that you are trying to call the function, instead of binding it to the RemoteFunction.

1 Like

When I do that, I get a different error, which is why I added them.

1 Like

What error are you getting?

In order to Add a Function to a RemoteFunction, you need to specify the function without parenthesis, adding them means that you are calling the function instead of assigning it into the RemoteFunction, if It returns a Function, It would work, otherwise it wont, but in this case, should work, any other error is likely from your function, or somewhere else entirely

1 Like

Let me run the script again, I’ll get back to you.

1 Like

21:45:37.976 ServerScriptService.DataHandler:92: attempt to index nil with ‘MaxNightUnlocked’ - Server - DataHandler:92

1 Like

then that has to do with your function returning a nil value, not the RemoteFunction, its working just fine.

1 Like

Well, I’m not sure how to make it not do that. Any suggestions?

1 Like

I did pass arguments, I passed “MaxNightUnlocked” It should also be passing the player variable.

If your RemoteFunction is invoked by the client prior to their data finishing loading, there will be no session data to access, which is the error you’re getting. Try adjusting your GetNightData function to this:

local function GetNightData(player, dataType)
	local playerData = sessionData[player.UserId]
	if dataType and playerData then
		local maxNightUnlocked = playerData[dataType]

		return maxNightUnlocked
	else
		warn("Player or DataType is invalid.")
		return nil
	end
end

There is also a chance a player could join the server before the script initializes, cause their data to never be loaded in the first place. That can be solved by having the script check for existing players when it first runs with this snippet placed just after your .PlayerAdded connection:

for _, player in ipairs(Players:GetPlayers()) do
	task.spawn(PlayerAdded, player)
end
1 Like

Thank you, @MysteriousVagabond. That was definitely the issue.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.