local KeyData = require(script.Parent.DataSettings)
local DSS = game:GetService("DataStoreService")
local plrPosition = DSS:GetDataStore(KeyData.Key.."-"..KeyData.Version.."-plrPosition")
--above part isn't really important
game.Players.PlayerAdded:Connect(function(player)
local plrdata = player:WaitForChild("PlayerData")
local pos = Instance.new("StringValue")
player.CharacterAdded:Connect(function(character)
wait()
repeat
pos.Name = "PosValue"
pos.Parent = plrdata
pos.Value = plrPosition:GetAsync(player.UserId) or "0, 3, 0"
local coord = {}
for num in string.gmatch(pos.Value, "[-%d%.]+") do
table.insert(coord, tonumber(num))
end
character.HumanoidRootPart.Position = Vector3.new(unpack(coord))
until character.HumanoidRootPart.Position == Vector3.new(unpack(coord))
game.Players.PlayerRemoving:Connect(function(player)
plrPosition:SetAsync(player.UserId, tostring(pos.Value))
end)
while wait(15) do
pos.Value = tostring(character.HumanoidRootPart.Position)
plrPosition:SetAsync(player.UserId, tostring(pos.Value))
end
end)
end)
Basically, when a player joins create a new string value. Whilst their character is alive, save it's HumanoidRootPart's position every 15 seconds. the repeat loop makes sure the player loads at their position . local coord variable and stuff below is converting the string into a Vector3 value. Whilst a new player successfully teleports to a fixed, set position, for some reason when a coming player joins there is a chance the script does not load the player's position and instead just spawns them at 0,Y,0, the default position roblox spawns you at. Can someone tell me what the problem is with not always loading the player's position? I do not want to use CFrame. There are also no errors in output.

8 comments
I've heard they can't be stored in datastores, tried myself and couldn't store them aswell.
Yea you can't save them, but it would be much easier to just convert it into a table rather then a string. {Vector.X, Vector.Y, Vector.Z}
I'll consider that, but I still don't know what's causing the problem of the script not loading the player's position half the time
Like I said, did you check if it's even saving, try printing?
I put a print statement after the CharacterAdded function and weirdly enough it's not printing anything depite my character fully loaded.
And to answer your question, sometimes it's saving and other it's not.
I would recommend AncestryChanged over PlayerRemoving as well so you can see when the actual player leaves the game rather then getting notified for each one. Your WaitForChild could be yielding or it could be yielding long enough to where the character has already loaded in thus not firing the event.
Thanks for your help though, turns out I previously was using Vector3Values incorrectly. I'll mark your answer as your solution.