Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

Why am I not able to pass a dictionary through RemoteFunction?

Asked by 5 years ago
Edited 5 years ago

According to this Devforum post and this ScriptingHelpers answer, I should be able to pass in a dictionary so long as it is only a dictionary not mixed with an array. I can still pair an array with a dictionary key though. However, when I call my RemoteFunction to get a table of inventory items generated by the server, all the tables are empty.

Server Code:

``` ReplicatedStorage = game.ReplicatedStorage PlayerStorageEvents = ReplicatedStorage.PlayerStorageEvents ServerStorage = game.ServerStorage

PlayerStorageEvents.GetInventory.OnServerInvoke = function(player) --Generate the dictionary that will be sent back local storage = { ["Inventory"] = {}, ["Equipment"] = {}, ["ActiveItems"] = {} }

--Get the player's storage
local playerStorage = ServerStorage.PlayerStorage:FindFirstChild(player.Name)

--Populate the table with all the elements in these folders
if playerStorage ~= nil then
    for i,v in pairs(playerStorage.Equipment:GetChildren()) do
        storage["Equipment"][i] = v
    end

    for i,v in pairs(playerStorage.ActiveItems:GetChildren()) do
        storage["ActiveItems"][i] = v
    end

    for i,v in pairs(playerStorage.Inventory:GetChildren()) do
        storage["Inventory"][i] = v
    end
end

return storage

end ```

Yet all these commands: print(#game.ReplicatedStorage.PlayerStorageEvents.GetInventory:InvokeServer()) print(#game.ReplicatedStorage.PlayerStorageEvents.GetInventory:InvokeServer()["Inventory"]) return 0 and all these commands: print(game.ReplicatedStorage.PlayerStorageEvents.GetInventory:InvokeServer()["Inventory"][0]) return nil

1 answer

Log in to vote
1
Answered by 5 years ago
Edited 5 years ago

Unfortunately, because the client has no access to ServerStorage, if the server returns instances that are in there, the client will treat that as nil.

However, there is a workaround. You can try using a table as the storage itself. Here's how it works:

  1. Declare a variable, which will be a table value (or dictionary), as the central inventory storage for all players.
  2. The key (index) to access the values of the table will be the player (object). The value will be similar to the storage variable you declared in line 7. ```lua -- Example. This adds a storage entry to the central storage for use later. local Players = game:GetService("Players") local CentralStorage = {}

Players.PlayerAdded:Connect(function(player) CentralStorage[player] = { -- player could be any Player. ["Inventory"] = {}, ["Equipment"] = {}, ["ActiveItems"] = {} } end ``` 3. To get the inventory of a player, simply return CentralStorage[player], where the player will be the one that is passed as the first argument/parameter as a result of RemoteFunction being invoked. 4. Since we are using a dictionary, the way we insert the items into this storage will be different. We will use the table.insert() method to add the new items into the right part(s) of the storage.

Here is the code to get a player's inventory. ```lua ReplicatedStorage = game.ReplicatedStorage PlayerStorageEvents = ReplicatedStorage.PlayerStorageEvents ServerStorage = game.ServerStorage

local CentralStorage = {} -- Since I do not know what and when the items will be inserted, I will leave this blank for now. -- Use table.insert(CentralStorage[player][section], item) to add items.

PlayerStorageEvents.GetInventory.OnServerInvoke = function(player) return CentralStorage[player] -- Simply return the dictionary returned using the player as the index. end ``` I hope this method will work. Remember, you need to change how the items will be inserted if you are ever going to use this. If you have any more problems, feel free to make a comment below. Thanks.

Ad

Answer this question