104: Cannot store Dictionary in data store

i’ve seen multiple threads about this, but, it seems like for each person the reason why this error pops up is different. so, i’ll try my best to explain what i’m doing.

i want to save IDs of a character (image IDs), along with its scale, speed, and name for a RP game. since i want to be able to save up to 4 custom characters, and since it basically follows the same format i just have a function that copies the table.

i’ve seen people use modulescripts, but when it comes to saving i feel like i have no idea what i’m working with so i’m using a normal script in ServerScriptService.

here’s the script:

local charabase = {
	name = "",
	idle1 = 0, idle2 = 0,
	walk1 = 0, walk2 = 0, walk3 = 0, walk4 = 0,
	jump = 0, fall = 0, sit = 0,
	canfly = false, fly1 = 0, fly2 = 0, fly3 = 0, flyidle = 0, 
	offset = 0, scale = Vector2.new(0, 0), 
	idlespeed = 0, walkspeed = 0
}

local function copytable(orig) -- copies tables, returns the copy
    local orig_type = type(orig)
    local copy
    if orig_type == 'table' then
        copy = {}
        for orig_key, orig_value in next, orig, nil do
            copy[copytable(orig_key)] = copytable(orig_value)
        end
        setmetatable(copy, copytable(getmetatable(orig)))
    else -- number, string, boolean, etc
        copy = orig
    end
    return copy
end

local basedata = {
	charas = {
		[1] = copytable(charabase),
		[2] = copytable(charabase),
		[3] = copytable(charabase),
		[4] = copytable(charabase)
	},
	playtime = 0,
	money = 0
}

here’s the script for saving, in case that’s important. what i try to do is have everything locally loaded into a table, and when the player leaves it’s saved.

local cachedata = {}
local function saving(player, newdata, cacheonly)
	newdata.money = newdata.money + 2 --temporary
	if cacheonly == false then
		local id = "playerdata_"..player.UserId
		local success, errormsg = pcall(function()
			playerdata:SetAsync(id, newdata)
		end)
		if success then	print("saved")
		else warn("data unable to be saved: "..errormsg) end
	end
	cachedata[player.UserId] = newdata
	print(cachedata[player.UserId].money)
end
game.Players.PlayerRemoving:Connect(function(player)
	saving(player, cachedata["playerdata_"..player.UserId], false)
end)

i have the brain the size of a wallnut when it comes to using datastore, so i don’t really understand what i’m doing wrong.

This is kind of off-topic and not going to specifically answer your question, but I was just like this when starting to use DataStores.

To this day, I’m still not the greatest at using DataStores, but I did find a module that helped me TREMENDOUSLY. It’s called DataStore2. I’m not trying to be one of those people that promotes others modules, this module actually made my life 1000x easier.

Hopefully using this module will help you :slight_smile:

2 Likes

I’m currently in a slight hurry, so I can’t go into detail on the matter, but as @ObstacleIsland says, DataStore2 can make things easier.

1 Like

There’s your issue, Vector2 is a Roblox datatype and none of those can be saved.
You could easily put the X and Y into an array and then unpack that array into a Vector2.new constructor when you need it again.

For example:

--// Saving
local Vect = Vector2.new(1, 2)
local Data = {Vect.X, Vect.Y}

--// Getting
local Data = {1, 2}
local Vect = Vector2.new(unpack(Data))

If you’d like to know, this is called serialization/deserialization.

2 Likes

i’ve been thinking of using it for a while, but i’m not sure how to exactly save arrays with datastore2. i’ll try to look into it, though!

1 Like

OHHH, that’s why??
i had no idea! thank you!

2 Likes