Leaderstats issue

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!
    I’m making a trail shop for my game.

  2. What is the issue? Include screenshots / videos if possible!
    Although it looks like it will work, my script doesn’t add leaderstats folder to the player.

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I asked ChatGPT. Millions of times.

After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!

local PlayersService = game:GetService("Players")
local DataStore = game:GetService("DataStoreService"):GetDataStore(":Trails5")
local TrailList = require(game.ReplicatedStorage:WaitForChild("TrailList"))

local CreateStats = {
	["Create"] = true, -- Set to false if you don't want to create Coins automatically
	["Name"] = "Coins"
}

local function LoadTrailData(Player)
	local UserId = Player.UserId
	local Success, DataArray = pcall(DataStore.GetAsync, DataStore, UserId)
	if Success and DataArray then
		print("Loaded data for", Player.Name)  -- Debug: Check if data is loaded
		for _, trailName in pairs(DataArray.OwnedTrails) do
			local trail = Instance.new("StringValue")
			trail.Name = trailName
			trail.Parent = Player.OwnedTrails
		end
		Player.EquippedTrail.Value = DataArray.EquippedTrail or ""

		if DataArray["Currency"] and CreateStats["Create"] then
			Player.leaderstats[CreateStats.Name].Value = DataArray["Currency"]
		end
	else
		print("Failed to load data for", Player.Name)  -- Debug: If data loading fails
	end
end

local function SaveTrailData(Player)
	pcall(function()
		DataStore:UpdateAsync(Player.UserId, function()
			local Array = {
				["EquippedTrail"] = Player.EquippedTrail.Value,
				["OwnedTrails"] = {},
			}

			if CreateStats["Create"] then
				Array["Currency"] = Player.leaderstats[CreateStats.Name].Value
			end

			for _, trail in pairs(Player.OwnedTrails:GetChildren()) do
				table.insert(Array.OwnedTrails, trail.Name)
			end

			return Array
		end)
	end)
end

PlayersService.PlayerAdded:Connect(function(Player)
	-- Leaderstats setup
	local Leaderstats = Instance.new("Folder")
	Leaderstats.Name = "leaderstats"
	Leaderstats.Parent = Player

	local Currency = Instance.new("IntValue")
	Currency.Name = CreateStats.Name
	Currency.Value = 0
	Currency.Parent = Leaderstats

	-- Trail storage setup
	local EquippedTrail = Instance.new("StringValue")
	EquippedTrail.Name = "EquippedTrail"
	EquippedTrail.Value = ""
	EquippedTrail.Parent = Player

	local OwnedTrails = Instance.new("Folder")
	OwnedTrails.Name = "OwnedTrails"
	OwnedTrails.Parent = Player

	-- Loaded flag
	local loaded = Instance.new("BoolValue")
	loaded.Name = "loaded"
	loaded.Value = false
	loaded.Parent = Player

	-- Load data
	LoadTrailData(Player)
	loaded.Value = true

	-- Load character trail
	local function LoadCharacterTrail(Character)
		task.delay(5, function()
			local trailTemplate = script.TrailStorage:FindFirstChild(Player.EquippedTrail.Value)
			if trailTemplate then
				local TrailClone = trailTemplate:Clone()
				TrailClone.Parent = Character:WaitForChild("UpperTorso")
				TrailClone.Attachment0 = Character.UpperTorso:WaitForChild("NeckAttachment")
				TrailClone.Attachment1 = Character.LowerTorso:WaitForChild("WaistFrontAttachment")
			end
		end)
	end

	if Player.Character then
		LoadCharacterTrail(Player.Character)
	end

	Player.CharacterAdded:Connect(function(Character)
		Character:WaitForChild("UpperTorso")
		if Player.EquippedTrail.Value ~= "" then
			LoadCharacterTrail(Character)
		end
	end)
end)


PlayersService.PlayerRemoving:Connect(function(Player)
	if Player:FindFirstChild("loaded") and Player.loaded.Value then
		SaveTrailData(Player)
	end
end)

game:BindToClose(function()
	if game:GetService("RunService"):IsStudio() then
		task.wait(1)
	else
		for _, player in pairs(PlayersService:GetPlayers()) do
			if player:FindFirstChild("loaded") and player.loaded.Value then
				SaveTrailData(player)
			end
		end
	end
end)

game.ReplicatedStorage.TrailResponse.OnServerInvoke = function(Player, TrailName, Action)
	local Response = false
	local TrailArray

	for _, trailData in pairs(TrailList) do
		if trailData.Name == TrailName then
			TrailArray = trailData
			break
		end
	end

	if not TrailArray then return end

	local Actions = {
		["Equip"] = function()
			if not Player.OwnedTrails:FindFirstChild(TrailName) then return end
			if Player.EquippedTrail.Value == TrailName then return end
			if not Player.Character then return end
			if not Player.Character:FindFirstChild("UpperTorso") then return end

			local ExistingTrail = Player.Character.UpperTorso:FindFirstChildWhichIsA("Trail")
			if ExistingTrail then ExistingTrail:Destroy() end

			Player.EquippedTrail.Value = TrailName

			local TrailClone = script.TrailStorage:FindFirstChild(TrailName)
			if TrailClone then
				local Clone = TrailClone:Clone()
				Clone.Parent = Player.Character.UpperTorso
				Clone.Attachment0 = Player.Character.UpperTorso.NeckAttachment
				Clone.Attachment1 = Player.Character.LowerTorso.WaistFrontAttachment
			end

			Response = true
		end,

		["Unequip"] = function()
			if not Player.OwnedTrails:FindFirstChild(TrailName) then return end
			if Player.EquippedTrail.Value ~= TrailName then return end

			Player.EquippedTrail.Value = ""

			if Player.Character and Player.Character:FindFirstChild("UpperTorso") then
				local TrailToRemove = Player.Character.UpperTorso:FindFirstChild(TrailName)
				if TrailToRemove then
					TrailToRemove:Destroy()
				end
			end

			Response = true
		end,

		["Buy"] = function()
			if Player.OwnedTrails:FindFirstChild(TrailName) then return end
			if Player.leaderstats[CreateStats.Name].Value >= TrailArray.Price then
				Player.leaderstats[CreateStats.Name].Value -= TrailArray.Price

				local trail = Instance.new("StringValue")
				trail.Name = TrailName
				trail.Parent = Player.OwnedTrails

				Response = true
			end
		end
	}

	if Actions[Action] then
		Actions[Action]()
	end

	return Response
end

Have you looked for errors and tried printing to make sure the code runs? Also if you print the name of the parent of Leaderstats, just before the end that closes the playeradded function, do you get the players name?

adding to what odin has said, you should do it on server.

it is on server, hence why playeradded is used to get the player