Help with DataStore (read for info)

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.

Unfortunately I am at school as of writing this, I usually write scripts, ask for any errors then run them. It’s not a problem if no one corrects me (depends). I will run it asap. I will still continue to rewrite parts and run them.
So what I’ll do is this:
Run 1st part
Fix it if there’s problems
Run 2st part (add it)
And repeat.

The problem: GetPlayers returns a table of all the players. You are doing the table and trying to index UserId (which doesn’t exist.)
Consider using this

for _,v in ipairs(Players:GetPlayers()) do
coroutine.wrap(function()
 Saving(v)
end)()
end

it loops through every player and saves their data according to your function
any issues let me know

@GalaxyRIP324 @PerilousPanther @iiPotatoFlamesii
Still not finished but here’s my progress. As of writing this I will be testing my script:

Script
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)


--PLAYER JOINS

--PLAYER JOINS

--PLAYER JOINS

--PLAYER LEAVES

--PLAYER LEAVES

--PLAYER LEAVES

--I will use this just to be sure

game.Players.PlayerRemoving:Connect(function(player)
    local PlayerUserid = "Player_"..player.UserId
     print("Player: "..player.Name.." (ID: "..PlayerUserId..") left the game.") 
      --To get info
    local Data = {
           NickName = player.leaderstats.NickName.Value;
           Description = player.leaderstats.Description
           --yes there will be more
      }
    
    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)

--PLAYER LEAVES

--PLAYER LEAVES

--PLAYER LEAVES

--SERVER CLOSES

--SERVER CLOSES

--SERVER CLOSES

--I add this to be sure if PlayerRemoved doesn’t work.
--It works a bit like the previous function.

local Players = game:GetService("Players")

local RunService = game:GetService("RunService")

game:BindToClose(function()
--This was based on DevHub’s article about this.    
    -- 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;
            Description = player.leaderstats.Description

        }

        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 CLOSES

--SERVER CLOSES

--SERVER CLOSES

--DEFAULT TEXT

--DEFAULT TEXT

--DEFAULT TEXT

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 TextBox = GUI.ChangeNickName
     local DescBox = GUI.ChangeDesc

    print("PLAYER JOINED")
    print(player.Name.." is crazy") --I usually write dumb stuff
    local leaderstats = player:WaitForChild("leaderstats")
    local NickName = leaderstats.NickName
    local Description = leaderstats.Description
      --add the future values
    print(Nickname.Value, Description.Value, Data)
    if Data == "" or nil then
        print("There is no text")
        
    else
        print("THERE IS TEXT")
        TextBox.Text = NickName.Value
           DescBox.Text = Description.Value


    end
end)

I had to change some things, there are still problems. But I didn’t add the change nickname function yet.

@PerilousPanther @GalaxyRIP324 @iiPotatoFlamesii
I’m having so much difficulty. Please help me by telling me what I am doing wrong.

Script
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")
	Desc.Name = "Description"
	Desc.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)
	print(Data)
	
	if success then
		
		--Getting our leaderstats of the player
		local leaderstats = player:WaitForChild("leaderstats")
		local NickName = leaderstats.NickName
		local Desc = leaderstats.Description
		NickName.Value = Name.Value
		
		Data.Name = NickName.Value
		Data.Desc = Desc.Value
		print(Data.Name, Data.Desc)
		
		
		if Data ~= nil then --If nothing existed before
			Name.Value = player.Name 
			Desc.Value = "No description yet"
			Data.Name = NickName.Value
			Data.Desc = Desc.Value
			print(Name.Value, Desc.Value)
			print("1: "..Data.Name, Data.Desc, "2: "..Name.Value, Desc.Value, Data)
			print(Name.Value, Desc.Value, Data)
			print(Data.Name, Data.Desc, Data)
			print(NickName.Value, Desc.Value)
			--Default NickNames will be the player’s name.
			print("Current NickName is: "..Name.Value) 
			print("Current Description is: "..Desc.Value) 

		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)


--PLAYER JOINS

--PLAYER JOINS

--PLAYER JOINS

--PLAYER LEAVES

--PLAYER LEAVES

--PLAYER LEAVES

--I will use this just to be sure

game.Players.PlayerRemoving:Connect(function(player)
	local PlayerUserid = "Player_"..player.UserId
	print("Player: "..player.Name.." (ID: "..PlayerUserid..") left the game.") 
	--To get info
	local Data = {
		NickName = player.leaderstats.NickName.Value;
		Description = player.leaderstats.Description.Value
		--yes there will be more
	}

	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)

--PLAYER LEAVES

--PLAYER LEAVES

--PLAYER LEAVES

--SERVER CLOSES

--SERVER CLOSES

--SERVER CLOSES

--I add this to be sure if PlayerRemoved doesn’t work.
--It works a bit like the previous function.

local Players = game:GetService("Players")

local RunService = game:GetService("RunService")

game:BindToClose(function()
	--This was based on DevHub’s article about this.    
	-- 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;
			Description = player.leaderstats.Description

		}

		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 CLOSES

--SERVER CLOSES

--SERVER CLOSES

--DEFAULT TEXT

--DEFAULT TEXT

--DEFAULT TEXT

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 TextBox = GUI.ChangeNickName
	--local DescBox = GUI.ChangeDesc

	print("PLAYER JOINED")
	print(player.Name.." is crazy") --I usually write dumb stuff
	local leaderstats = player:WaitForChild("leaderstats")
	local NickName = leaderstats.NickName
	local Description = leaderstats.Description
	--add the future values
	print(Data.Name)
	print(NickName.Value, Description.Value, Data)
	if Data == "" or nil then
		print("There is no text")

	else
		print("THERE IS TEXT")
		TextBox.Text = NickName.Value
		--DescBox.Text = Description.Value


	end
end)


local Event = game.ReplicatedStorage.DumbInfo.NickName -- Put RemoteEvent here

Event.OnServerEvent:Connect(function(Player, Text)

	local NickName = Player.leaderstats.NickName
	NickName.Value = Text
	local Description = Player.leaderstats.Description

	local success, newName = pcall(function()
		return DataStore1:UpdateAsync(Player.UserId, Text)
	end)

	if success then
		print("New NickName:", NickName.Value)
	end

	print("New NickName: "..NickName.Value)

end)

The reason I print so many things is that one time when I Updated the NickName, the ouput was in between 2 things. One in Data and one in value.

Remove everything after the .PlayerRemoving function and tell me if the datastore works. What kind of script are you using for all of this?

A normal script. Since it’s in ServerScriptService.

I am also wondering if I should do another post or rename this one to fit the current problem.

Changed some parts an now this:
Data.Name isn’t the value we changed and saved.
Data.NickName is there weirdly. So basically I’ve created a double.

I’ll comeback to this tomorrow.

So basically things are going very well. I just found out I asked for Data.Name and Data.Desc (The Instance’s name) and then I realize while printing there were 4 values: Desc, Description, Name, NickName, the real names of the String Values objects are the ones who changed. Tonight I’ll finish up things and say if there’s any problems.

I’ll obviously share the script.

2 Likes

Things are going well, I just have to patch up the leaving/closing game part which sometimes doesn’t always save but it saves now more often than before. I’ll comeback to 12:30 (lunch time), as of now it’s 9:20 am. I can still use the DevForum.

Oh and also weirdly for some reason the TextBoxe’s text aren’t the values but literally “TextBox”, bit weird I think I can fix it else I’ll ask for help.