DataStores - How do I save multiple tables by JSON encoding?

I found this thread which is very helpful (Is it possible to create a Table and save/Load it?).

Can JSON encoding/decoding only save/open 1 table or is there a way to do multiple ones? Any tips?

Thanks!

JSON encoding/decoding the data is redundant because roblox will need to encode the table into a JSON string to be able to transfer it to their external database and when receiving the data, roblox parses it back into a lua table from the json string. But to answer your question, JSONEncode and JSONDecode can only accept 1 argument, which is a single table, however that table can contain many various tables.

When dealing with multiple data to be stored in a single datastore, you will need to think of an appropriate structure. Say you have in-game currency and an inventory system which holds tools which is operated based on a folder containing string values with the names of the tools. You can use a singular dictionary where the currency has its own index and value in the that dictionary and the inventory is an array in that dictionary that contains will contain strings. One important to keep in mind is that datastores cannot save instances, or any other non-UTF-8 character, so the idea is to serialise the data by saving the tools’ names in the player’s inventory as strings in the array. For the in-game currency, there is no need for serialisation since numbers can be saved.

Example table for saving:

local Data = {
    Credits = 25;
    Inventory = {
        "Tool1";
        "Tool2";
        "Tool3";
    }
}

DataStore:SetAsync(player.UserId, Data)

When it comes time to load the inventory, you will need to deserialise the saved data: the reverse of serialisation. You need to reconstruct the string values in the folder with the names saved as strings by iterating over the table. Loading the in-game currency is easy as it’s just a single value:

Example of loading the saved data:

local Data = DataStore:GetAsync(player.UserId)

player.Credits.Value = Data.Credits

for _, toolName in ipairs(Data.Inventory) do
    local stringVal = Instance.new("StringValue")
    stringVal.Name = toolName
    stringVal.Parent = player.Inventory
end
2 Likes

Thanks for elaborating on this! At first, I didn’t know it could be done with multiple tables inside of another one, but this helps a bunch.

Going to work on this and keep the topic updated incase I run into an issue.

Continuing on this topic; so I put tables in as subtables and it seems that it’s registering them well. However, as an example, in one table, I used strings instead of integers. When converting it to JSON, it does print it, but strings aren’t encoded; they’re still shown as “”.

Print:

Test code:

local DataStoreService = game:GetService("DataStoreService")
HttpService = game:GetService("HttpService")

local accessories = {
	["BackAccessory"] = {"1"};
	["FaceAccessory"] = {"2"};
	["FrontAccessory"] = {"3"};
	["HairAccessory"] = {"4"};
	["HatAccessory"] = {"5"};
	["NeckAccessory"] = {"6"};
	["ShouldersAccessory"] = {"7"};
	["WaistAccessory"] = {"8"};
}
local clothes = {
	["Shirt"] = {11};
	["Pants"] = {22};
	["GraphicTShirt"] = {33};
}
local colors = {
	["HeadColor"] = 16;
	["LeftArmColor"] = 16;
	["LeftLegColor"] = 16;
	["RightArmColor"] = 16;
	["RightLegColor"] = 16;
	["TorsoColor"] = 0
}
local facialassets = {
	["FullFace"] = 265;
	["Blush"] = 865;
	["Eyebrows"] = 97;
	["Eyeliner"] = 215;
	["Eyes"] = 25;
	["Lips"] = 1
}
--assign it into tables

--encode data
local data = {accessories,clothes,colors,facialassets}
print(data)
local dataEncoded = HttpService:JSONEncode(data)
print(dataEncoded)
local data = HttpService:JSONDecode(dataEncoded)
print(data)