In my game, players have an inventory made up of folders and values. (not leaderstats)
This inventory is cloned to a player when they join. I used a script to save a player’s data when they leave, but it doesn’t work. I have made sure Studio has access to HTTP requests and API services. For now, I am only trying to save the BoughtHouse value. Here is my script:
local DataStoreService = game:GetService("DataStoreService")
local store = DataStoreService:GetDataStore("Houses")
game.Players.PlayerRemoving:Connect(function(plr)
local playerUserID = plr.UserId
local playeOwnsHouse = plr.Inventory.BoughtHouse.Value
local setSuccess, errorMessage = pcall(function()
store:SetAsync(playerUserID, playeOwnsHouse)
end)
if not setSuccess then
warn(errorMessage)
end
end)
game.Players.PlayerAdded:Connect(function(plr)
local getSuccess, currentValue = pcall(function()
return store:GetAsync(plr.UserId)
end)
if getSuccess then
plr.Inventory.BoughtHouse.Value = currentValue
end
end)
local DataStoreService = game:GetService("DataStoreService")
local store = DataStoreService:GetDataStore("Houses")
game.Players.PlayerRemoving:Connect(function(plr)
local playerUserID = plr.UserId
local playeOwnsHouse = plr.Inventory.BoughtHouse.Value
local setSuccess, errorMessage = pcall(function()
store:SetAsync("House_"..playerUserID, playeOwnsHouse)
end)
if not setSuccess then
warn(errorMessage)
end
end)
game.Players.PlayerAdded:Connect(function(plr)
local data
local getSuccess, err = pcall(function()
data = store:GetAsync("House_"..plr.UserId)
end)
if getSuccess then
plr.Inventory.BoughtHouse.Value = data
end
end)
If you are testing this in studio, data storing in studio will not always work, I’m not entirely sure why. This is why you use a BindToClose function. It is helpful in studio and in the real game to test datastoring when the server is shut down or is closing. In this case, when you are testing in studio and you press “Stop” during test mode, the server is shut down, and the BindToClose function is ran.
I also edited some of your code so that when the Datastore Service fails to retrieve player data, it will retry 10 times until it is successful. That way, your game will have a higher chance of successful retrieving and saving data.
I annotated my code below for you, let me know if I help with anything else.
local DataStoreService = game:GetService("DataStoreService")
local store = DataStoreService:GetDataStore("Houses")
game.Players.PlayerAdded:Connect(function(player)
local data = nil
-- Repeats Getting Data 10 Times until Successful
local tries = 0
local success, err = false, nil
repeat
tries += 1
success, err = pcall(function()
data = store:GetAsync("House_"..player.UserId)
end)
if not success then wait(1) end
until
tries == 10 or success
-- When Successful, Set the Data
-- If not Successful, warn the Output
if success then
player.Inventory.BoughtHouse.Value = data
else
warn(err)
end
end)
local function SaveData(player)
-- Get Player ID and Data
local playerUserID = player.UserId
local playerOwnsHouse = player.Inventory.BoughtHouse.Value
-- Repeat Saving 10 Times until Successful
local tries = 0
local success, err = false, nil
repeat
success, err = pcall(function()
store:SetAsync("House_"..playerUserID, playerOwnsHouse)
end)
if not success then wait(1) end
until
tries == 10 or success
-- If Not Successful, Warn
if not success then
warn(err)
end
end
-- Save Data on Leave
game.Players.PlayerRemoving:Connect(function(player)
SaveData(player)
end)
-- Save Data on ServerClosing
game:BindToClose(function()
wait(1)
for _, player in pairs(game.Players:GetPlayers()) do
coroutine.wrap(SaveData)(player)
end
end)