Help with DataStore (read for info)

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.

1 Like

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.

1 Like

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)

  1. Joins
  2. Data loads
  3. If he looks at the UIs of his info and his surroundings, everything seems to be like what he kept it as.
  4. The player can freely change his info and other things.

In Server’s side: (how things run)

  1. Player joins.
  2. Data loads and the values inside of player.leaderstats are changed to Data.
  3. Everything’s loaded into the player.
  4. 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.