I want to save the player’s data when this player leaves the game. (
BindToClose runs only when ALL players leave the game, so I’m using
game.Players.PlayerRemoving for that).
Also, to avoid excessive data transfer to DataStore, during the game, I’m using a “Cache”, ie, I’m storing all player’s data from LocalScript to ServerScript, and storing this data in a local variable “Jogo” in ServerScript (which is persistent).
Therefore, the data will be effectively saved (SetAsync) ONLY when the player leaves the game.
In short, this is the logic:
- Data from LocalScript is sent to ServerScript
- ServerScript keeps this data in a global variable “Jogo”
- This process will repeat until the player leaves the game
When the player leaves the game, the following must occur:
game.Players.PlayerRemovingwill run and set the final player’s data to be saved
- This final data will be sent to Server
game.Players.PlayerRemovingwill run and finally save (SetAsync) the player’s data effectively.
print("LOCAL Start") local ReplicatedStorage = game:GetService("ReplicatedStorage") local RemoteEventCache = ReplicatedStorage:WaitForChild("RemoteEventCache") -- disparado pelo cliente, salva tabela de celulas do jogador atual no cache local Jogo = "** Local Init Data" local function Cache() -- will send data to Server for cache print("LOCAL Cache") print(Jogo) RemoteEventCache:FireServer(Jogo) -- send data to Server cache print("LOCAL: after RemoteEventCache") -- - Here, SERVER Cache should have already been run end game.Players.PlayerRemoving:Connect(function(Player) -- when a player leaves the game print('--------------------') print("LOCAL PlayerRemoving") Jogo = "** Data from LOCALSCRIPT must be saved" Cache() -- força envio do cache (independente dos 5 segundos) end)
print("SERVER Start") local DataStoreService = game:GetService("DataStoreService") local RunService = game:GetService("RunService") local ReplicatedStorage = game:GetService("ReplicatedStorage") local Jogo = "** Server Init Data will be saved" -- player's data (persistent in the Server Script) local function Cache(Player, Jogo2) -- save player's data in cache (but not SetAsync) print("SERVER Cache") Jogo = Jogo2 end function FlushCache(Player, Jogo) print("SERVER FlushCache") warn(Jogo) local JogoStore = DataStoreService:GetDataStore("Jogo", Player) JogoStore:SetAsync("Jogo", Jogo) warn("Saved") end game.Players.PlayerRemoving:Connect(function(Player) -- when a player leaves the game print("SERVER PlayerRemoving") FlushCache(Player, Jogo) -- SetAsync the current global variable Jogo end) game:BindToClose(function() -- no more users (server Shutdown) print("SERVER BindToClose") if RunService:IsRunning() and RunService:IsStudio() then -- only when stopping the game in Studio wait(3) -- will force Studio to wat 3 secs to finish SetAsync in PlayerRemoving end end) ReplicatedStorage:WaitForChild("RemoteEventCache").OnServerEvent:Connect(Cache) -- cliente -> servidor, quando LocalScript altera conteúdo da tabela 'Celula' e
Running the game (save to Roblox first), here the output:
As shown above, after the LocalScript
RemoteEventCache:FireServer(Jogo) runs, the correspondent Server “Cache” function should be fired.
Therefore, the final player’s data sent from LocalScript
"** Data from LOCALSCRIPT must be saved" are not being received by the server, which is saving the old data there
"** Server Init Data will be saved"…
What’s wrong? Why the final LocalScript
FireServer is not being received by the Server?
Here the project to download, save, and test:
DataStore.rbxl (22.9 KB)