DataStore failing to save

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? I want my DataStore to save and not fail to save

  2. What is the issue?

local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("AvatarData")
local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Data = {
	Face = 0;
	Shirt = 0;
	Pant = 0;
	Hat = 0;
	Torso = {5, 105, 174};
	Arms = {245, 206, 44};
	Head = {245, 206, 44};
	Legs = {165, 190, 69}
}


local playersavetable = {};

local function loadStarterData(Player)
		local CharData = Instance.new("Folder")
		CharData.Name = "AvatarConf"
		CharData.Parent = Player
		for statname, statvalue in pairs(Data) do
			if type(statvalue) == 'number' then
			local intvalue = Instance.new("IntValue")
			intvalue.Name = statname
			intvalue.Value = statvalue
			intvalue.Parent = CharData
			else
			local colorvalue = Instance.new("Color3Value")
			colorvalue.Name = statname
			colorvalue.Value = Color3.fromRGB(statvalue[1],statvalue[2],statvalue[3])
			colorvalue.Parent = CharData
		end
	end
end

local function loadData(player)
	local Data
	local s, e = pcall(function()
	Data = DataStore:GetAsync('UserId'..player.UserId)
	end)
	
	if s then 
		print (player.Name.."Data loaded")
	else
		print(player.Name.."Data failed to load")
	end
	
	if Data then
		for statname, statvalue in pairs(Data) do
			player.stats[statname].Value = statvalue
		end
		print(player.Name.."Data has been loaded")
	else
		print(player.Name.."No data found! generating..")
		end
	end

local function saveData(player)
	--if RunService:IsStudio() then return end
	local Data = {}
	for _, stat in pairs(player.AvatarConf:GetChildren())do
		Data[stat.Name] = stat.Value
	end
	local s, e = pcall(function()
		DataStore:SetAsync('UserId'..player.UserId, Data)
	end)
		if s then 
	print(player.Name.."Data has been saved")
		else
	warn (player.Name.."Data failed to save")
	end
end

ReplicatedStorage.SaveEvent.OnServerEvent:Connect(function(player)
 saveData(player)	
end)

Players.PlayerAdded:Connect(function(player)
	playersavetable[player] = tick()
	loadStarterData(player)
	loadData(player)
end)

Players.PlayerRemoving:Connect(function(player)
	saveData(player)
end)

This script gives this output

" [16:23:48.177 - TyDye_RBLXData failed to save] "

  1. What solutions have you tried so far?
    I tried re watching the tutorial I used to help me make the script but that didn’t help. I also tried changing around a few things on my own but none of any of that helped.

If anyone has any questions then feel free to ask :smiley:

1 Like

studio API access is enabled and I tried doing it ingame to and it spits the same error

In the part where you print the ‘warn’, print also the ‘e’ variable and we’ll see what the error is.

" [ TyDye_RBLXData failed to save104: Cannot store Dictionary in data store. Data stores can only accept valid UTF-8 characters.]"

Thanks for teaching me that, but thats the reason it fails to save.

And that’s what we are looking for, aren’t we?
What are the names of your stats because something is wrong with them. I mean all the stat.Name that are used to index the Data table.

for _, stat in pairs(player.AvatarConf:GetChildren()) do
	Data[stat.Name] = stat.Value
end
local Data = {
	Face = 0;
	Shirt = 0;
	Pant = 0;
	Hat = 0;
	Torso = {5, 105, 174};
	Arms = {245, 206, 44};
	Head = {245, 206, 44};
	Legs = {165, 190, 69}
}

you mean these? thats what they are all called in the datastore

These are the stat.Name and stat.Value?

Yes, also BINGO I found the issue!

Commenting out the Color3Values causes data to save successfully and im not sure how to make it work while saving the Color3 though it will likely involve a else statement

It’s because the value of a Color3Value is not something like that {165, 190, 69} as you said but it’s a type of object that can’t be simply saved (at least I think that it’s because of that, if someone knows better - let us know) but you have to somehow extract the RGB values, put them into an array and then save.

eek! Is there any guide for that?

A lot about datastore: Data Stores | Documentation - Roblox Creator Hub
About errors and limits: Documentation - Roblox Creator Hub (your error code was 104)

The value of a Color3Value is a Color3, therefore you can reference the Color3 datatype API for your case here. There is an R, G and B property for Color3 values that you can take out and save.

local colorValue = Color3ValueObject.Value
local R, G, B = colorValue.R, colorValue.G, colorValue.B

Here is a function you can use to extract the RGB values of a Color3 and put them into an array to save them, as well as a code sample to use to handle it:

local function color3ToDictionary(color3Object)
    assert(typeof(color3Object) == "Color3", "Color3 expected")

    local color3Dictionary = {
        R = color3Object.R,
        G = color3Object.G,
        B = color3Object.B,
    }

    return color3Dictionary
end

-- Then your loop
for _, stat in ipairs(player.AvatarConf:GetChildren()) do
    if stat:IsA("Color3Value") then
        Data[stat.Name] = color3ToDictionary(stat.Value)
    else
        Data[stat.Name] = stat.Value
    end
end

EDIT: Corrected array to dictionary, oops.

DataStores can only store primitive datatypes excluding function, userdata and thread.

2 Likes

GWA! I don’t know if I just really suck or what! I don’t know if im supposed to put the color3 values in the table or where it says “Color3 expected” also do I need a function for all 4 of the things im trying to save the color for or can I create multiple tables inside one function?

You just need to copy the color3ToDictionary function and place it somewhere (particularly at the top) of your code sample and replace your for loop for compiling data with the one provided. The function is meant to accept a Color3 object and convert it into a dictionary format, then give it back. You don’t touch any of the code in those samples.

I don’t really understand your question when you’re referring to needing a function for the 4 things you want to save, an explanation would be nice. If what you’re saying is that you need to save four color values, you can just reuse the function by calling it again.

Multiple tables can be created from one function but you’ll have to return all of them as well as modify the function to accept an arbitrary amount of objects.

1 Like
local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("AvatarData")
local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local Data = {
	Face = 0;
	Shirt = 0;
	Pant = 0;
	Hat = 0;
	Torso = {5, 105, 174};
	Arms = {245, 206, 44};
	Head = {245, 206, 44};
	Legs = {165, 190, 69}
}

local function color3ToDictionary(color3Object)
    assert(typeof(color3Object) == "Color3", "Color3 expected")

    local color3Dictionary = {
        R = color3Object.R,
        G = color3Object.G,
        B = color3Object.B,
    }

    return color3Dictionary
end


local playersavetable = {};

local function loadStarterData(Player)
		local CharData = Instance.new("Folder")
		CharData.Name = "AvatarConf"
		CharData.Parent = Player
		for statname, statvalue in pairs(Data) do
			if type(statvalue) == 'number' then
			local intvalue = Instance.new("IntValue")
			intvalue.Name = statname
			intvalue.Value = statvalue
			intvalue.Parent = CharData
			else
			local colorvalue = Instance.new("Color3Value")
			colorvalue.Name = statname
			colorvalue.Value = Color3.fromRGB(statvalue[1],statvalue[2],statvalue[3])
			colorvalue.Parent = CharData
		end
	end
end

local function loadData(player)
	local Data
	local s, e = pcall(function()
	Data = DataStore:GetAsync('UserId'..player.UserId)
	end)
	
	if s then 
		print (player.Name.."Data loaded")
	else
		print(player.Name.."Data failed to load")
	end
	
	if Data then
		for statname, statvalue in pairs(Data) do
			player.stats[statname].Value = statvalue
		end
		print(player.Name.."Data has been loaded")
	else
		print(player.Name.."No data found! generating..")
		end
	end

local function saveData(player)
	--if RunService:IsStudio() then return end
	local Data = {}
	for _, stat in ipairs(player.AvatarConf:GetChildren()) do
    if stat:IsA("Color3Value") then
        Data[stat.Name] = color3ToDictionary(stat.Value)
    else
        Data[stat.Name] = stat.Value
    end
end
	local s, e = pcall(function()
		DataStore:SetAsync('UserId'..player.UserId, Data)
	end)
		if s then 
	print(player.Name.."Data has been saved")
		else
	warn (player.Name.."Data failed to save")
	end
end

ReplicatedStorage.SaveEvent.OnServerEvent:Connect(function(player)
 saveData(player)	
end)

Players.PlayerAdded:Connect(function(player)
	playersavetable[player] = tick()
	loadStarterData(player)
	loadData(player)
end)

Players.PlayerRemoving:Connect(function(player)
	saveData(player)
end)

So I don’t have to modify any of the code in the samples? Sorry that is what was slipping me up. When I said the thing about saving 4 things I meant how would I save the Color3value of the Torso, Arms, Legs, and Head but it seems I only need one table if I am understanding correctly.


I was going to say its still not working because it still returned that my data failed to save but then I remembered I had studio API access disabled, so I enabled it and it worked! Thank you for the solution!

1 Like