The reason I am not using that when the player leaves, is as mentionned in the previous post not working. So an autosave every 5-20 seconds would be good. Or even a mannual autosave.
So how should I fix this. Yes this is my first time using DataStore.
What did ‘value’ print as? .PlayerAdded/.PlayerRemoved not working doesn’t really make sense and is symptomatic of something else going on with your code.
It’s mostly me having problems with PlayerRemoved (as mentionned in previous post). I also tried to use BindToClose since my game is a single player game. I will print everything and comeback quickly.
@PerilousPanther I tried a new script. Here it is. bad news: STILL DOESN’T SAVE.
local DataStoreService = game:GetService("DataStoreService")
local DataStore1 = DataStoreService:GetDataStore("DataStore1")
local success, currentData = pcall(function()
return DataStore1:GetAsync("Player_1234")
end)
if success then
print("Current Data:", currentData)
end
local function saveData(dataStoreKey, value)
local setSuccess, errorMessage = pcall(function()
DataStore1:SetAsync(dataStoreKey, value)
end)
print(value)
if not setSuccess then
warn(errorMessage)
end
end
local function Saving(player, Data)
-- Update data store key
local playerUserID = player.UserId
if Data then
saveData(playerUserID, Data)
print(playerUserID, Data)
end
end
while true do
wait(20)
local Players = game:GetService("Players")
local Player = Players:GetPlayers()
local players = Players:GetPlayers()
for _, player in pairs(players) do
local playerData = {
NickName = player.leaderstats.NickName.Value
}
local userId = player.UserId
local data = playerData[userId]
--print(playerData)
Saving(player, playerData)
end
end
If it could help I can send every scripts. While they are in my previous post it may just save a bit of time.
Ok, so what did it print? I looked at the other post and I’m not sure why you’re using multiple scripts for data loading/saving, or where a potential data leak is coming from. In this kind of situation I think you should start using a datastore module that does a lot of the heavy lifting for you. One of the better ones is ProfileService.
It’s comprehensive, easy to use and enables you to not to worry (generally) about data leaks.
Copied and pasted (I did something in the base script if the value is nil it will be the player’s name)
In order:
18:51:37.717 Current Data: nil - Server - SaveData:9
18:51:37.717 Current Data is: 16Thunderstorm - Server - Data:24
18:51:58.200 ▼ {
[“NickName”] = “16Thunderstorm”
} - Server - SaveData:17
18:51:58.201 484327688 ▼ {
[“NickName”] = “16Thunderstorm”
} - Server - SaveData:28
I’ll try to put everything in one script (base)
What are you doing here?
local success, currentData = pcall(function()
return DataStore1:GetAsync("Player_1234")
end)
You’re trying to index a DataStore object with a player id. This is NOT how you use datastores. DataStore:GetAsync()
is what you should be using. Also, you shouldn’t be saving the data every 5 seconds, since the maximum rate you can save the same value is every 6 seconds, and you should wait every 60 seconds to autosave. Also, this wont be doing anything regardless since you save the exact same data to the data store.
So as of right now I made this:
(I think there are some things I should redo but I’m in a bit of a rush)
@iiPotatoFlamesii
@PerilousPanther
The Script
local DataStoreService = game:GetService("DataStoreService")
local DataStore1 = DataStoreService:GetDataStore("DataStore1")
game.Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local Name = Instance.new("StringValue")
Name.Name = "NickName"
Name.Parent = leaderstats
local PlayerUserid = "Player_"..player.UserId
local Data
local success, errormessage = pcall(function()
Data = DataStore1:GetAsync(PlayerUserid)
end)
if success then
local leaderstats = player:WaitForChild("leaderstats")
local NickName = leaderstats.NickName
NickName.Value = Data
if Data ~= nil then
Name.Value = Data
print("Current Data is: "..Name.Value)
print("Data: "..Data)
else
Name.Value = Data
print("Data: "..Data)
print(Name.Value)
end
else
print(errormessage)
end
end)
game.Players.PlayerRemoving:Connect(function(player)
local PlayerUserid = "Player_"..player.UserId
local Data = player.leaderstats.NickName.Value
local success, errormessage = pcall(function()
DataStore1:SetAsync(PlayerUserid, Data)
end)
if success then
print("Data was saved")
else
print("There was an error")
warn(errormessage)
end
end)
--CHANGE NICKNAME
--CHANGE NICKNAME
--CHANGE NICKNAME
local Event = game.ReplicatedStorage.DumbInfo.NickName -- Put RemoteEvent here
Event.OnServerEvent:Connect(function(Player, Text)
local NickName = Player.leaderstats.NickName
NickName.Value = Text
local success, newName = pcall(function()
return DataStore1:UpdateAsync("Player_1234", Text)
end)
if success then
print("New NickName:", NickName.Value)
end
print("New NickName: "..NickName.Value)
end)
--CHANGE NICKNAME
--CHANGE NICKNAME
--CHANGE NICKNAME
--DEFAULT TEXT
--DEFAULT TEXT
--DEFAULT TEXT
print("TESTING")
game.Players.PlayerAdded:Connect(function(player)
local PlayerUserid = "Player_"..player.UserId
local Data
local success, errormessage = pcall(function()
Data = DataStore1:GetAsync(PlayerUserid)
end)
local GUI = player.PlayerGui:WaitForChild("PlayersCard").Frame.NNFrame
local TextLabel = GUI.Default
local TextBox = GUI.ChangeNickName
print("PLAYER JOINED")
print(player.Name.." is crazy") --I usually write dumb stuff
local leaderstats = player:WaitForChild("leaderstats")
local NickName = leaderstats.NickName
print(NickName.Value, Data)
if Data == "" or nil then
print("There is no text")
TextLabel.Visible = false
else
print("THERE IS TEXT")
TextLabel.Visible = true
TextLabel.Text = NickName.Value
TextBox.Text = NickName.Value
end
end)
-- This part I think a lot of it should be redone.
--DEFAULT TEXT
--DEFAULT TEXT
--DEFAULT TEXT
--SERVER CLOSING
--SERVER CLOSING
--SERVER CLOSING
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
game:BindToClose(function()
-- if the current session is studio, do nothing
if RunService:IsStudio() then
print("YOU'RE IN STUDIO")
return
end
print("saving player data")
-- go through all players, saving their data
local players = Players:GetPlayers()
for _, player in pairs(players) do
local playerData = {
NickName = player.leaderstats.NickName.Value
}
local userId = player.UserId
local data = playerData[userId]
if data then
-- wrap in pcall to handle any errors
local success, result = pcall(function()
-- SetAsync yields so will stall shutdown
DataStore1:SetAsync(userId, data)
end)
if not success then
warn(result)
end
end
end
print("completed saving player data")
end)
--SERVER CLOSING
--SERVER CLOSING
--SERVER CLOSING
--AUTOSAVE
--AUTOSAVE
--AUTOSAVE
local success, currentData = pcall(function()
return DataStore1:GetAsync("Player_1234")
end)
if success then
print("Current Data:", currentData)
end
local function saveData(dataStoreKey, value)
local setSuccess, errorMessage = pcall(function()
DataStore1:SetAsync(dataStoreKey, value)
end)
print(value)
if not setSuccess then
warn(errorMessage)
end
end
local function Saving(player, Data)
-- Update data store key
local playerUserID = player.UserId
if Data then
saveData(playerUserID, Data)
print(playerUserID, Data)
end
end
while true do
wait(20) -- Changed it so it's not so frequent, might make it longer
local Players = game:GetService("Players")
local Player = Players:GetPlayers()
local players = Players:GetPlayers()
for _, player in pairs(players) do
local playerData = {
NickName = player.leaderstats.NickName.Value
}
local userId = player.UserId
local data = playerData[userId]
--print(playerData)
Saving(player, playerData)
end
end
--AUTOSAVE
--AUTOSAVE
--AUTOSAVE
I really think there are parts that I have to redo.
I have to. Definetly I have to redo
Why are you updating a sync to Player_1234?
local success, newName = pcall(function()
return DataStore1:UpdateAsync("Player_1234", Text)
end)
This was probably made when I started to learn how DataStore works (I am still learning).
This too:
Where it says “Player_1234” put the playerID, otherwise the data will never be loaded/ updated.
I’ll start rewriting, but please know as of writing this I am at school, so I won’t be so available. But I’ll try. So I’ll rewrite it part by part.
So this is the first part:
local DataStoreService = game:GetService("DataStoreService")
local DataStore1 = DataStoreService:GetDataStore("DataStore1")
--The basics, we get our DataStore
game.Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local Name = Instance.new("StringValue")
Name.Name = "NickName"
Name.Parent = leaderstats
--There will be more
local PlayerUserid = "Player_"..player.UserId
print(PlayerUserid)
--Just for the sake of it.
local Data
local success, errormessage = pcall(function()
Data = DataStore1:GetAsync(PlayerUserid)
end)
if success then
--Getting our leaderstats of the player
local leaderstats = player:WaitForChild("leaderstats")
local NickName = leaderstats.NickName
NickName.Value = Data --Just so the value is changed
if Data ~= nil then --If nothing existed before
Data = player.Name --Default NickNames will be the player’s name.
print("Current Data is: "..Name.Value) --It will be nil
print("Data: "..Data)
else
Name.Value = Data
print("Data: "..Data)
--Nothing needs to be done here
print(Name.Value)
end
else
print(errormessage)
end
end)
I might rewrite this since I will have to add more values.
Newer version of the first part:
local DataStoreService = game:GetService("DataStoreService")
local DataStore1 = DataStoreService:GetDataStore("DataStore1")
--The basics, we get our DataStore
game.Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local Name = Instance.new("StringValue")
Name.Name = "NickName"
Name.Parent = leaderstats
--There will be more
local Desc = Instance.new("StringValue")
Name.Name = "Description"
Name.Parent = leaderstats
local PlayerUserid = "Player_"..player.UserId
print(PlayerUserid)
--Just for the sake of it.
local Data
local success, errormessage = pcall(function()
Data = DataStore1:GetAsync(PlayerUserid)
end)
if success then
--Getting our leaderstats of the player
local leaderstats = player:WaitForChild("leaderstats")
local NickName = leaderstats.NickName
NickName.Value = Data
local Desc = leaderstats.Description
Desc.Value = Data
NickName.Value = Data.Name
Desc.Value = Data.Desc
if Data ~= nil then --If nothing existed before
Name.Value = player.Name
--Default NickNames will be the player’s name.
print("Current NickName is: "..Name.Value)
--It will be nil
print("Data: "..Data)
else
Name.Value = Data.Name
Desc.Value = Data.Desc
print("Data: "..Data)
--Nothing needs to be done here
print(Name.Value, Desc.Value)
end
else
print(errormessage)
end
end)
Please correct any mistakes.
The reason I added a new value was because as I watched a tutorial. When the person added a value they changed the code a bit.
So to avoid confusion. Here are the steps of what happens (some parts (while playing) what I plan on).
In Client’s side: (Player’s experience playing)
- Joins
- Data loads
- If he looks at the UIs of his info and his surroundings, everything seems to be like what he kept it as.
- The player can freely change his info and other things.
In Server’s side: (how things run)
- Player joins.
- Data loads and the values inside of player.leaderstats are changed to Data.
- Everything’s loaded into the player.
- Usually when the player changes something, it will change the value and once done the data will change to the value. Upon changes.
I hope I didn’t forget anything.
And does it work now? If not I would seriously consider the module option.