Datastore only returning value for first value

I’m using DataStoreService to store a bunch of bool values of whether a player owns a certain item or not. My problem is, it saves values, but will only save it in the first value of my table, for example:

I change the value of StarParticles to true, but when I save and re-enter the game, only the value of HeartParticles (the first value on the list) is set to true, and not StarParticles. You can see the scripts below. I’m not experienced at all with using tables/datastores so I’m not sure if I’m doing this right. I’ve checked the output, there’s no misspellings/errors, it claims my data was saved with no errors.

This is just a portion of the script:

local playerUserId = "Player_"..player.UserId
	
	-- Join
	
	local data
	local success, errormessage = pcall(function()
		data = inventoryDataStore:GetAsync(playerUserId)
	end)
	
	if success then
		-- Particles
		HeartParticles.Value = data.HeartParticles
		SparkleParticles.Value = data.SparkleParticles
		RainbowParticles.Value = data.RainbowParticles
		TreatzCookieParticles.Value = data.TreatzCookieParticles
		StarParticles.Value = data.StarParticles
		FlowerParticles.Value = data.FlowerParticles
		VideoGameParticles.Value = data.VideoGameParticles
		TicketParticles.Value = data.TicketParticles
		FlameParticles.Value = data.FlameParticles
		CashParticles.Value = data.CashParticles
		HazardParticles.Value = data.HazardParticles
		PlanetParticles.Value = data.PlanetParticles
		CrownParticles.Value = data.CrownParticles
		
		-- Nametags
		BlueNametag.Value = data.BlueNametag
		RedNametag.Value = data.RedNametag
		YellowNametag.Value = data.YellowNametag
		GreenNametag.Value = data.GreenNametag
		OrangeNametag.Value = data.OrangeNametag
		PinkNametag.Value = data.PinkNametag
		PurpleNametag.Value = data.PurpleNametag
		TurquoiseNametag.Value = data.TurquoiseNametag
		DarkGreenNametag.Value = data.DarkGreenNametag
		MaroonNametag.Value = data.MaroonNametag
		FireRedNametag.Value = data.FireRedNametag
		OliveNametag.Value = data.OliveNametag
		MagentaNametag.Value = data.MagentaNametag
		BlackNametag.Value = data.BlackNametag
		GoldenNametag.Value = data.GoldenNametag
		
		-- Icons
		LeafIcon.Value  = data.LeafIcon
		CookieIcon.Value = data.CookieIcon
		TreeIcon.Value = data.TreeIcon
		HeartIcon.Value = data.HeartIcon
		FlowerIcon.Value = data.FlowerIcon
		SoccerIcon.Value = data.SoccerIcon
		RollingPinIcon.Value = data.RollingPinIcon
		StarIcon.Value = data.StarIcon
		StrawberryIcon.Value = data.StrawberryIcon
		ExplosionIcon.Value = data.ExplosionIcon
		CupcakeIcon.Value = data.CupcakeIcon
		CrownIcon.Value = data.CrownIcon
	end

Player Leaving:

game.Players.PlayerRemoving:Connect(function(player)
	local playerUserId = "Player_"..player.UserId
	
	local data = {
		-- Particles
		HeartParticles = player.Inventory.Particles.HeartParticles.Value;
		SparkleParticles = player.Inventory.Particles.SparkleParticles.Value;
		RainbowParticles = player.Inventory.Particles.RainbowParticles.Value;
		TreatzCookieParticles = player.Inventory.Particles.TreatzCookieParticles.Value;
		StarParticles = player.Inventory.Particles.StarParticles.Value;
		FlowerParticles = player.Inventory.Particles.FlowerParticles.Value;
		VideoGameParticles = player.Inventory.Particles.VideoGameParticles.Value;
		TicketParticles = player.Inventory.Particles.TicketParticles.Value;
		FlameParticles = player.Inventory.Particles.FlameParticles.Value;
		CashParticles = player.Inventory.Particles.CashParticles.Value;
		HazardParticles = player.Inventory.Particles.HazardParticles.Value;
		PlanetParticles = player.Inventory.Particles.PlanetParticles.Value;
		CrownParticles = player.Inventory.Particles.CrownParticles.Value;
		
		-- Nametags
		BlueNametag = player.Inventory.Nametags.BlueNametag.Value;
		RedNametag = player.Inventory.Nametags.RedNametag.Value;
		YellowNametag = player.Inventory.Nametags.YellowNametag.Value;
		GreenNametag = player.Inventory.Nametags.GreenNametag.Value;
		OrangeNametag = player.Inventory.Nametags.OrangeNametag.Value;
		PinkNametag = player.Inventory.Nametags.PinkNametag.Value;
		PurpleNametag = player.Inventory.Nametags.PurpleNametag.Value;
		TurquoiseNametag = player.Inventory.Nametags.TurquoiseNametag.Value;
		DarkGreenNametag = player.Inventory.Nametags.DarkGreenNametag.Value;
		MaroonNametag = player.Inventory.Nametags.MaroonNametag.Value;
		FireRedNametag = player.Inventory.Nametags.FireRedNametag.Value;
		OliveNametag = player.Inventory.Nametags.OliveNametag.Value;
		MagentaNametag = player.Inventory.Nametags.MagentaNametag.Value;
		BlackNametag = player.Inventory.Nametags.BlackNametag.Value;
		GoldenNametag = player.Inventory.Nametags.GoldenNametag.Value;
		
		-- Icons
		LeafIcon = player.Inventory.Icons.LeafIcon.Value;
		CookieIcon = player.Inventory.Icons.CookieIcon.Value;
		TreeIcon = player.Inventory.Icons.TreeIcon.Value;
		HeartIcon = player.Inventory.Icons.HeartIcon.Value;
		FlowerIcon = player.Inventory.Icons.FlowerIcon.Value;
		SoccerIcon = player.Inventory.Icons.SoccerIcon.Value;
		RollingPinIcon = player.Inventory.Icons.RollingPinIcon.Value;
		StarIcon = player.Inventory.Icons.StarIcon.Value;
		StrawberryIcon = player.Inventory.Icons.StrawberryIcon.Value;
		ExplosionIcon = player.Inventory.Icons.ExplosionIcon.Value;
		CupcakeIcon = player.Inventory.Icons.CupcakeIcon.Value;
		CrownIcon = player.Inventory.Icons.CrownIcon.Value;
	}
	
	local success, errormessage = pcall(function()
		inventoryDataStore:SetAsync(playerUserId, data)
	end)
	
	if success then
		print("saved")
	else
		print("error")
	end
end)

This might be the issue
when you set the value, make sure you set it on serverside by either having a script handle it, or by changing to Server in the Test tab of studio before editing the properties of anything in the explorer

2 Likes

I did do that, my problem is the first value does work as intended while the rest do not.

1 Like

Sometimes testing in studio doesn’t save data when you leave because when you stop a game the server just shuts down before it can even save, so you can use function game:BindToClose(), which runs right before server shuts down

And in the function you can loop through all the players and save their data.

This is a problem usually found in studio

1 Like

I set up a local server, set SaveInStudio to true and left the game on Player1, which did print a data saved message in the output. That’s not my problem, one value is saving so I know the saving works, only the first value works and nothing else.

1 Like

Instead of ; you should have , when creating the table when the player leaves

Also instead of typing all the values manually why not just loop the values like this

local playerLoaded = {}

game.Players.PlayerAdded:Connect(function(player)
    -- when the player enters the game try to load there data
    local success, value = pcall(dataStore.GetAsync, dataStore, player.UserId)
    if success == false then return end
   
    -- if the value = nil then set value to a empty table
    value = value or {}

    -- clone the data folder inside this script with all its values
    local folder = script.Data:Clone()

    -- loop all values and set them to match what was last saved in the datastore
    for i, child in ipairs(folder) do child.Value = value[child.Name] or child.Value end

    -- place the folder into the player
    folder.Parent = player

    -- set the playerloaded to true so we can keep track if there are players loaded so that bind to close can wait
    playerLoaded[player] = true
end)

game.Players.PlayerRemoving:Connect(function(player)
    -- if player loaded == nil meaning the player failed to load when they entered we simple exit because we dont want to overwrite the old data
    if playerLoaded[player] == nil then return end
 
    -- create a table and set the the values from there data folder
    local playerData = {}
    for i, child in ipairs(player.Data:GetChildren()) do
        playerData[child.Name] = child.Value
    end

    -- now save this table to the datastore
    local success, value = pcall(dataStore.SetAsync, dataStore, player.UserId, playerData)

    -- now set playerLoaded to nil so that bindtoclose can stop looping and allow the server to close
    playerLoaded[player] = nil
end)

-- while players are loaded dont close the server (only works upto 30 seconds)
game:BindToClose(function()
    while next(playerLoaded) ~= nil do
        task.wait()
    end
end)