Good day all,
The Problem
I have a “Player Manager (client)” script placed in ReplicatedFirst which performs some basic functionality immediately after a player joins the game, namely moving the custom “Loading Menu” into the player’s PlayerGui.
This is where things become slightly more convoluted. The Player Manager (Client) script receives the Loading Menu from another script on the server side, called “Asset Manager”. The Asset Manager’s job is to take incoming asset requests (all assets are stored in ServerStorage.Assets) and return a clone of the requested asset by way of a RemoteFunction.
In this case, the Player Manager (Client) script is attempting to request the Loading Menu by firing a RemoteFunction. Most of the time it works, however, approximately 1-in-3 times this will, at random, not work and I will get an “attempting to index nil value” error.
What I Know So Far
When the error occurs:
• The Asset Manager script does not detect the :InvokeServer().
• The server has just started.
• It can occur even after a 10-second wait() period.
The issue may be:
• The Asset Manager script has not loaded by this point. (I’ve tested this and it does connect the events before the error appears)
Player Manager (Client)
-- << VARIABLES >> --
local Players = game:GetService("Players")
local ReplicatedFirst = game:GetService("ReplicatedFirst")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
local RemoteFunction = ReplicatedStorage:WaitForChild("Remote Instances", 10):WaitForChild("Remote Function", 10)
local Studio = game.CreatorId == 0
local Player = Players.LocalPlayer
-- << FUNCTIONS >> --
function LoadGame ()
-- fetch loading menu
local LoadingMenu = RemoteFunction:InvokeServer ("Fetch Asset", "Loading Menu")
-- display loading menu
LoadingMenu.Parent = Player.PlayerGui
-- remove loading screen
ReplicatedFirst:RemoveDefaultLoadingScreen()
end
-- << EXECUTION >> --
LoadGame ()
Asset Manager
-- << VARIABLES >> --
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local ServerStorage = game:GetService("ServerStorage")
local BindableEvent = ServerStorage["Bindable Instances"]["Bindable Event"]
local BindableFunction = ServerStorage["Bindable Instances"]["Bindable Function"]
local RemoteFunction = ReplicatedStorage["Remote Instances"]["Remote Function"]
local Assets = ServerStorage["Assets"]
-- << FUNCTIONS >> --
function SearchForAsset (Player, Function, Asset)
-- verify request is relevant
if Function == "Fetch Asset" then
-- search for asset
if Assets["User Interfaces"]:FindFirstChild(Asset) then
-- fetch asset
local Asset = Assets["User Interfaces"]:WaitForChild(Asset, 5)
return FetchAsset (Asset)
else
-- report non-existent asset
BindableEvent:Fire ("Report Error", "Asset '".. Asset .."' doesn't exist. Error Location: ".. script:GetFullName())
end
end
end
function FetchAsset (Asset)
-- create cloned asset
local Asset = Asset:Clone()
Asset.Parent = ReplicatedStorage.Assets
-- send cloned asset
return Asset
end
-- << EXECUTION >> --
BindableFunction.OnInvoke = SearchForAsset
RemoteFunction.OnServerInvoke = SearchForAsset