Datastores being broken

local DataStore = game:GetService("DataStoreService")
local ds = DataStore:GetDataStore("Ability")
local ds2 = DataStore:GetDataStore("Ability2")
local ds3 = DataStore:GetDataStore("Ability3")

--Don't worry about the rest of the code, except for line 25.
game.Players.PlayerAdded:connect(function(player)
	local leader = Instance.new("Folder",player)
	leader.Name = "Abilities"	
	local Cash = Instance.new("BoolValue",leader)
	Cash.Name = "Boost"
	local Cash2 = Instance.new("BoolValue",leader)
	Cash2.Name = "Heal"
	local Cash3 = Instance.new("BoolValue",leader)
	Cash3.Name = "Engineer"
	
game:BindToClose(function()
	for _, player in pairs(game.Players:GetPlayers()) do
		ds:SetAsync(player.UserId, player.Abilities.Boost.Value)
		ds2:SetAsync(player.UserId, player.Abilities.Heal.Value)
		ds3:SetAsync(player.UserId, player.Abilities.Engineer.Value)      
	end
end)

game.Players.PlayerRemoving:connect(function(player)
	ds:SetAsync(player.UserId, player.Abilities.Boost.Value)
	ds2:SetAsync(player.UserId, player.Abilities.Heal.Value)
		ds3:SetAsync(player.UserId, player.Abilities.Engineer.Value)
	end)
end)


Okay, your code is sort of confusing. But anyway, usually bind to close is after the PlayerRemoving function. Also why is there an end after the final SetAsync and not where the PlayerAdded function is?

I will have to fix the abilities things later, do you have a idea why the new code isn’t working?

Not really, but anything you have to fix should probably be fixed anyway, just in case.

Please use one data store and save everything in a table

Alrighty! I need to do other things though, so it might take me a mintue.

I can’t since i do not want people seeing the values of the abilities

You can still do that by the way, I do it in my game, the actual data is stored in tables, whenever a player joins, a ServerScript gets that data through a ModuleScript and sets the values in the player to the values of the data. Whenever I want to update the data, all I have to do is fire a BindableEvent and that will just set the values in the player to the values of the data.

Updated code that supports abilities:

local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local isStudio = RunService:IsStudio()
local DataStoreService = game:GetService("DataStoreService")
local ds = DataStoreService:GetDataStore("LeaderStatSave")

local temporalData = {}
local abilities = {
	"Boost",
	"Heal",
	"Engineer"
}

Players.PlayerAdded:Connect(function(plr)
	local leader = Instance.new("Folder")
	leader.Name = "leaderstats"

	local private = Instance.new("Folder")
	private.Name = "PrivateStats"

	local Coins = Instance.new("NumberValue", leader)
	Coins.Name = "Coins"

	local Wins = Instance.new("NumberValue", leader)
	Wins.Name = "Wins"

	leader.Parent = plr

	temporalData[plr.UserId] = ds:GetAsync(plr.UserId) or {}

	if temporalData[plr.UserId].Abilities == nil then
		temporalData[plr.UserId].Abilities = {}
	end

	for _, ability in ipairs(abilities) do
		if temporalData[plr.UserId].Abilities[ability] == nil then
			temporalData[plr.UserId].Abilities[ability] = false
		end
		local bool = Instance.new("BoolValue")
		bool.Name = ability
		bool.Value = temporalData[plr.UserId].Abilities[ability]
		bool:GetPropertyChangedSignal("Value"):Connect(function()
			temporalData[plr.UserId].Abilities[ability] = bool.Value
		end)
		bool.Parent = private
	end

	private.Parent = plr

	Coins.Value = temporalData[plr.UserId].Coins or 0
	Coins:GetPropertyChangedSignal("Value"):Connect(function()
		temporalData[plr.UserId].Coins = Coins.Value
	end)

	Wins.Value = temporalData[plr.UserId].Wins or 0
	Wins:GetPropertyChangedSignal("Value"):Connect(function()
		temporalData[plr.UserId].Wins = Wins.Value
	end)

	plr.AncestryChanged:Connect(function()
		if plr:IsDescendantOf(game) or temporalData[plr.UserId] == nil then
			return
		end
		if isStudio then
			print("Data not saved because it runs in Studio")
			return
		end
		local s, err = pcall(function()
			ds:UpdateAsync(plr.UserId, function()
				return temporalData[plr.UserId]
			end)
		end)
		if s ~= true then
			warn("Failed saving data for player: " .. plr.Name .. ", key: " .. plr.UserId .. "\n" .. tostring(err))
		else
			print("Data saved for player: " .. plr.Name)
		end
		temporalData[plr.UserId] = nil
	end)
end)
2 Likes

Just know, i am not a great scripter but this is extremely confusing, i;ve never used module scripts in my life so yeah.

Thanks! Do i just add more after the heal engineer etc etc?

1 Like

Just a question, what is the point? Wouldn’t this always be true?

Thanks but could i make it so its inside the player as my scripts require that
example, can i do

    private.Parent = plr

Edit: it’s there, my bad.

This is absolutely more reliable, when player leaves they no longer exist in game that’s why

So couldn’t you just do if plr?

image

Your data should be set to table, try resetting your data

game:GetService("DataStoreService"):GetDataStore("LeaderStatSave"):RemoveAsync(your user id)
1 Like

Sorry if this has already been mentioned, I’m on my phone. Have you considered using a community resource such as ProfileService? Resources like this are great at hiding all the complexities of data storage and providing you the necessary functions. They work on the concept of ‘promise’ to save data.

I think i should do this in console, am i right?

1 Like

I do not know whats a “ProfileService” but i guess i will learn.