Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Why is the DataStore not saving correctly?

My Datastore won't save. This is causing issues between The game and the avatar creator. If the player has not created an avatar, it will send them to the creator. Once created, a value is ticked. It is not saving, so it is just an endless loop between teleporting to both of the places.

Yes, the game does have access to the datastore service as I have checked the little box.

local Datastore = game:GetService("DataStoreService"):GetDataStore("Seraph1V5!")
local ServerStorage = game:GetService("ServerStorage")

local Noob = {
	Seraph = false,
	Tries = 3,
	Race = "Human",
	Hair = "Beautiful Hair",
	Shirt = "Yu",
	Pants = "Yu",
	Colour = "Pastel Brown",
	LuckyNumber = 0,
	CharacterCreated = false,
}

PlayerAdded = function(player)
	local key = "user "..player.UserId
	local Persistance = Instance.new("Folder", ServerStorage)
	Persistance.Name = "Persistance"..player.Name
	
	local Data = Instance.new("Folder", Persistance)
	Data.Name = "Data"
	local Seraph = Instance.new("BoolValue", Data)
	Seraph.Name = "Seraph"
	local Tries = Instance.new("IntValue", Data)
	Tries.Name = "Tries"
	local Race = Instance.new("StringValue", Data)
	Race.Name = "Race"
	local Hair = Instance.new("StringValue", Data)
	Hair.Name = "Hair"
	local Shirt = Instance.new("StringValue", Data)
	Shirt.Name = "Shirt"
	local Pants = Instance.new("StringValue", Data)
	Pants.Name = "Pants"
	local Colour = Instance.new("StringValue", Data)
	Colour.Name = "Colour"
	local LuckyNumber = Instance.new("StringValue", Data)
	LuckyNumber.Name = "LuckyNumber"
	local CharacterCreated = Instance.new("BoolValue", Data)
	CharacterCreated.Name = "CharacterCreated"
	

	
	local StoredData = Datastore:GetAsync(key) or Noob
	
	Seraph.Value = StoredData.Seraph
	Tries.Value = StoredData.Tries
	Race.Value = StoredData.Race
	Hair.Value = StoredData.Hair
	Shirt.Value = StoredData.Shirt
	Pants.Value = StoredData.Pants
	Colour.Value = StoredData.Colour
	LuckyNumber.Value = StoredData.LuckyNumber
	CharacterCreated.Value = StoredData.CharacterCreated

end	
-----------------------------------------------------------	

PlayerLeaving = function(player)
	local key = "user "..player.UserId
	local success, message = pcall(function()
		Datastore:SetAsync(key, {
			Seraph = ServerStorage["Persistance"..player.Name.Data.Seraph.Value],
			Tries = ServerStorage["Persistance"..player.Name.Data.Tries.Value],
			Race = ServerStorage["Persistance"..player.Name.Data.Race.Value],
			Hair = ServerStorage["Persistance"..player.Name.Data.Hair.Value],
			Shirt = ServerStorage["Persistance"..player.Name.Data.Shirt.Value],
			Pants = ServerStorage["Persistance"..player.Name.Data.Pants.Value],
			Colour = ServerStorage["Persistance"..player.Name.Data.Colour.Value],
			LuckyNumber = ServerStorage["Persistance"..player.Name.Data.LuckyNumber.Value],
			CharacterCreated = ServerStorage["Persistance"..player.Name.Data.CharacterCreated.Value]
		})
	end)
	if success then
		print("Saved '"..player.Name.."' Data. " .. message)
	end
end


game.Players.ChildAdded:Connect(function(player) PlayerAdded(player) end)
game.Players.ChildRemoved:Connect(function(player) PlayerLeaving(player) end)

--------------------------------------------------------------------------------

2 comments

0

game.Players.PlayerAdded and PlayerRemoved

0

Don't forget to accept my answer if it helps

1 answer

✓ Accepted answer

Wiki's description on PlayerRemoving:

The PlayerRemoving event fires right before a Player is leaves the game. This event fires before Instance/ChildRemoved|ChildRemoved does on Players, and behaves somewhat similarly to Instance/DescendantRemoving. Since event fires before the actual removal of a Player, this event is useful to store player data using a GlobalDataStore.

So the data was never saving because it was too late, the player already left. Simply switching the events should fix the problem. Always use PlayerAdded and PlayerRemoving on the Players service. Another thing is that ChildAdded and ChildRemoved also fires for non-Player instances.

Now, for the code itself, it is way too long. You should use loops.

local Datastore = game:GetService("DataStoreService"):GetDataStore("Seraph1V5!")
local ServerStorage = game:GetService("ServerStorage")
local names = {"Race", "Hair", "Shirt", "Pants", "Colour"}
local Noob = {
    Seraph = false,
    Tries = 3,
    Race = "Human",
    Hair = "Beautiful Hair",
    Shirt = "Yu",
    Pants = "Yu",
    Colour = "Pastel Brown",
    LuckyNumber = 0,
    CharacterCreated = false,
}

local function PlayerAdded(player) -- # localise your variables
    local stringValues = {} -- # store our string values 
    local key = "user "..player.UserId
    local Persistence = Instance.new("Folder") -- 2nd argument discouraged
    Persistence.Name = "Persistence"..player.Name
    Persistence.Parent = ServerStorage -- # Parent last

    local Data = Instance.new("Folder")
    Data.Name = "Data"
    Data.Parent = Persistence

    local Seraph = Instance.new("BoolValue")
    Seraph.Name = "Seraph"
    Seraph.Parent = Data

    local CharacterCreated = Instance.new("BoolValue")
    CharacterCreated.Name = "CharacterCreated"
    CharacterCreated.Parent = Data

    local Tries = Instance.new("IntValue")
    Tries.Name = "Tries"
    Tries.Parent = Data

    local LuckyNumber = Instance.new("IntValue") -- # it's a number, should be IntValue
    LuckyNumber.Name = "LuckyNumber"
    LuckyNumber.Parent = Data

    for _, v in ipairs(names) do
        -- # create stringvalue each name 
        local stringValue = Instance.new("StringValue")
        stringValue.Name = v
        stringValue.Parent = Data
        table.insert(stringValues, stringValue) -- # insert string value into stringValues array
    end

    local StoredData = Datastore:GetAsync(key) or Noob

    Seraph.Value = StoredData.Seraph
    Tries.Value = StoredData.Tries
    LuckyNumber.Value = StoredData.LuckyNumber
    CharacterCreated.Value = StoredData.CharacterCreated

    for k, v in pairs(StoredData) do
        for _, stringValue in ipairs(stringValues) do
            if type(v) == "string" then -- # assign string value Value property to the strings
                stringValue.Value = v
            end
        end
    end
end 
----------------------------------------------------------- 

local function PlayerLeaving(player)
    local key = "user "..player.UserId
    local dataToStore = {}

    for _, child in ipairs(ServerStorage["Persistence" .. player.Name]:GetChildren()) do
        dataToStore[child.Name] = child.Value -- # key is the name of child, value is it's Value property
    end

    local success, message = pcall(function()
        Datastore:SetAsync(key, dataToStore)
    end)
    if success then
        print("Saved '"..player.Name.."' Data.")
    end
end


game.Players.PlayerAdded:Connect(PlayerAdded)
game.Players.PlayerRemoving:Connect(PlayerLeaving)
--------------------------------------------------------------------------------

1 comment

0

Thank you for this. But I have 1 problem. When Loading in, all of the string values are saved and loaded as "Beautiful Hair". For some reason, all of the strings are loading the value of Hair

This discussion is preserved as it was. New answers, comments, and votes are closed.