This code is trying to attempt to grab a player’s inventory based with the given player argument. It fires a remote event to get the inventory, then the other script fires it back and gives the table. Right now though, the script that’s using it is printing nil. Why is this?
Module
local TheValleyFunctions = {}
function TheValleyFunctions.GetInventory(Player)
game.ReplicatedStorage.Inventory.MapInventory:FireServer(Player)
game.ReplicatedStorage.Inventory.MapInventory.OnClientEvent:Connect(function(Inventory)
return Inventory
end)
end
return TheValleyFunctions
Script it’s used in
...
local function Map()
local GetInventory = TheValleyFunctions.GetInventory(game.Players.LocalPlayer)
local CurrentItem
local CurrentAmount
local SlotNum
print(GetInventory)
...
As far as I’m aware, the issues arise from the fact Return will get whatever inventory is and return it within the OnClientEvent function, meaning nothing is truly returned to the GetInventory function. You might be able to fix it with this, but I foresee issues with timing which may be your next problem.
function TheValleyFunctions.GetInventory(Player)
game.ReplicatedStorage.Inventory.MapInventory:FireServer(Player)
local Inventory
game.ReplicatedStorage.Inventory.MapInventory.OnClientEvent:Connect(function(fetchedInventory)
Inventory = fetchedInventory
end)
return Inventory`
end
If this doesn’t work, which I’m not sure if it will, you could also try directly returning the event?
Yeah, you can try returning the entire event like that, however that’d still be a bit iffy. I believe the main problem is the fact that this function acts like a wrapper; you may be able to avoid this all together with a bit of refactoring.
There is indeed a timing issue. It returns Inventory before the remote event gets back to the module. I tried fixing it with this:
function TheValleyFunctions.GetInventory(Player)
game.ReplicatedStorage.Inventory.MapInventory:FireServer(Player)
local Inventory
repeat task.wait() until game.ReplicatedStorage.Inventory.MapInventory.OnClientEvent:Connect(function(FetchedInventory)
print("This happens")
Inventory = FetchedInventory
end)
return Inventory
end
But to no avail.
This also just gave the other script something called “Connection”
function TheValleyFunctions.GetInventory(Player)
game.ReplicatedStorage.Inventory.MapInventory:FireServer(Player)
local Inventory
local DB = false
game.ReplicatedStorage.Inventory.MapInventory.OnClientEvent:Connect(function(FetchedInventory)
DB = true
print("This happens")
Inventory = FetchedInventory
end)
repeat task.wait() until DB ~= false
return Inventory
end
what I did was make a loop until the client fired, when the event fires, the DB variable change to true, which ll make the loop stop and return the inventory, so yes
You could also use RemoteEvent.OnClientEvent:Wait() instead of a repeat loop since this is a local call. :Wait() will return any values given on the next event call. So instead, you could write the code like this:
function TheValleyFunctions.GetInventory(Player)
game.ReplicatedStorage.Inventory.MapInventory:FireServer(Player)
return game.ReplicatedStorage.Inventory.MapInventory.OnClientEvent:Wait()
end
Also, you could use RemoteFunctions instead of a RemoteEvent for this sort of thing, since you’re calling a RemoteEvent to the server to then send you back data; something that a RemoteFunction handles pretty easily.
local MapInventory = game.ReplicatedStorage.Inventory.MapInventory
-- Server script
MapInventory.OnServerInvoke = function(player: Player, ...)
print(...)
local Inventory = nil
-- Code to get your inventory
return Inventory
end
-- LocalScript
local Inventory = MapInventory:InvokeServer("Whatever you would put here")
print(Inventory)
RemoteFunctions also must always return something, otherwise the script calling the RemoteFunction will hang/not continue forward unless in a coroutine/new thread or the function is entirely ran.