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

Saving amount of items player has?

Asked by 5 years ago

This is my current invenotry saving/loading script

local inv = game:GetService("DataStoreService"):GetDataStore("inv_01")
game.Players.PlayerAdded:Connect(function(plr)
    local items = inv:GetAsync(plr.UserId) or {}
    local inventory = Instance.new("Folder",plr)
    inventory.Name = "Inventory"
    --Load items
    for i,v in pairs(items) do
        if game.ReplicatedStorage.Items:FindFirstChild(v) ~= nil then
            game.ReplicatedStorage.Items[v]:Clone().Parent = inventory
        end
    end
    --Save inventory when item added
    inventory.ChildAdded:Connect(function(c)
        items[#items+1] = c.Name
        inv:SetAsync(plr.UserId, items)
    end)
    --save inventory when item removed
    inventory.ChildRemoved:Connect(function(c)
        items = {}
        for i,v in pairs(inventory:GetChildren()) do
            items[i] = v.Name
        end
        inv:SetAsync(plr.UserId, items)
    end)

end)


Not asking for an entire script just a way.

0
What? Can you explain the error? yHasteeD 1819 — 5y
0
There is no error, but I need a kind of way to store the value of an item someone has. For example: Player1 has 21 Items. VeryDarkDev 47 — 5y
0
Let's say you want to leave in value a texture saved? yHasteeD 1819 — 5y
0
Not sure if I'm being clear enough but what I do mean is I want to save the quantity/amount of an item someone has VeryDarkDev 47 — 5y
View all comments (3 more)
0
Huum, this script not saving itens correct? if no i can post a script that save. yHasteeD 1819 — 5y
0
no the script itself saves items properly but I need to know how I can make it so it will save the ammount of that item the players have. Like I said before. So again for example when someone picks up an item they already have it would show "item x2" meaning they have 2 of item VeryDarkDev 47 — 5y
0
I'm looking for this too lol. i try to make this~ yHasteeD 1819 — 5y

2 answers

Log in to vote
0
Answered by
xEmmalyx 285 Moderation Voter
5 years ago
Edited 5 years ago

I worked on an inventory system not too long ago, I can think of 2 solutions for your problem

EDIT: I made a test place that has a basic item give shop and date store setup(Uncopylocked) Inventory Data Store Test Place

  1. Use the name of the item as the name to save Make it an IntValue and use the value as the number of the item

  2. The way I did it a while ago since I had multiple things to save for the item was placing values inside of the item and saving/loading those

Example for #2

This will save all the values into a table and then load them 1 by 1 into your inventory folder

It automatically saves every 300 seconds with a 30 second delay between players

I am not very good at coding so I'm sure there are more efficient ways but this is my way of doing it

local DSS = game:GetService("DataStoreService")
local set = "example1"
local invds = DSS:GetDataStore("inventory"..set)

game.Players.PlayerAdded:connect(function(player)

    local key = tostring(player.UserId..set)

    local inventory = Instance.new("Folder", player)
    inventory.Name = "inventory"

    if invds:GetAsync(key) ~= nil then
        local tablea1 = invds:GetAsync(key)
        for k,v in pairs(tablea1) do
            local itemname = Instance.new("StringValue",player.inventory)
            itemname.Name = v[1]
            local itemlevel = Instance.new("IntValue",itemname)
            itemlevel.Value = v[2]
            itemlevel.Name = "Level"
            local itemamount = Instance.new("IntValue",itemname)
            itemamount.Value = v[3]
            itemamount.Name = "Amount"
        end
    else
        local iddata = {}
        invds:SetAsync(key, iddata)
    end

end)

function SaveData(player)

    local key = tostring(player.UserId..set)

    invds:UpdateAsync(key, function(OldValue)
        if type(OldValue) == "table" then
            local tablea1 = {}
            for k,v in pairs(player.inventory:GetChildren()) do
                local tabledata = {v.Name, v["Level"].Value, v["Amount"].Value}
                table.insert(tablea1, tabledata)
            end
            OldValue = tablea1
        end
        return OldValue
    end)

end

game.Players.PlayerRemoving:Connect(SaveData)


while wait(300) do
    for k,v in pairs(game.Players:GetChildren()) do
        wait(30)
        SaveData(v)
    end
end

0
I'll test both methods and get back to you with the result of it VeryDarkDev 47 — 5y
0
if you encounter any errors just reply here or send me a message and I'll get back to you asap! xEmmalyx 285 — 5y
0
Alright so here's an error I got with the 2nd option while testing. Apparently Id is an "unknown global" not sure if this is because the above code may be a snippet from something else or I'm doing something wrong VeryDarkDev 47 — 5y
0
ah my mistake use the code now and it should be good, I forgot to change a variable xEmmalyx 285 — 5y
Ad
Log in to vote
0
Answered by 5 years ago
Edited 5 years ago

The short answer, with least modification to your existing system is to simply save a slightly more complex data struct. For example, instead of just saving the array of names, save a small table. So this:

items[i] = v.Name

Might become something like this:

items[i] = {
    name = itemName,
    quantity = quantityOfItem,
}

How you track the quantity of the item in memory on the server is another matter. I would recommend just using a dictionary keyed with the item name. Don't make multiple copies of the actual items, that is a huge waste of memory. In fact, cloning the items into the player's inventory folder is probably already wasteful. The items probably don't need to exist until you are ready to parent them to something in Workspace or ReplicatedStorage. It's probably best to do all of this inventory stuff just in a table, and only worry about instantiating the actual items when they need to be spawned in world or at least made available to clients.

A side note, you will find a lot of examples and many inventory systems that unpack datastore data into folders of value objects. This is mostly a legacy from the times before RemoteEvents, when this was a way to get values replicated to clients. This a horribly memory-inefficient way to store simple data, equally terrible for read/write performance--recursive search of hierarchical structure where a simple O(1) dictionary could be used--and no longer a good practice for sending data server-to-client. Use tables in server Scripts, and RemoteEvents to communicate values between server and clients.

Answer this question