Is there any way to save player data between places?

Hey Roblox Devs. I thought about an issue in my game, which would be saving player data between places. See, I think I made a mistake by making 2 different places in my game instead of just doing it all in one place. The thing is I want to have the main place be the place where you can just hang around, look at leaderboards, buy stuff, etc, and then the second place would be the main action…If I wanted a coin system, and if I made it so that you can buy things from both the main lobby and the main game, I would need the whole game in one place right?

So, having 2 different places in my game, means that the data will only get stored in one of those places and not the other, unless there’s a way to transfer the data between places.

Please let me know if I should just have my game in one place instead of 2, or if there’s a way to transfer the player data. (Also, when I say “place” I’m refering to “places” in asset manager)

1 Like

If both places are under the same game then you are good, since data is stored globally in the game, which means you can access it from all places within it.

Please see this roblox reference, specifically the header titled Sending Teleport Data:

If you are using Datastore, it can be accessed from any Place in your universe (using the same name of the datastore).

3 Likes

Are you sure? I tested that at first. I have 2 values named level and coins, placed in leaderstats. If this was true, then when I teleport through the places I should have the same leaderstats, which I don’t.

1 Like

Are you sure you are using the same name for the datastores?

You can see here in first paragraph that its accessible from any place within the experience.

1 Like

Wdym using the same name? So I need a data store script for every place I have in my game? If so, yes, I’m using the same name…I can’t show you my scripts right now because I’m on my phone, but once I’m home I can show you.

I don’t know how I would access the data store from another place in the first place. Can you show me? Currently I have a script for loading data and saving data, and it’s the exact same for the two places. I tested how the data gets synced by playing the actual game and giving myself coins, then joining the other place. The coins data didn’t load, so I suppose having the same exact scripts for each place is not how I should solve this problem.

Sometimes stuff doesnt get saved in time when teleporting to another place. Try to make it so your script waits or gives enough time for your data to be saved and then teleport the player. Then once on the other side, retrieve the data and it should be fine, i think.

Is there a specific code to make the script wait or should I just put a wait()? Also, I don’t know how I would retrieve the data on the other side; wouldn’t it not recognize the data store?

yes, I’m completely sure. I can show you my script now.

local function teleportPlayers()
		if #list > 0 then
			billboard.Frame.Status.Text = "TELEPORTING"
			billboard.Frame.Status.TextColor3 = Color3.fromRGB(255, 0, 0)
			local playersToTeleport = {}
			local teleportTime = 0
			for i=1,#list do
				if game.Players:findFirstChild(list[i]) then
					table.insert(playersToTeleport,game.Players:findFirstChild(list[i]))
					TransitionEvent:FireClient(game.Players:findFirstChild(list[i]))
				else
					table.remove(list,i)	
				end
			end 
			local code = TS:ReserveServer(placeId)
			teleporting = true
			TS:TeleportToPrivateServer(placeId,code,playersToTeleport)
			repeat wait() until #list <= 0
			billboard.Frame.Status.Text = "READY"
			billboard.Frame.Status.TextColor3 = Color3.fromRGB(255, 0, 0)
			teleporting = false
		end
		
		local playerID = player.UserId

		local data = {
			Coins = player.leaderstats.Coins.Value;
			XP = player.leaderstats.XP.Value;
			Level = player.Level.Value;
			Rank = player.Rank.Value;

			BlackoutLevel = player.GunLevels.BlackoutLevel.Value;
			MP7Level = player.GunLevels.MP7Level.Value;

			campaignLevel = player.campaignLevel.Value;

			CurrentObjective = player.CurrentObjective.Value;
		}

		local success, errormessage = pcall(function()
			PlayerData:SetAsync(playerID, data)
		end)

		if success then
			print("saved data")

		else
			print("data didn't save")
			warn(errormessage)
		end

this is the script I use when the player gets teleported into the place, it saves the data.

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


game.Players.PlayerAdded:Connect(function(player)
	
	local leaderstats = Instance.new("Folder", player)
	leaderstats.Name = "leaderstats"

	local Coins = Instance.new("NumberValue", leaderstats)
	Coins.Name = "Coins"
	Coins.Value = 25
	local XP = Instance.new("NumberValue", leaderstats)
	XP.Name = "XP"
	local Level = Instance.new("NumberValue", player)
	Level.Name = "Level"
	local Rank = Instance.new("NumberValue", player)
	Rank.Name = "Rank"

	local GunsUnlocked = Instance.new("Folder", player)
	GunsUnlocked.Name = "GunsUnlocked"
	--add each unlockable gun as a bool value

	local GunLevels = Instance.new("Folder", player)
	GunLevels.Name = "GunLevels"
	local BlackoutLevel = Instance.new("NumberValue", GunLevels)
	BlackoutLevel.Name = "BlackoutLevel"
	local MP7Level = Instance.new("NumberValue", GunLevels)
	MP7Level.Name = "MP7Level"

	local campaignLevel = Instance.new("NumberValue", player)
	campaignLevel.Name = "campaignLevel"

	local CurrentObjective = Instance.new("NumberValue", player)
	CurrentObjective.Name = "CurrentObjective"

	local playerID = "Player_"..player.UserId
	local data
	local success, errormessage = pcall(function()
		data = PlayerData:GetAsync(playerID)
	end)

	if success then
		Coins.Value = data
		XP.Value = data
		Level.Value = data
		Rank.Value = data

		BlackoutLevel.Value = data

		campaignLevel.Value = data

		CurrentObjective.Value = data

		print("loaded data")
	end
	
	while true do
		local data = {
			Coins = player.leaderstats.Coins.Value;
			XP = player.leaderstats.XP.Value;
			Level = player.Level.Value;
			Rank = player.Rank.Value;

			BlackoutLevel = player.GunLevels.BlackoutLevel.Value;
			MP7Level = player.GunLevels.MP7Level.Value;

			campaignLevel = player.campaignLevel.Value;

			CurrentObjective = player.CurrentObjective.Value;
		}

		local success, errormessage = pcall(function()
			PlayerData:SetAsync(playerID, data)
		end)

		if success then
			print("saved data")

		else
			print("data didn't save")
			warn(errormessage)
		end
		wait(60)
	end
end)

game.Players.PlayerRemoving:Connect(function(player)
	local playerID = player.UserId

	local data = {
		Coins = player.leaderstats.Coins.Value;
		XP = player.leaderstats.XP.Value;
		Level = player.Level.Value;
		Rank = player.Rank.Value;

		BlackoutLevel = player.GunLevels.BlackoutLevel.Value;
		MP7Level = player.GunLevels.MP7Level.Value;

		campaignLevel = player.campaignLevel.Value;

		CurrentObjective = player.CurrentObjective.Value;
	}

	local success, errormessage = pcall(function()
		PlayerData:SetAsync(playerID, data)
	end)

	if success then
		print("saved data")

	else
		print("data didn't save")
		warn(errormessage)
	end
end)

this is the script I use when the player joins the game, it loads the data and when the player leaves, it saves it.

local playersInGame = game.ReplicatedStorage.playersInGame

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


game.Players.PlayerAdded:Connect(function(player)
	
	wait(0.5)
	if playersInGame.Value == 1 then	
		local leaderstats = Instance.new("Folder", player)
		leaderstats.Name = "leaderstats"
		
		local Coins = Instance.new("NumberValue", leaderstats)
		Coins.Name = "Coins"
		local XP = Instance.new("NumberValue", leaderstats)
		XP.Name = "XP"
		local Level = Instance.new("NumberValue", player)
		Level.Name = "Level"
		local Rank = Instance.new("NumberValue", player)
		Rank.Name = "Rank"
		
		local GunsUnlocked = Instance.new("Folder", player)
		GunsUnlocked.Name = "GunsUnlocked"
		--add each unlockable gun as a bool value
		
		local GunLevels = Instance.new("Folder", player)
		GunLevels.Name = "GunLevels"
		local BlackoutLevel = Instance.new("NumberValue", GunLevels)
		BlackoutLevel.Name = "BlackoutLevel"
		local MP7Level = Instance.new("NumberValue", GunLevels)
		MP7Level.Name = "MP7Level"
		
		local campaignLevel = Instance.new("NumberValue", player)
		campaignLevel.Name = "campaignLevel"
		
		local CurrentObjective = Instance.new("NumberValue", player)
		CurrentObjective.Name = "CurrentObjective"
		
		local playerID = "Player_"..player.UserId
		local data
		local success, errormessage = pcall(function()
			data = PlayerData:GetAsync(playerID)
		end)
		
		if success then
			Coins.Value = data
			XP.Value = data
			Level.Value = data
			Rank.Value = data
			
			BlackoutLevel.Value = data
			
			campaignLevel.Value = data
			
			CurrentObjective.Value = data
			
			print("loaded data")
		end
	wait(0.5)
	elseif playersInGame > 1 then
		local leaderstats = Instance.new("Folder", player)
		leaderstats.Name = "leaderstats"
		
		local Coins = Instance.new("NumberValue", leaderstats)
		Coins.Name = "Coins"
		local XP = Instance.new("NumberValue", leaderstats)
		XP.Name = "XP"
		local Level = Instance.new("NumberValue", player)
		Level.Name = "Level"
		local Rank = Instance.new("NumberValue", player)
		Rank.Name = "Rank"
		
		local GunsUnlocked = Instance.new("Folder", player)
		GunsUnlocked.Name = "GunsUnlocked"
		
		local GunLevels = Instance.new("Folder", player)
		GunLevels.Name = "GunLevels"
		local BlackoutLevel = Instance.new("NumberValue", GunLevels)
		BlackoutLevel.Name = "BlackoutLevel"
		local MP7Level = Instance.new("NumberValue", GunLevels)
		MP7Level.Name = "MP7Level"
		
		local playerID = "Player_"..player.UserId
		local data
		local success, errormessage = pcall(function()
			data = PlayerData:GetAsync(playerID)
		end)
		
		if success then
			Coins.Value = data
			XP.Value = data
			Level.Value = data
			
			BlackoutLevel.Value = data
			
			print("loaded multiplayer data")
		end
	end
end)

game.Players.PlayerRemoving:Connect(function(player)
	if playersInGame.Value == 1 then
		local playerID = player.UserId
		
		local data = {
			Coins = player.leaderstats.Coins.Value;
			XP = player.leaderstats.XP.Value;
			Level = player.Level.Value;
			Rank = player.Rank.Value;
			
			BlackoutLevel = player.GunLevels.BlackoutLevel.Value;
			MP7Level = player.GunLevels.MP7Level.Value;
			
			campaignLevel = player.campaignLevel.Value;
			
			CurrentObjective = player.CurrentObjective.Value;
		}
		
		local success, errormessage = pcall(function()
			PlayerData:SetAsync(playerID, data)
		end)
		
		if success then
			print("saved data")
			
		else
			print("data didn't save")
			warn(errormessage)
		end
		
	elseif playersInGame > 1 then
		local playerID = player.UserId
		
		local data = {
			Coins = player.leaderstats.Coins.Value;
			XP = player.leaderstats.XP.Value;
			Level = player.Level.Value;
			Rank = player.Rank.Value;

			BlackoutLevel = player.GunLevels.BlackoutLevel.Value;
			MP7Level = player.GunLevels.MP7Level.Value;
		}
		
		
		local success, errormessage = pcall(function()
			PlayerData:SetAsync(playerID, data)
		end)
		
		if success then 
			print("saved multiplayer data")
			
		else
			print("multiplayer data didn't save")
			warn(errormessage)
		end
	end
end)

this is the script I use in the other place, which gets the datastore, loads the data, and also saves it if the player leaves.

1 Like

So your saying if I having a datastore named “data” on one of my places, I can’t access that datastore through another place?

Yes you can. You just load data for datastore called “data”.