Help saving table in datastore

So I’ve been optimizing my game, and I’m trying to store one dictionary in a datastore instead of using several datastores to save the player’s data with the following script. I’m currently testing with an unreleased feature to avoid breaking player data, so that is why cash isn’t saved in a table.

local dataStores = game:GetService("DataStoreService")
local playerData = dataStores:GetDataStore("playerData")
local StarterGui = game:GetService("StarterGui")
local MarketplaceService = game:GetService("MarketplaceService")
local tableData = dataStores:GetDataStore("plrData")

game.ReplicatedStorage.giveCash.OnServerEvent:Connect(function(player, cash)
	player.leaderstats.Cash.Value += cash
end)

game.ReplicatedStorage.Events.Start.OnServerEvent:Connect(function(player)
	for i, v in pairs(workspace.Bases:GetChildren()) do
		if v.Owner.Value == nil then
			player.Character.HumanoidRootPart.Position = v.Spawn.Position
			player.data.plot.Value = v
		end
	end
	if player.data.plot.Value == nil then
		player.data.isJudge = true
		player.Character.HumanoidRootPart.Position = workspace.judgeArea.Spawn.Position
	end
	workspace:SetAttribute("gameInProgress", true)
end)

game.Players.PlayerAdded:Connect(function(player)
	local leaderstats = Instance.new("Folder", player)
	leaderstats.Name = "leaderstats"
	local Cash = Instance.new("IntValue", leaderstats)
	Cash.Name = "Cash"
	Cash.Parent = leaderstats
	Cash.Value = playerData:GetAsync("Player_" .. player.UserId)
	workspace.playerCount.Value += 1
	local data = Instance.new("Folder", player)
	data.Name = "data"
	local plot = Instance.new("ObjectValue", data)
	plot.Name = "plot"
	local isJudge = Instance.new("BoolValue", data)
	isJudge.Name = "isJudge"
	local membershipTime = Instance.new("StringValue", data)
	membershipTime.Name = "membershipTime"
	local datastoredata = player.UserId or "no data"
	print(datastoredata)
	local membership = datastoredata[1]
	membershipTime.Value = membership or "not member"
end)

game.Players.PlayerRemoving:Connect(function(player)
	local success, err = pcall(function()
		local cash = player.leaderstats.Cash.Value
		playerData:SetAsync("Player_" .. player.UserId, cash)
	end)
	if success then
		print("Saved " .. player.leaderstats.Cash.Value)
	elseif err then
		error(err)
	end 
	local data = {
		isMember = player.data.membershipTime
	}
	tableData:SetAsync(player.UserId, data)
	workspace.playerCount.Value -= 1
end)

local Players = game:GetService('Players')
local ServerScriptService = game:GetService('ServerScriptService')

local ChatService = require(ServerScriptService:WaitForChild('ChatServiceRunner'):WaitForChild('ChatService'))

ChatService.SpeakerAdded:Connect(function(PlayerName)
	local Speaker = ChatService:GetSpeaker(PlayerName)
	Speaker:SetExtraData('NameColor', Color3.fromRGB(209, 193, 97))
	Speaker:SetExtraData('ChatColor', Color3.fromRGB(178, 248, 229))
	Speaker:SetExtraData('Tags', {{TagText = 'Beta Tester', TagColor = Color3.fromRGB(189, 83, 83)}})
end)

game:BindToClose(function()
	if game["Run Service"].IsStudio then
		wait(3)
	end
end)

However, when I save the data, it errors

and if i’m not mistaken, they automatically run JSONEncode and Decode. And I have tried running the JSON myself, but that returns null

	local data = {
		isMember = player.data.membershipTime
	}
	tableData:SetAsync(player.UserId, data)

I have a question: What exacly is player.data.membershipTime? An object? Perhaps you wanted to save here player.data.membershipTime.Value and you forgot to add “.Value”?

You were right, however now it is just saving nothing. When it loads, it loads an empty string

EDIT: wait nvm i accidentally deleted part of the script thats why lol

Your own error message is giving you the answer. You cannot save a dictionary.
You would be able to save an array but a dictionary is different.

This is why I don’t touch dictionaries and always convert anything I’m saving to string regardless of what it is.

I tried arrays but it still errored

What errored when you ran it as an array?

The issue atm is you got one error covering up another so it kind of hard to tell with the way this script is.

it errored the same thing but instead of dictionary it said array. I figured it out now though, thanks!

This error message is incorrect, has been for a long time.

You CAN save dictionaries to DataStores. This error message is for when data can’t be serialized, aka you have a Color3, Vector3, CFrame or something else in there.

It’s just a question of following some basic limitations.

  • Only allows for booleans, numbers, strings, or other JSON strings.

  • You cannot have mixed tables. A JSON string can only be either an array or a dictionary. (You can’t save a table with userIDs as indexes for instance.)

  • Dictionaries can only have a string as their key.

Well red text don’t lie, if it is incorrect then perhaps the script is on a different version of studio.

personally I don’t trust all the new things where datastores save arrays as I think it just misses the core point of what a datastore was designed to save which is string. I translate everything to string myself.

either way its red and don’t work, it would be worth just translating it all into text and saving it that way

Yeah um, datastores will only save strings internally, I don’t recommend using :JSONEncode() yourself because it makes it hard to mess with on DataStore editors and stuff, and it’s hard to convert properly later. DataStores will decode the data for you in the correct form without you having to do anything.

Also I don’t know what you’re talking about with them “it saves data with arrays internally”? I’ve never heard any of that.