Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

How would I reverse this to restore multiple values?

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

1 comment

0

is there any error in the output?

2 answers

✓ Accepted answer

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

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");

1 comment

0

this is incorrect. a datastore can perfectly save tables without the need of serialization.

This discussion is preserved as it was. New answers, comments, and votes are closed.