Why i only get nil from datastore?

Hi guys. Im trying to create a position saver with datastore. This part below is how i saved the data. The second part is where it reads nil aways instead of the saved value.

Why is this happening?

-- saving:
	local playerUserId = "Player_"..player.UserId
	    local character = sessionData[playerUserId].Char
	    sessionData[playerUserId].X = character.HumanoidRootPart.CFrame.Position.X
            sessionData[playerUserId].Y = character.HumanoidRootPart.CFrame.Position.Y
            sessionData[playerUserId].Z = character.HumanoidRootPart.CFrame.Position.Z
	    sessionData[playerUserId].x = character.HumanoidRootPart.CFrame.LookVector.X
	    sessionData[playerUserId].y = character.HumanoidRootPart.CFrame.LookVector.Y
	    sessionData[playerUserId].z = character.HumanoidRootPart.CFrame.LookVector.Z
	    print("saved X =",sessionData[playerUserId].X)
	        local tries = 0
	        local success
	        local errormsg
	        repeat
	            tries = tries + 1
	            success, errormsg = pcall(function() playerData:SetAsync(playerUserId, sessionData[playerUserId]) end)

-- reading:
	local data
	    local sussess, errormsg = pcall(function() data = playerData:GetAsync(playerUserId) end)
	    if data then -- se tiver
	        warn("DataStore downloaded for", player)
	        sessionData[playerUserId] = data
	        print("reading X =", sessionData[playerUserId].X) -- prints nil
	 
	    spawn(function() -- this part is constanty atualizing character info for when player leaves.
	        while saving and player.Character do
	            if character.Humanoid.SeatPart ~= nil then
	                seat = character.Humanoid.SeatPart
	            end
	            if seat then
	                sessionData[playerUserId].Vehicle = character.Humanoid.SeatPart.Parent.Name
	            else
	                sessionData[playerUserId].Vehicle = "None"
	            end
	            sessionData[playerUserId].Char = player.Character
	            print(character, "saving")
	        wait(2)
	        end
	    end)

Notes: I checked that “sessionData[playerUserId].Char” is saving corectly with all infos needed. Also I tried putting a generic number instead of Position.X and it keeps returning nil instead of the number, same with string, to make sure I can save Position.XYZ in datastore. The “data” variable is sussessfuly returning a table. All the data saved comes just as “nil nil nil nil”. PCalls sucess and errormsgs are OK.

Whole code:

-- Set up table to return to any script that requires this module script
local PositionSaver = {}

local DataStoreService = game:GetService("DataStoreService")
local playerData = DataStoreService:GetDataStore("PlayerData")

-- Table to hold player information for the current session
local sessionData = {}


-- Function to add player to the "sessionData" table

local function LoadData(player)
	repeat wait() until player.Character and player.Character.HumanoidRootPart
	character = player.Character
	local playerUserId = "Player_"..player.UserId
	---Remove Data When Player is Loaded---
	--playerData:RemoveAsync(playerUserId)
	--playerData:RemoveAsync("Player_65654127")
	---------------------------------------
	local data 
	local sussess, errormsg = pcall(function() data = playerData:GetAsync(playerUserId) end)
	print("Error: ", errormsg)
	if data then -- se tiver
		warn("DataStore baixada para", player)
		sessionData[playerUserId] = data -- traz do dado da datastore para a sessiondata
		player.Character:MoveTo(Vector3.new(sessionData[playerUserId].X,
			sessionData[playerUserId].Y,sessionData[playerUserId].Z))
		player.Character.HumanoidRootPart.Orientation = Vector3.new(sessionData[playerUserId].x,
			sessionData[playerUserId].y, sessionData[playerUserId].z)
		print(player, "replaced to:", sessionData[playerUserId].X,
			sessionData[playerUserId].Y, sessionData[playerUserId].Z)
		if sessionData[playerUserId].Vehicle ~= "None" and sessionData[playerUserId].Vehicle ~= nil then
			print(player,"com veiculo: ", sessionData[playerUserId].Vehicle, " carregado.")
			local veh = game.Workspace:FindFirstChild("Vehicles"):FindFirstChild(sessionData[playerUserId].Vehicle):Clone()
			veh:SetPrimaryPartCFrame(character.HumanoidRootPart.CFrame)
			character.Humanoid:Sit(veh.DriveSeat)
		end
	else -- user novo
		sessionData[playerUserId] = {}
		table.insert(sessionData[playerUserId], "X")
		table.insert(sessionData[playerUserId], "Y")
		table.insert(sessionData[playerUserId], "Z")
		table.insert(sessionData[playerUserId], "x")
		table.insert(sessionData[playerUserId], "y")
		table.insert(sessionData[playerUserId], "z")
		table.insert(sessionData[playerUserId], "Vehicle")
		sessionData[playerUserId].Vehicle = "None"
		table.insert(sessionData[playerUserId], "Char")
		sessionData[playerUserId].Char = character
		warn("DataStore nova criada para", player)
	end
	spawn(function() 
		while player.Character do
			if character.Humanoid.SeatPart ~= nil 
			and character.Humanoid.SeatPart.Parent.Name ~= "None" then
				sessionData[playerUserId].Vehicle = character.Humanoid.SeatPart.Parent.Name
			else
				sessionData[playerUserId].Vehicle = "None"
			end
			sessionData[playerUserId].Char = player.Character
		wait(2)	
		end
	end)
end

local function savePlayerData(player) -- called in autosave and in PlayerRemoving(SaveOnExit)
	local playerUserId = "Player_"..player.UserId
	local character = sessionData[playerUserId].Char
	sessionData[playerUserId].X = character.HumanoidRootPart.CFrame.Position.X
	sessionData[playerUserId].Y = character.HumanoidRootPart.CFrame.Position.Y
	sessionData[playerUserId].Z = character.HumanoidRootPart.CFrame.Position.Z
	sessionData[playerUserId].x = character.HumanoidRootPart.CFrame.LookVector.X
	sessionData[playerUserId].y = character.HumanoidRootPart.CFrame.LookVector.Y
	sessionData[playerUserId].z = character.HumanoidRootPart.CFrame.LookVector.Z
	print("saved X =",sessionData[playerUserId].X)
		local tries = 0	
		local success
		local errormsg
		repeat
			tries = tries + 1
			success, errormsg = pcall(function() playerData:SetAsync(playerUserId, sessionData[playerUserId]) end)
			if not success then
				wait(1)
				warn("|retrying save data for", player,".|| Error:", errormsg)
			end
		until tries == 3 or success -- tries to save 3 times
		if not success then
			warn("Cannot save data for", player,".|| Error:", errormsg)
		else
			warn("Data de", player, "salva", "Error: ", errormsg)
		end
end

----------------------------------------------------------------
game.Players.PlayerAdded:Connect(LoadData)
local RemoteEvent = game.ReplicatedStorage.RemoteEvent
RemoteEvent.OnServerEvent:Connect(function(plr, request)
	if request == "love" then
		savePlayerData(plr)
	end
end)

----------------------------------------------------------------
return PositionSaver

I dont think that your actually able to save Vector3 values in a datastore, only a boolean, string, integer and table
@Necro_las Also you should consider using DataStore2 but thats just my opinion though

Are you saving with values?

I agree with loveicicle. I don’t think you can save Vector3 values. DataStore2 is much easier and efficient.

Im not saving vector3 values.
I have not ;-; Only if I could make this work first.

and what do you mean by “with values”, Mega?

Maybe try to convert the whole vector3 into a string and then save it and when loading it back in game just de-compile it back to a vector

--vector3s to strings

local VectorToString = function(vec)
    return vec.X..' '..vec.Y..' '..vec.Z
end

local StringToVector = function(str)
        local tab = {}
    for a in string.gmatch(str,"%d+") do
           table.insert(tab,a)
        end
        return Vector3.new(tab[1],tab[2],tab[3])
end

VECTOR3 TO A TABLE

local VectorToTable = function(vec)
    return {vec.X,vec.Y,vec.Z}
end

local TableToVector = function(tab)
    return Vector3.new(tab[1],tab[2],tab[3])
end
1 Like

Are you saving intvalues, boolvalues, vector3values?

Hes saving the X Y and Z position of the character
image

Oh, that makes a lot more sense. I agree with your way.

You could also make a table and serialize it.

1 Like

Even when I save just “10”(as string) instead of anything, it reads nil from datastore.

How about you try the method I gave above I think it will really help you

Use loveicicle’s method or use DataStore2.

sorry but it doesnt seem to work. I think i will have to search about datastore2 then.Thank you guys s2

Well, he’s saving the X Y and Z values of CFrame separately, so this is not the case.

1 Like

Well even then its still easier to just convert the Vector3 into a string a or table then read it while its being loaded back into a Vector3 then just individually saving each Vector

I think you’re getting the DataStore with a different “PlayerUserID” string. (You don’t specify what the value is in your “reading” code)

On the reading code, replace this line:

local sussess, errormsg = pcall(function() data = playerData:GetAsync(playerUserId) end)

with this:

local sussess, errormsg = pcall(function() data = playerData:GetAsync("Player_"..player.UserId)

If that doesn’t work you should make sure you’re using the same datastore keycode for both scripts, else it won’t work.

I haven’t copied that part in the code shown, but right above that GetAsync I already reset the playerUserId. So thats not the problem.