[OPEN] DataStores not working?

Hey! I’m trying to create a DataStore system for my game, but the script isnt working? I’ve had around 10 testers and they’ve all said the saving is not working. No errors or warnings. 'player(id)‘s data was saved successfully’ and 'player(id)‘s data was fetched successfully’ is printing correctly though. I have asked a few friends and other developers and they’re not sure why it isn’t saving (the values to show up though). Please let me know if you find a solution, thanks!

local dataStoreService = game:GetService("DataStoreService")
local playerDataStore = dataStoreService:GetDataStore("playerDataStore")

game.Players.PlayerAdded:Connect(function(player)
	local leaderstatsFolder = Instance.new("Folder")
	leaderstatsFolder.Parent = player
	leaderstatsFolder.Name = "leaderstats"

	local Coins = Instance.new("IntValue")
	Coins.Parent = leaderstatsFolder
	Coins.Name = "Coins"

	local CurrentItem = Instance.new("IntValue")
	CurrentItem.Parent = leaderstatsFolder
	CurrentItem.Name = "CurrentItem"

	local Pickaxe = Instance.new("IntValue")
	Pickaxe.Parent = leaderstatsFolder
	Pickaxe.Name = "Pickaxe"

	local OwnsFurnace = Instance.new("IntValue")
	OwnsFurnace.Parent = leaderstatsFolder
	OwnsFurnace.Name = "OwnsFurnace"

	local OwnsAnvil = Instance.new("IntValue")
	OwnsAnvil.Parent = leaderstatsFolder
	OwnsAnvil.Name = "OwnsAnvil"

	local playerUserId = "Player_"..player.UserId

	local coinsData
	local currentItemData
	local pickaxeData
	local ownsFurnaceData
	local ownsAnvilData
	local success, errormessage = pcall(function()
		coinsData = playerDataStore:GetAsync(player.UserId.."-coinsData")
		currentItemData = playerDataStore:GetAsync(player.UserId.."-currentItemData")
		pickaxeData = playerDataStore:GetAsync(player.UserId.."-pickaxeData")
		ownsFurnaceData = playerDataStore:GetAsync(player.UserId.."-ownsFurnaceData")
		ownsAnvilData = playerDataStore:GetAsync(player.UserId.."-ownsAnvilData")
	end)

	if success then
		Coins.Value = coinsData
		print(player.Name.."("..player.UserId..")'s data was fetched successfully")

	else
		print(player.Name.."("..player.UserId..")'s data was fetched unsuccessfully")
		warn(errormessage)
	end
end)

game.Players.PlayerRemoving:Connect(function(player)
	local success, errormessage = pcall(function()
		playerDataStore:SetAsync(player.UserId.."-coinsData",player.leaderstats.Coins.Value)
		playerDataStore:SetAsync(player.UserId.."-currentItemData",player.leaderstats.CurrentItem.Value)
		playerDataStore:SetAsync(player.UserId.."-pickaxeData",player.leaderstats.Pickaxe.Value)
		playerDataStore:SetAsync(player.UserId.."-ownsFurnaceData",player.leaderstats.OwnsFurnace.Value)
		playerDataStore:SetAsync(player.UserId.."-ownsAnvilData",player.leaderstats.OwnsAnvil.Value)
	end)

	if success then
		print(player.Name.."("..player.UserId..")'s data was saved successfully")

	else
		print(player.Name.."("..player.UserId..")'s data was saved unsuccessfully")
		warn(errormessage)
	end
end)

It is much better to use HttpService:SerializeJSON rather than making a lot of keys like this. This can help you not hit rate limits.

local dataStoreService = game:GetService("DataStoreService")
local httpService = game:GetService("HttpService")
local playerDataStore = dataStoreService:GetDataStore("playerDataStore")

game.Players.PlayerAdded:Connect(function(player)
    local leaderstatsFolder = Instance.new("Folder")
    leaderstatsFolder.Parent = player
    leaderstatsFolder.Name = "leaderstats"

    local Coins = Instance.new("IntValue")
    Coins.Parent = leaderstatsFolder
    Coins.Name = "Coins"

    local CurrentItem = Instance.new("IntValue")
    CurrentItem.Parent = leaderstatsFolder
    CurrentItem.Name = "CurrentItem"

    local Pickaxe = Instance.new("IntValue")
    Pickaxe.Parent = leaderstatsFolder
    Pickaxe.Name = "Pickaxe"

    local OwnsFurnace = Instance.new("IntValue")
    OwnsFurnace.Parent = leaderstatsFolder
    OwnsFurnace.Name = "OwnsFurnace"

    local OwnsAnvil = Instance.new("IntValue")
    OwnsAnvil.Parent = leaderstatsFolder
    OwnsAnvil.Name = "OwnsAnvil"

    local playerUserId = "Player_"..player.UserId

    local success, data = pcall(function()
        return playerDataStore:GetAsync(player.UserId)
    end)

    if success then
        -- Deserialize the data, giving us back our table
        local data = httpService:JSONDecode(data)
        local coinsData = data.coinsData
        local currentItemData = data.currentItemData
        local pickaxeData = data.pickaxeData
        local ownsFurnaceData = data.ownsFurnaceData
        local ownsAnvilData = data.ownsAnvilData
        Coins.Value = coinsData
        print(player.Name.."("..player.UserId..")'s data was fetched successfully")

    else
        print(player.Name.."("..player.UserId..")'s data was fetched unsuccessfully")
        warn(data)
    end
end)

game.Players.PlayerRemoving:Connect(function(player)
    -- Put data into a table.
    local data = {
        coinsData = player.leaderstats.Coins.Value,
        currentItemData = player.leaderstats.CurrentItem.Value,
        pickaxeData = player.leaderstats.Pickaxe.Value,
        ownsFurnaceData = player.leaderstats.OwnsFurnace.Value,
        ownsAnvilData = player.leaderstats.OwnsAnvil.Value
    }
    local success, errormessage = pcall(function()
        -- Serialize data using HttpService.
        playerDataStore:SetAsync(player.UserId, httpService:JSONEncode(data))
    end)

    if success then
        print(player.Name.."("..player.UserId..")'s data was saved successfully")

    else
        print(player.Name.."("..player.UserId..")'s data was saved unsuccessfully")
        warn(errormessage)
    end
end)

Still not working for some reason. I have found that if i manually set the value in the dev console it saves, but doesnt work when i set the value with scripts. Thanks for the help.

Are the scripts local scripts?

Do you know how to properly use DataStoreServices? Are they LocalScripts?

Make sure you have Datastore Api Services enabled.

They’re normal scripts in ServerScriptService

All security option are enabled

Data is JSONEncoded by default when you :SetAsync and it’s decoded when you :GetAsync, no need to en/decode it again.