Datastore is not saving a string value when the player leaves the game

Here is my code below. This code saves a string value on a gui when the player leaves and then loads in the saved string value onto the gui when the player rejoins the game. For some reason, when the player leaves, the string value is not being saved. I tried adding a print line that prints the value saved in the datastore when I rejoined the game, but it just printed nil. Any ideas?

game.Players.PlayerRemoving:Connect(function(player)
	game.ReplicatedStorage.Events.PlayerisLeaving:FireClient(player)
	game.ReplicatedStorage.Events.PlayerisLeavingFireback.OnServerEvent:Connect(function(player, textstring)
		CoinQuestDatastore:SetAsync(player.UserId, textstring)
	end)
end)

Hello. This happens because the server shuts down when the last player leaves. PlayerRemoving event is not fired.
You should use game:BindToClose to solve this. I’ll link a post explaining that in detail.

https://devforum.roblox.com/t/how-to-properly-save-player-data-in-data-stores-upon-server-close/313218

It’s still not working. Any other reasons you could think of?
(btw I put the script into a bindtoclose function)

	game:BindToClose(function()

	-- When game is ready to shutdown

	for i, player in pairs(game.Players:GetPlayers()) do
		if player then
			game.ReplicatedStorage.Events.PlayerisLeaving:FireClient(player)
			game.ReplicatedStorage.Events.PlayerisLeavingFireback.OnServerEvent:Connect(function(player, textstring)
				CoinQuestDatastore:SetAsync(player.UserId, textstring)
			end)
			player:Kick("This game is shutting down")
		end
	end

	wait(5)	

end)

Also, using RemoteEvent calls on PlayerRemoving or BindToClose will just stop the script at that point. It doesn’t work because the player upon whom the RemoteEvent is called has already been removed from the game.

roblox datastore dont save strings except datastore2 (i dont know how)

I’m pretty sure this isn’t true. My old system in Restrictly used a StringValue to save whether the Player was banned or not, before I moved on to booleans. I also saved the reason for the ban.

I just tried this code, and it worked…?

local TableOfValues = {
	"Dark Team",
	"Light Team";
}

local DSS = game:GetService("DataStoreService")
local TeamData = DSS:GetDataStore("TeamData")

game.Players.PlayerAdded:Connect(function(Player)
	local Stats = Instance.new("Folder", Player)
	Stats.Name = "Stats"
	
	local TeamChosen
	xpcall(function()
		TeamChosen = TeamData:GetAsync(Player.UserId.."_Team") or nil
		warn(TeamData:GetAsync(Player.UserId.."_Team"))
	end, function(err)
		warn(err)
	end)
	
	if TeamChosen == nil then
		warn("No team chosen!")
		local RandomInt = math.random(1, 2)
		TeamChosen = TableOfValues[RandomInt]
	end
	
	local PlrTeam = Instance.new("StringValue", Stats)
	PlrTeam.Name = "TeamChosen"
	PlrTeam.Value = TeamChosen
	
	print(PlrTeam.Value)
end)

game.Players.PlayerRemoving:Connect(function(Player)
	xpcall(function()
		TeamData:SetAsync(Player.UserId.."_Team", Player.Stats.TeamChosen.Value)
		warn("Saved for "..Player.Name)
	end, function(err)
		warn(err)
	end)
end)

game:BindToClose(function()
	coroutine.resume(coroutine.create(function()
		for _, Plr in pairs(game.Players:GetPlayers()) do
			xpcall(function()
				TeamData:SetAsync(Plr.UserId.."_Team", Plr.Stats.TeamChosen.Value)
				warn("Saved Data for "..Plr.Name)
			end, function(err)
				warn(err)
			end)
		end
	end))
end)

let me try using GetDataStore instead of ordered :flushed:
nevermind it worked

2 Likes