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

How would I reverse this to restore multiple values?

Asked by 4 years ago

Hi, I've lately started practising with DataStores; I've been aiming to try and save multiple values at once. So far this has worked; I've now encountered the issue of essential reverse engineering the method in an attempt to re-call the values when loading.

Below is the method of saving, but as I said I'm struggling to reverse this.

Does anybody have any suggestions?

    function System.DataSave(Player)

        local PlayerData = Player:WaitForChild('PlayerData')
        local Saves = {}

        Saves.isPlaying = PlayerData.isPlaying.Value

        local configs = {"CharacterData", "StarShipData", "Unlocked"}
        for _, config_name in pairs(configs) do
            local config = PlayerData[config_name]
            Saves[config_name] = {}

            for _, ValueObject in pairs(config:GetDescendants()) do
                Saves[config_name][ValueObject.Name] = ValueObject.Value
            end
        end

        DS1:SetAsync(Player.UserId, Saves)

    end
0
is there any error in the output? speedyfox66 237 — 4y

2 answers

Log in to vote
0
Answered by
megukoo 877 Moderation Voter
4 years ago

I'm assuming your asking how to "retrieve" your values that you've saved, assuming you've said you want to "restore" these values to their ObjectValue form.

First, you'll want to have a function that can get the data of a player.

function System.LoadData(player)
    local key = player.UserId

end

Next, you'll want to use the method :GetAsync() to retrieve the values stored with that key.

function System.LoadData(player)
    local key = player.UserId
    local playerData = DS1:GetAsync(key) -- retrieve their saved data


end

You'll most likely want to check if that data exists, so you can apply default data settings if you wish to. I'll leave that section up to you however.

function System.LoadData(player)
    local key = player.UserId
    local playerData = DS1:GetAsync(key)

    if playerData then
        -- load and create things like leaderstats here

        return playerData -- return the player data if you want
    else
        -- player has no data, what will you do?
        -- perhaps create the default save
    end
end

This is an example where you'd be able to create ObjectValues from saved data following your method of doing things.

function System.LoadData(player)
    local key = player.UserId
    local playerData = DS1:GetAsync(key)

    if playerData then
        local data = Instance.new("Folder")
        data.Name = "PlayerData"

        local coins = Instance.new("NumberValue")
        coins.Value = playerData.Coins -- sets the value of tangible data to what has been saved
        data.Parent = player
        coins.Parent = data
        return playerData
    else
        -- player has no data, what will you do?
        -- perhaps create the default save
    end
end
Ad
Log in to vote
0
Answered by 4 years ago
Edited 4 years ago

well first up, Datastore won't save an array or an object, it will cause an error..

so before you save either an array or table, you must turn it into a string, or somehow into binary numbers...

you can use the JSONEncode() and JSONDecode() methods of HTTPService to turn arrays and objects into a JSON like string..

so when you do:

local HTTPService = game:GetService("HTTPService")
local data = {
    coins = 20,
    wins = 40,
    swords = {"Katana", "Blackstar", "etc"}
}

local stringified = HTTPService:JSONEncode(data);
print(stringified) -->{ "coins"=20,  "wins"=40,  "swords"=["Katana", "Blackstar", "etc"] };

local back_to_lua_object = HTTPService:JSONDecode(stringified) -- back to the object that was encoded

you can store the stringified JSON string in Datastore,

also i recommend that you make a ModuleScript that handles datastore, this way so everything remains abstract...

like this:

local DatstoreService = game:GetService("DatastoreService")
local DS = {};

function DS.initiate(player)
    local datastore = DatstoreService :GetDataStore(game_ds_key, player.UserId)
    return {
        function get_data(key)
            return datastore:GetAsync(key)
        end,

        function set_data(key, value)
            datastore:SetAsync(key, value)
        end,

        function update_data(key, new_value)
            datastore:UpdateAsync(key, function(old_value)
                return new_value
            end)
        end,

        function delete_data(key)
            datastore:RemoveAsync(key);
        end
    }
end

return DS;

so you can just to:

local ds= require(the_datastore_module_script_directory).initiate(player);
ds.set_data("some_name_of_data", stringified);
ds.get_data("some_name_of_data");
0
this is incorrect. a datastore can perfectly save tables without the need of serialization. megukoo 877 — 4y

Answer this question