How would one go about saving a player's position?

While making an open-world game, I’ve ran into somewhat of an issue. Every time the game is played from an account, a player spawns in the traditional method. This is good for mini-games, but not for ones where the map is just too large and quest-based for the player to restart every time they join. I’ve figured out a way to spawn the player randomly in one of the map’s many buildings, but I don’t have the basic idea on what I should start writing to save the player’s position.

I’m thinking DataStores but I’ve never really worked with those. I know this is a quite broad question but I’d like some assistance in case any of you have ran into a similar problem in the past.

Many thanks, DevForum!

I’ve got a few links for you (all of these were very helpful for me): Best way to make a DataStore?
Best way to make a DataStore?
Documentation - Roblox Creator Hub

Most likely something like:

local DataStoreService = game:GetService("DataStoreService")
local positionStore = DataStoreService:GetDataStore("PlayerPosition")
 
local success, err = pcall(function()
	positionStore:SetAsync("PLAYER ID HERE", POSITION VALUE HERE)
end)
 
if success then
	print("Success!")
end

And then reading it when the player joins.
Hope this helps!
Someperson576

2 Likes

I actually did something like this just to fool around the other day, paste this code into a script and put it into severscriptservice:

local Players = game.Players
local DatastoreService = game:GetService("DataStoreService")
local PlayerData = DatastoreService:GetDataStore("TestDataStoreSpathi") --Change this datastore name to something else
Players.PlayerAdded:Connect(function(Player)
	Player.CharacterAdded:Connect(function(Character)
		local NewPosition = PlayerData:GetAsync(Player.UserId) or {0,0,0}
		Character:MoveTo(Vector3.new(NewPosition[1], NewPosition[2], NewPosition[3]))
		
		Character:WaitForChild("Humanoid").Changed:Connect(function()
			Position = {Character.HumanoidRootPart.Position.X, Character.HumanoidRootPart.Position.Y, Character.HumanoidRootPart.Position.Z}
		end)
	end)
end)

Players.PlayerRemoving:Connect(function(Player)
	game:BindToClose(function()
	PlayerData:SetAsync(Player.UserId, Position)
	end)
end)

Note: This datastore doesn’t check to see if the data failed to load, so if your data isn’t retrieved successfully (perhaps because datastores are down,) you will just spawn at (0,0,0).

I suggest you watch datastore tutorials on YouTube so that you may get familiar with such systems.

1 Like

The links were really helpful. I think I can pull this off now. Thank you for your help, and @Spathi as well, of course!

2 Likes

You should not bind to close under a PlayerRemoving call. This means all players that ever play in that server will all be saved when it’s shut down for good, which will definitely hit limits. You should save on PlayerRemoving as well as BindToClose, but only use BindToClose to save players currently in game.

3 Likes

User Player.CharacterRemoving Evnet

1 Like

Good catch! Thank you for telling me!

2 Likes