Save function gives error?

Here is my save function:

local function save(plr)
	local cash = plr.leaderstats.Cash.Value
	local equippedPet = functions.GetEquippedPets(plr)
	local ownedPets = functions.GetOwnedPets(plr)
	local rpName = {plr.Data.RpName.Text.Value, plr.Data.RpName.Font.Value, plr.Data.RpName.Color.Value}
	
	local toSave = {cash, equippedPet,ownedPets, rpName}
	datastore:SetAsync("user_-" .. plr.UserId, toSave)
end

Here is the error I get:
104: Cannot store Array in data store. Data stores can only accept valid UTF-8 characters.

1 Like

Data stores cannot accept dictionaries as values to save. To circumvent this, you can convert the dictionary to a JSON string and then decode it back to a dictionary to read from it.

To encode:

local toSave_Str = game:GetService("HttpService"):JSONEncode(toSave)
datastore:SetAsync("user_-" .. plr.UserId, toSave_Str)

And to decode:

local data_Str = datastore:GetAsync("user_-" .. plr.UserId)
local data = game:GetService("HttpService"):JSONDecode(data_Str)

Also, be sure to utilize Google before asking questions here.

Is there room for improvement with this code?

local function load(plr)
	local data
	if datastore:GetAsync("user_-" .. plr.UserId) == nil then
		data = {200, 0, {1}, {plr.Name, "Gotham", Color3.fromRGB(255, 255, 255)}}
	else
		local data_Str = datastore:GetAsync("user_-" .. plr.UserId)
		data = game:GetService("HttpService"):JSONDecode(data_Str)
	end
	return data
end

I don’t believe that you can encode any values that aren’t base lua types such as Color3. In this instance I’d change the Color3 to a table so that you have data.color = {255,255,255}. Then, convert this back to a Color3 upon load.

Also, I’d create this data as a dictionary rather than a table as values would be easier to keep track of and to index. For example:

data = {
    cash = 200,
    equippedPet = 0,
    ownedPets = { 1 },
    rpName = {
        name = plr.Name,
        font = "Gotham",
        color = {r = 255, g = 255, b = 255}
    }
}

Then, you can index this data via “data.cash” or “data.rpName.color.g” or whatever you need. In my experience, this is easier to keep track of and usually looks cleaner. It is still valid to encode with JSON as well.

This is my suggestion, and you don’t have to follow it. I believe these steps will make scripting your game easier, however.

For future reference, you can post already-working code for review in Code Review.