How to send over models from Server to client?

I want to make a script that takes a player inventory and essentially turns it into a table using strings(model names) Example bellow
image
into this
image
If there are better inventory sorting methods out there that store a lot of values in other values please let me know I’m just trying to come up with ideas on my own at the moment

Edit -
Forgot to say that the inventory system is in ServerStorage to hide it from explotation

1 Like

I haven’t tested this, but it should work.

local folder = -- Path to your folder
local t = {} -- The table

local function insertChildren(inst,tab)
    for _, c in inst:GetChildren() do
        tab[c.Name .. " - " .. c.Value] = {} -- c should be a StringValue as it will hold it's type (Like "Sight - Attachment")
        if #c:GetChildren() > 0 then
            insertChildren(c,tab[c.Name])
        end
    end
end

insertChildren(folder,t)

I’d normally do pretty much OOP to set that up
there’d be a table that stores “items” and each item would have a different class like M4A1 or something more generic like Gun
each class would have a hardcoded schema/fileset to search for, so you’d specifically check for Magazine and store the value of the magazine inside the object


but if you want an unstructured setup similar to yours that converts the instances to a table, I’d have something like this

inventory = {}

storeItem(item)
   itemData = {}
   addField(item, itemData)
   table.insert(inventory, itemData) -- using table.insert in case you have similar items like 2 M4A1s

addField(child, parent)
   fieldData = { child.Value, {} } --[1] is the value assuming it's scalar like "M4A1" or 30; and [2] is for any nested fields like isArmorPiercing
   parent[child.Name] = fieldData --the index in parent is the fieldname, like "name" or "color" or "isArmorPiercing"
   for each child in child
      addField(child, fieldData)

-- example usage
storeItem(game.ServerStorage["On Sling"].M4A1)

and then I’d also store the instances a bit cleaner like

Assault Rifle - a StringValue representing an assault rifle  - name=Assault Rifle, value=M4A1
   Extra - a CFrameValue representing where gun attachments are attached - value=some object CFrame
   Grip - a CFrameValue representing where users' hands attach to - value=some object CFrame
   Magazine - an IntValue representing how much ammo is left - value=the ammo left
      Bullet Type - anything because this is an array and it isnt a scalar value - value=anything
         Armor Piercing - a BoolValue representing if the bullets are armor piercing - value=boolean
         Drop Rate - a NumberValue representing maybe the number of studs a bullet drops by per second of airtime - value=some number like 1

this would result in a table like

inventory = {
   [1] = {
      ["Assault Rifle"] = {
         "M4A1",
         {
            Extra = { CFrame.new(...), {} },
            Grip = { CFrame.new(...), {} },
            Magazine = {
               30,
               {
                  ["Bullet Type"] = {
                     null,
                     {
                        ["Armor Piercing"] = { true, {} },
                        ["Drop Rate"] = { 1, {} }
                     }
                  }
               }
            }
         }
      }
   }
}

you could add a bit more to remove the redundant data and turn {1, {}} to just 1 also


Also note that I prefer doing it with OOP because you’d have less redundancy from not needing to store Grip, Extra, Armor Piercing, Drop Rate for each M4A1. That data that’s shared between each is stored separately only once
I would also strictly use in-code inventory systems and not use Value instances like StringValue and IntValue at all by just storing the table and working directly with it

I don’t see any use case where this method would make sense. If you want to send models from server to client, just copy the Gun and move it to Replicated Storage, then let the client know, “Hey! Your gun is in replicated storage!” And then let the client take it out of there.

1 Like

Yes, this is actually a pretty good idea.

gun.Parent = game.ReplicatedStorage
RE:FireClient(plr)
gun.Parent = game.ServerStorage

Make it a RemoteFunction that the client needs to answer first, this prevents the gun from getting removed before the client could get it.

Doesn’t ReplicatedStorage replicate for all players? The assets that I use are actually rather big (entire cars) and sending it to ReplicatedStorage might lag everyone in the server. Why should the rest receive the asset for nothing?

I only want to send models to the users that require a specific model and I can’t find a way to do that. I’ve tried to insert models directly into a viewport in playerGUI from server but that hasn’t worked. Remote functions/events don’t send models at all.

I think parenting the model to workspace in an obscure position is better? Since the client is not going to “load” it until the player gets close. Am I correct on this? Or does ReplicatedStorage not have the downside I’m imagining…