How would I save a player's purchases to DataStore?

Viewed 53

So I'm working on a game with my friend and we have these game upgrades that unlock new stuff, but I'm wondering how I could save them?

My purchase module is set up like this:

local module = {}

local Upgrades = {
    { id = "idForThing", cash = 20, callback = function(player) 
        -- hi!
    end, unlimitedPurchases = true, purchased = false }
}

module.getUpgrade = function(upgradeID)
    for i, upg in pairs(Upgrades) do
        if upg.id == upgradeID then
            return upg
        else
            continue
        end
    end
    return nil
end

module.getUpgrades = function()
    return Upgrades
end

module.purchaseUpgrade = function(player, upgradeID)
    for i, upg in pairs(Upgrades) do
        if upg.id == upgradeID then
            if upg.purchased then
                SFX.Error:Play()
                break
            end
            if game:GetService("ServerStorage").Cash.Value >= upg.cash then
                game:GetService("ServerStorage").Cash.Value -= upg.cash
                upg.purchased = not upg.unlimitedPurchases
                upg.callback(player)
                SFX.Purchased:Play()
            else
                SFX.Error:Play()
            end
            break
        else
            continue
        end
    end
end

return module

So, basically in the Upgrades table it has items that contain 5 values.

  • id

The item ID

  • cash

The amount it costs

  • callback

Code that runs when purchased

  • unlimitedPurchases

If it's true, you can purchase said item more than once

  • purchased

Changes to true when the player purchases the item.

I made module.getUpgrades in hopes that I could just copy the Upgrades table to the DataStore but then it'd also copy the cash which I don't want. I just want it to copy the id and purchased value. So how would I copy just the id and purchased value?

2 Answers

You can remove keys from a table by setting them to nil table[key] = nil (or table.remove if you have an array). However there is another catch here that lua tables are passed by reference, so we don't want to remove from the returned value from getUpgrades as it'll remove it from the Upgrades table as well.

Presuming your DataStore has some function insert(...) which takes a table and puts it into the datastore; instead what we can do is make a new table with only the keys we want, like:

local upgrades = module.getUpgrades(id)
local insert_tbl = { id = upgrades.id, purchased = upgrades.purchased }
DataStore.insert(insert_tbl)

You can return the id value and purchased value like this.

-- for returning single upgrade
module.getUpgrade = function(upgradeID)
    for i, upg in pairs(Upgrades) do
        if upg.id == upgradeID then
            return {id = upg.id, purchased = upg.purchased}
        else
            continue
        end
    end
    return nil
end
-- for multiple upgrades just loop through the table
module.getUpgrades = function()
    res = {}
    for i, v in pairs(Upgrades)do
       table.insert(res,{id = v.id, purchased = v.purchased})
    end
    return res
end

If you know what you are doing, you can ignore the rest of my answer.

You need to call the moduleName.getUpgrades() for saving.

local moduleName = require("YourModuleName")

-- To save, just call the function inside the setAsync
PlayerSavesU:SetAsync(player.UserId, moduleName.getUpgrades())

-- To use the retrieved data from GetAsync();
local data = PlayerSavesU:GetAsync(player.UserId);
if(data ~= nil) then
    for i,v in pairs(data) do
        print(v.id, v.purchased)
    end
end

Although, this code might work. It is still not very useful because it does not know which player purchased the items. So you need to add a way to identify each player.

Related