How to put a table into datastore?

I am trying to make a shop for my game that has one time purchases in it. I use a table to hold all the items that the player has bought, but how do I save it? Is there a table value instead of an int or number value that will work for this? I tried using the JSON http thing but it did not work.

here are the scripts:
serverscriptservice serverside script

local DSS = game:GetService("DataStoreService")
local mainDS = DSS:GetDataStore("CoinsData")
local trailsDS = DSS:GetDataStore("TrailsData")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local events = ReplicatedStorage:FindFirstChild("Events")
local hs = game:GetService("HttpService")

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

	
	local leaderstats = Instance.new("Folder", player)
	leaderstats.Name = "leaderstats"
	
	local coins = Instance.new("IntValue", leaderstats)
	coins.Name = "Coins"
	
	local trails = Instance.new("StringValue", player)
	trails.Name = "Trails"
	
	local data = mainDS:GetAsync(player.UserId)
	local trailsData = trailsDS:GetAsync(player.UserId)
	if data then
		if data[1] then 
			coins.Value = data[1]
		end
	end
	if trailsData then
		if data[1] then
			trails.Value = data[1]
		end
	end
end)

game.Players.PlayerRemoving:Connect(function(player)
	local leaderstats = player:WaitForChild("leaderstats")
	local coins = leaderstats:WaitForChild("Coins")
	local trails = player:WaitForChild("Trails")
	mainDS:SetAsync(player.UserId, {coins.Value})
	trailsDS:SetAsync(player.UserId, {trails.Value})
end)

game.ReplicatedStorage.BuyTrail.OnServerEvent:Connect(function(player, Price, OwnedTrails)
	print(Price)
	print(player)
	player.leaderstats.Coins.Value -= Price
--I need to set player.Trails.Value to OwnedTrails but it wont work
end)

StarterGui descendant Local Script
image

local frame = script.Parent
local HealTrail = frame.HealTrail
local JumpTrail = frame.JumpTrail
local RainbowTrail = frame.RainbowTrail
local SpeedTrail = frame.SpeedTrail
local player = game.Players.LocalPlayer
local OwnedTrails = {player.Trails.Value}


local TrailCosts = {
    HealTrail = 100,
    JumpTrail = 200,
    RainbowTrail = 300,
    SpeedTrail = 400
}
local function Buy(Trail)
    if table.find(OwnedTrails, Trail) then return end -- already owned
    local Cost = TrailCosts[Trail]
	if not Cost then return end -- invalid trail name
	if player.leaderstats.Coins.Value < Cost then return end -- insufficient funds
	game.ReplicatedStorage.BuyTrail:FireServer(Cost, OwnedTrails)
	print("Bought")
	table.insert(OwnedTrails, Trail)
--somehow I need to set player.Trails.Value to owned Tables...
end


HealTrail.MouseButton1Click:Connect(function()
    Buy("HealTrail")
end)
JumpTrail.MouseButton1Click:Connect(function()
    Buy("JumpTrail")
end)
RainbowTrail.MouseButton1Click:Connect(function()
    Buy("RainbowTrail")
end)
SpeedTrail.MouseButton1Click:Connect(function()
    Buy("SpeedTrail")
end)
1 Like

I am pretty sure that you can just save a table “directly”. For example:

YourDatastore:SetAsync(player.UserId, YourTableName)

Also, you should put the :GetAsync and :SetAsync lines in a pcall like this.

local success, errormsg = pcall(function()
			YourDataStore:GetAsync(player.UserId)
end)
	if success then
		--do stuff with the data
	else
		warn("Error while saving data. Error: "..errormsg)
	end

I use HTTPService:JSONEncode() for table storing, but I usually take it a step further by serializing it into numbers and dashes since it reduced data size a ton. You don’t have to do that, though.

Warning: using JSONEncode/decode means that working with the data via Cloud APIs will be difficult as all the objects will be encoded! Much easier to just store the table directly and then you can access/manipulate directly with JSON via Cloud APIs.