I want to make a save system so that people don't have to restart every single time they play
I don't really know what to do so I will show you the code for my leader stats this is located in the work space
local function onPlayerJoin(player)
local leaderstats = Instance.new("Model")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local gold = Instance.new("IntValue")
gold.Name = "JumpBoost"
gold.Value = 150
gold.Parent = leaderstats
local speed = Instance.new("IntValue")
speed.Name = "Speed"
speed.Value = 20
speed.Parent = leaderstats
local coin = Instance.new("IntValue")
coin.Name = "CloudCoins"
coin.Value = 0
coin.Parent = leaderstats
local rebirths = Instance.new("IntValue")
rebirths.Name = "Rebirths"
rebirths.Value = 0
rebirths.Parent = leaderstats
end
game.Players.PlayerAdded:Connect(onPlayerJoin)
Again I don't really know what to do so, please help.
The documentation for Data Stores is pretty good. An important warning for testing :
DataStoreService cannot be used in Studio if a game is not configured to allow access to API services.
So you will have to publish the game and configure it online to allow you to make HTTP requests and access the Data Store APIs. So be sure to look at the section in that link titled, Using Data Stores in Studio, it will walk you through the menus.
Anyways, right now, you are creating the player's starting values when they join the game. DataStores allow you save the values from the last session and then load those in the next time they join.
Roblox DataStores allow you to store key-value tables. Let's make a helper object for managing the loading and saving of data.
Make a ModuleScript called PlayerDataStore :
-- Make a database called PlayerExperience, we will store all of our data here
local DataStoreService = game:GetService("DataStoreService")
local playerStore = DataStoreService:GetDataStore("PlayerExperience")
local PlayerDataStore = {}
function PlayerDataStore.getDataForPlayer(player, defaultData)
-- attempt to get the data for a player
local playerData
local success, err = pcall(function()
playerData = playerStore:GetAsync(player.UserId)
end)
-- if it fails, there are two possibilities:
-- a) the player has never played before
-- b) the network request failed for some reason
-- either way, give them the default data
if not success or not playerData then
print("Failed to fetch data for ", player.Name, " with error ", err)
playerData = defaultData
else
print("Found data : ", playerData)
end
-- give the data back to the caller
return playerData
end
function PlayerDataStore.saveDataForPlayer(player, saveData)
-- since this call is asyncronous, it's possible that it could fail, so pcall it
local success, err = pcall(function()
-- use the player's UserId as the key to store data
playerStore:SetAsync(player.UserId, saveData)
end)
if not success then
print("Something went wrong, losing player data...")
print(err)
end
end
return PlayerDataStore
Now we can use this module to handle all of our loading and saving.
At the end of the day, your player join code will look very similar to your example, it will just try to first load the data. It is also important to listen for when the player leaves, so you can save their data for next time.
In a Script next to PlayerDataStore :
-- load in the PlayerDataStore module
local playerDataStore = require(script.Parent.PlayerDataStore)
local function onPlayerJoin(player)
-- get the player's information from the data store,
-- and use it to initialize the leaderstats
local defaultData = {
gold = 150,
speed = 0,
coins = 0,
rebirths = 0,
}
local loadedData = playerDataStore.getDataForPlayer(player, defaultData)
-- make the leaderboard
local leaderstats = Instance.new("Model")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local gold = Instance.new("IntValue")
gold.Name = "JumpBoost"
gold.Value = loadedData.gold
gold.Parent = leaderstats
local speed = Instance.new("IntValue")
speed.Name = "Speed"
speed.Value = loadedData.speed
speed.Parent = leaderstats
local coin = Instance.new("IntValue")
coin.Name = "CloudCoins"
coin.Value = loadedData.coins
coin.Parent = leaderstats
local rebirths = Instance.new("IntValue")
rebirths.Name = "Rebirths"
rebirths.Value = loadedData.rebirths
rebirths.Parent = leaderstats
end
local function onPlayerExit(player)
-- when a player leaves, save their data
local playerStats = player:FindFirstChild("leaderstats")
local saveData = {
gold = playerStats.JumpBoost.Value,
speed = playerStats.Speed.Value,
coins = playerStats.CloudCoins.Value,
rebirths = playerStats.Rebirths.Value,
}
playerDataStore.saveDataForPlayer(player, saveData)
end
game.Players.PlayerAdded:Connect(onPlayerJoin)
game.Players.PlayerRemoving:Connect(onPlayerExit)
Hope this helps!
I tried everything i found but nothing seems to0 be working, here is my script
local DataStoreService = game:GetService('DataStoreService')
local playerData = DataStoreService:GetDataStore('PlayerData')
local datatobesaved
local function load(player: Player)
local leaderstats = Instance.new('Folder')
leaderstats.Name = 'leaderstats'
leaderstats.Parent = player
local LuckSauceIn = Instance.new('StringValue')
LuckSauceIn.Name = 'LuckSauce'
LuckSauceIn.Parent = leaderstats
LuckSauceIn.Value = "0"
local LuckSauce = Instance.new('NumberValue')
LuckSauce.Name = 'LuckSauceInt'
LuckSauce.Parent = player
local LuckUppgradeCost = Instance.new('NumberValue')
LuckUppgradeCost.Name = 'LuckUppgradeCost'
LuckUppgradeCost.Parent = player
LuckUppgradeCost.Value = 1000
local luckMultiplier = Instance.new('NumberValue')
luckMultiplier.Name = 'LuckMultiplier'
luckMultiplier.Parent = player
local autoClicksGamePass = Instance.new('BoolValue')
autoClicksGamePass.Name = 'autoClicksGamePassOwned'
autoClicksGamePass.Parent = player
autoClicksGamePass.Value = false
local instantClicksGamePass = Instance.new('BoolValue')
instantClicksGamePass.Name = 'instantClicksGamePassOwned'
instantClicksGamePass.Parent = player
instantClicksGamePass.Value = false
local doubleLuckGamePass = Instance.new('BoolValue')
doubleLuckGamePass.Name = 'doubleLuckGamePassOwned'
doubleLuckGamePass.Parent = player
doubleLuckGamePass.Value = false
local PlayerUserId = 'Player_'..player.UserId
local data = playerData:GetAsync(PlayerUserId)
if data then
print(data['LuckSauce'].." valuenow")
player.LuckSauceInt.Value = data['LuckSauce']
else
print("no data")
player.LuckSauceInt.Value = 0
end
end
local function save(player: Player)
print(player.LuckSauceInt.Value.." Money")
datatobesaved = {
LuckSauce = player.LuckSauceInt.Value
}
local playerid = 'Player_'..player.UserId
local success, err = pcall(function()
playerData:SetAsync(playerid, datatobesaved)
end)
if success then
print("data saved!")
else
print("data failed to save!")
end
end
game:BindToClose(function()
for i, plr in pairs(game.Players:GetPlayers()) do
save(plr)
end
end)
game.Players.PlayerAdded:Connect(function(player: Player)
load(player)
end)
game.Players.PlayerRemoving:Connect(function(player: Player)
print(player.leaderstats.LuckSauce.Value.." Money before")
save(player)
end)
i tried hard coding in wat the data should be by making it 5, so now it always loads as 5 so that works but the saving is the problem
Ive tried all the things people recomended on other posts but nothing works also i dont have it anywhere else that removes them either, i want the values to not become zero right before trying to save
I was trying to make a Loading Data screen so it will fit perfectly and when the screen is fully loaded, fire a RemoteEvent that will load the data
I was expecting that this will work but instead of working, my data doesn't loaded correctly even when it's already saved on the previous game.
There are no error messages, as the codes are stable
I didn't tried any of the fixes, because I thought my code is fine enough.
Here's my code:
local function addData(player)
local Profile = Instance.new("Folder")
Profile.Name = "ProfileData"
Profile.Parent = player
local Books = Instance.new("Folder")
Books.Name = "BooksData"
Books.Parent = player
local Interactions = Instance.new("Folder")
Interactions.Name = "InteractionsActivity"
Interactions.Parent = player
local Settings = Instance.new("Folder")
Settings.Name = "SettingsData"
Settings.Parent = player
local Coins = Instance.new("IntValue")
Coins.Name = "Coins"
Coins.Parent = Profile
Coins.Value = 0
local Diamonds = Instance.new("IntValue")
Diamonds.Name = "Diamonds"
Diamonds.Parent = Profile
Diamonds.Value = 0
local XP = Instance.new("IntValue")
XP.Name = "XP"
XP.Parent = Profile
XP.Value = 0
local Level = Instance.new("IntValue")
Level.Name = "Level"
Level.Parent = Profile
Level.Value = 0
local IsSettingsOpen = Instance.new("IntValue")
IsSettingsOpen.Name = "IsSettingsOpen"
IsSettingsOpen.Parent = Interactions
local CurrentScreenOrientation = Instance.new("IntValue")
CurrentScreenOrientation.Name = "CurrentScreenOrientation"
CurrentScreenOrientation.Parent = Settings
end
local function loadData(player)
local PlayerId = "Player_" ..player.UserId
local SaveData = GameDataStore:GetAsync(PlayerId)
if SaveData then
player.ProfileData.Coins.Value = SaveData['Coins']
player.ProfileData.Diamonds.Value = SaveData['Diamonds']
player.ProfileData.XP.Value = SaveData['XP']
player.ProfileData.Level.Value = SaveData['Level']
player.InteractionsActivity.IsSettingsOpen.Value = SaveData['IsSettingsOpen']
player.SettingsData.CurrentScreenOrientation.Value = SaveData['CurrentScreenOrientation']
print("[GameData] Data loaded!")
else
player.ProfileData.Coins.Value = 0
player.ProfileData.Diamonds.Value = 0
player.ProfileData.XP.Value = 0
player.ProfileData.Level.Value = 0
player.InteractionsActivity.IsSettingsOpen.Value = 0
player.SettingsData.CurrentScreenOrientation.Value = 1
end
ReplicatedStorage.DataLoaded:FireClient(player)
print("[GameData] Firing DataLoaded RemoteEvent to Single Client")
end
local function saveData(player)
local SaveData = {
Coins = player.ProfileData.Coins.Value,
Diamonds = player.ProfileData.Diamonds.Value,
XP = player.ProfileData.XP.Value,
Level = player.ProfileData.Level.Value,
IsSettingsOpen = player.InteractionsActivity.IsSettingsOpen.Value,
CurrentScreenOrientation = player.SettingsData.CurrentScreenOrientation.Value
}
local PlayerId = "Player_" ..player.UserId
local success, err = pcall(function()
GameDataStore:SetAsync(PlayerId, SaveData)
end)
if success then
print("[GameData] Data has been sucessfully saved!")
else
warn("[Warning - GameData] Failed to save data! Check your internet connection and try again!")
end
end
Players.PlayerAdded:Connect(addData)
ReplicatedStorage.LoadData.OnServerEvent:Connect(loadData)
Players.PlayerRemoving:Connect(saveData)
And again, as my previous asked question one, I found out why this happens
In Roblox Studio, DataStore always fails and sometimes just work, but in Roblox, it's working like as expected.
I made data store but its not loading saves values.
I tried on actual servers, still nothing.
also its outputs only log, no errors, no warnings.
local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("SkinStats")
game.Players.PlayerAdded:Connect(function(Player)
local Leaderstats = Instance.new("Folder", Player)
Leaderstats.Name = "leaderstats"
local Cash= Instance.new("IntValue", Leaderstats)
Cash.Name = "Cash"
Cash.Value = 100
local Kills= Instance.new("IntValue", Leaderstats)
Kills.Name = "Kills"
Kills.Value = 0
local Data = DataStore:GetAsync(Player.UserId)
print(Data)
if Data then
Cash.Value = Data["Cash"]
Kills.Value = Data["Kills"]
print("also works")
end
end)
game.Players.PlayerRemoving:Connect(function(Player)
DataStore:SetAsync(Player.UserId, {
["Cash"] = Player.leaderstats.Cash.Value;
["Kills"] = Player.leaderstats.Kills.Value;
})
end)
There is a problem in the way you're saving the data. You need to add comma "," not semi-colon ";".
game.Players.PlayerRemoving:Connect(function(Player)
DataStore:SetAsync(Player.UserId, {
["Cash"] = Player.leaderstats.Cash.Value,
["Kills"] = Player.leaderstats.Kills.Value
})
end)
I asked a second question because my last one was getting out of the subject with comments. So I'm trying to make roblox saving the stats of a player but it puts always the basic stats. Even if the player already played.
Here's my code :
local HttpService = game:GetService("HttpService")
local DataStoreService = game:GetService("DataStoreService")
local ds = DataStoreService:GetDataStore("Data")
game.Players.PlayerAdded:Connect(function(player)
local defaultData = {
coins = 0,
gems = 0,
xp = 0,
level = 1,
maxstamina = 100,
maxmagic = 100,
}
local loadedData = defaultData
local success, result = pcall(function()
return ds:GetAsync(player.UserId)
end)
if success then
if result then
-- if we've successfully loaded the data, parse the stored json data
print(string.format("An old player named %s has returned with data : %s!", player.Name, tostring(result)))
-- player data should look like this :
-- {"coins":0,"xp":0,"gems":0,"level":1,"maxstamina":100,"maxmagic":100}
local parseSuccess, parseResult = pcall(function()
return HttpService:JSONDecode(result)
end)
if parseSuccess then
loadedData = parseResult
else
warn(string.format("Failed to parse %s with error : %s", tostring(result), tostring(parseResult)))
end
else
-- we have a new player
print(string.format("New player named %s has joined!", player.Name))
end
else
warn(string.format("Something went wrong fetching %s's data : %s", player.Name, tostring(result)))
-- TO DO: FIGURE OUT HOW YOU WANT TO HANDLE THIS ERROR.
-- IF YOU DO NOTHING, THE PLAYER'S DATA WILL BE THE DEFAULT DATA USED FOR
-- NEW PLAYERS
end
-- create the leaderstats and hidden values, load the data from the loadedData table
local leaderstats = Instance.new("Model", player)
leaderstats.Name = "leaderstats"
local hidden = Instance.new("Model", player)
hidden.Name = "hidden"
local coins = Instance.new("IntValue", leaderstats)
coins.Name = "Coins"
coins.Value = loadedData.coins
local gems = Instance.new("IntValue", leaderstats)
gems.Name = "Gems"
gems.Value = loadedData.gems
local level = Instance.new("IntValue", leaderstats)
level.Name = "Level"
level.Value = loadedData.level
local xp = Instance.new("IntValue", hidden)
xp.Name = "XP"
xp.Value = loadedData.xp
local maxstamina = Instance.new("IntValue", hidden)
maxstamina.Name = "MaxStamina"
maxstamina.Value = loadedData.maxstamina
local maxmagic = Instance.new("IntValue", hidden)
maxmagic.Name = "MaxMagic"
maxmagic.Value = loadedData.maxmagic
local stamina = Instance.new("IntValue", hidden)
stamina.Name = "Stamina"
stamina.Value = loadedData.maxstamina
local magic = Instance.new("IntValue", hidden)
magic.Name = "Magic"
magic.Value = loadedData.maxmagic
end)
game.Players.PlayerRemoving:Connect(function(player)
local stats = player.leaderstats
local hidden = player.hidden
local data = {
coins = stats.Coins.Value,
gems = stats.Gems.Value,
xp = hidden.XP.Value,
level = stats.Level.Value,
maxstamina = hidden.MaxStamina.Value,
maxmagic = hidden.MaxMagic.Value,
}
-- wrap the request in a try-catch block to ensure that failures don't throw errors
local success, result = pcall(function()
-- save all the data as a JSON string
ds:setAsync(player.UserId, HttpService:JSONEncode(data))
end)
if not success then
warn(string.format("Failed to save %s's data with error : %s", player.Name, tostring(result)))
-- TO DO: FIGURE OUT HOW YOU WANT TO HANDLE THIS ERROR.
-- IF YOU DO NOTHING, THE PLAYER WILL LOSE THIS SESSION'S DATA
end
end)
More info :
The game is public but not finished here's the link if you wan't to test it : https://web.roblox.com/games/4867142155/Medieval-Fighting-Simulator-Beta?refPageId=b25ecb6b-40c9-4c28-a4bb-2e4e0a6c6d61
The Studio API Service is enabled
There's no error code
How can you help me?
I changed my answer :
So we must use DataStore2 and then it shall work!
Here's a good DataStore2 tutorial : https://www.youtube.com/watch?v=hBfMfB0BwGA
Here's my final code :
local DataStore2 = require(1936396537)
local defaultCoins = 0
local defaultGems = 0
local defaultLevel = 1
local defaultXP = 0
local defaultMStamina = 100
local defaultMMagic = 100
DataStore2.Combine("Data","coins","gems","level","xp","mstamina","mmagic")
local xpToLevelUp = function(level)
return 100 + level * 5
end
game.Players.PlayerAdded:Connect(function(player)
local coinsDataStore = DataStore2("coins",player)
local gemsDataStore = DataStore2("gems",player)
local levelDataStore = DataStore2("level",player)
local xpDataStore = DataStore2("xp",player)
local mstaminaDataStore = DataStore2("mstamina",player)
local mmagicDataStore = DataStore2("mmagic",player)
local stats = Instance.new("Folder",player)
stats.Name = "stats"
local coins = Instance.new("IntValue",stats)
coins.Name = "Coins"
local gems = Instance.new("IntValue",stats)
gems.Name = "Gems"
local level = Instance.new("IntValue",stats)
level.Name = "Level"
local xp = Instance.new("IntValue",stats)
xp.Name = "XP"
local mstamina = Instance.new("IntValue",stats)
mstamina.Name = "MStamina"
local stamina = Instance.new("IntValue",stats)
stamina.Name = "Stamina"
local mmagic = Instance.new("IntValue",stats)
mmagic.Name = "MMagic"
local magic = Instance.new("IntValue",stats)
magic.Name = "Magic"
local function coinsUpdate(updatedValue)
coins.Value = coinsDataStore:Get(updatedValue)
end
local function gemsUpdate(updatedValue)
gems.Value = gemsDataStore:Get(updatedValue)
end
local function levelUpdate(updatedValue)
level.Value = levelDataStore:Get(updatedValue)
end
local function xpUpdate(updatedValue)
if updatedValue >= xpToLevelUp(levelDataStore:Get(defaultLevel)) then
xpDataStore:Increment(xpToLevelUp(levelDataStore:Get(defaultLevel)) * -1)
levelDataStore:Increment(1)
else
player.stats.XP.Value = updatedValue
end
end
local function mStaminaUpdate(updatedValue)
mstamina.Value = mstaminaDataStore:Get(updatedValue)
end
local function mMagicUpdate(updatedValue)
mmagic.Value = mmagicDataStore:Get(updatedValue)
end
coinsUpdate(defaultCoins)
gemsUpdate(defaultGems)
levelUpdate(defaultLevel)
xpUpdate(defaultXP)
mStaminaUpdate(defaultMStamina)
mMagicUpdate(defaultMMagic)
stamina.Value = mstamina.Value
magic.Value = mmagic.Value
coinsDataStore:OnUpdate(coinsUpdate)
gemsDataStore:OnUpdate(gemsUpdate)
levelDataStore:OnUpdate(levelUpdate)
xpDataStore:OnUpdate(xpUpdate)
mstaminaDataStore:OnUpdate(mStaminaUpdate)
mmagicDataStore:OnUpdate(mMagicUpdate)
end)
game.ReplicatedStorage.Buy.OnServerEvent:Connect(function(player,cost,item)
local coinsDataStore = DataStore2("coins",player)
if player.leaderstats.Coins.Value < cost then
game.ReplicatedStorage.NotEnoughCoins:FireClient(player)
else
coinsDataStore:Increment(cost * -1,defaultCoins)
local buyedItem = game.ReplicatedStorage.Products:WaitForChild(item)
local clonedItem = buyedItem:Clone()
clonedItem.Parent = player.Backpack
end
end)
game.ReplicatedStorage.EarnCoins.OnServerEvent:Connect(function(player,coins)
local coinsDataStore = DataStore2("coins",player)
coinsDataStore:Increment(coins,defaultCoins)
end)
game.ReplicatedStorage.EarnGems.OnServerEvent:Connect(function(player,gems)
local gemsDataStore = DataStore2("gems",player)
gemsDataStore:Increment(gems,defaultGems)
end)
game.ReplicatedStorage.Enchance.OnServerEvent:Connect(function(player,cost,item,enchancedItem)
local gemsDataStore = DataStore2("gems",player)
if player.leaderstats.Gems.Value < cost then
game.ReplicatedStorage.NotEnoughGems:FireClient(player)
else
gemsDataStore:Increment(cost * -1,defaultGems)
item:Destroy()
local clonedItem = enchancedItem:Clone()
clonedItem.Parent = player.Backpack
end
end)
game.ReplicatedStorage.GainXP.OnServerEvent:Connect(function(player,amount)
local xpDataStore = DataStore2("xp",player)
xpDataStore:Increment(amount,defaultXP)
end)
game.ReplicatedStorage.LevelUp.OnServerEvent:Connect(function(player)
local mstaminaDataStore = DataStore2("mstamina",player)
local mmagicDataStore = DataStore2("mmagic",player)
mstaminaDataStore:Increment(25,defaultMStamina)
mmagicDataStore:Increment(25,defaultMMagic)
end)