Stats don't save when reducing your stats

  1. What do you want to achieve? Keep it simple and clear!
    I want to make a chat tags shop where you spend your coins for chat tags
  2. What is the issue? Include screenshots / videos if possible!
    The issue is that when i buy any item in the shop and then rejoin, the stats don’t save which makes me able to buy it again
    Here is the script:
local Cost = 100
local ChatTagColor = "123,255,0"
local ChatTag = "Cool"
local plr = game.Players.LocalPlayer
	if plr:WaitForChild("leaderstats").Coins.Value >= Cost and plr:WaitForChild("SecretFolder").ChatTag.Value ~= ChatTag then
		plr.leaderstats.Coins.Value -= Cost
		plr.SecretFolder.ChatTag.Value = ChatTag
		plr.SecretFolder.ChatTagColor.Value = ChatTagColor
		script.Parent.Text = "Equipped"
	elseif plr:WaitForChild("leaderstats").Coins.Value < Cost then
		script.Parent.Text = "Not enough coins!"
	elseif plr:WaitForChild("SecretFolder").ChatTag.Value == ChatTag then
		script.Parent.Text = "You already have it equipped!"
  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I can’t find any solution.
1 Like

Bump because this topic is being ignored (sort of)

Use DataStores, there are many tutorials and threads on how to use them. Here are just a few examples I found by typing “save” in the searchbar Lol…

1 Like

I am literally using it
The problem is that only the incremented stats save
But thanks for your recommendation

Can you provide the script that you’re using to save the data?

Here is the script

local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("DataStore")

	local leaderstats ="Folder",plr)
	leaderstats.Name = "leaderstats"

	local Wins ="NumberValue")
	Wins.Name = "Wins"
	Wins.Parent = leaderstats

	local Coins ="NumberValue")
	Coins.Name = "Coins"
	Coins.Parent = leaderstats	
	local SecretFolder ="Folder",plr)
	SecretFolder.Name = "SecretFolder"
	local ChatTag ="StringValue")
	ChatTag.Name = "ChatTag"
	ChatTag.Parent = SecretFolder
	local ChatTagColor ="StringValue")
	ChatTagColor.Name = "ChatTagColor"
	ChatTagColor.Parent = SecretFolder
	local PlayerUserId = "Player_"..plr.UserId
	local success, errormessage = pcall(function()
		data = DataStore:GetAsync(PlayerUserId, data)
	if success then
		Wins.Value = data.Wins
		Coins.Value = data.Coins
		ChatTag.Value = data.ChatTag
		ChatTagColor.Value = data.ChatTagColor
	local PlayerUserId = "Player_"..plr.UserId

	local data = {
		Wins = plr.leaderstats.Wins.Value;
		Coins = plr.leaderstats.Coins.Value;
		ChatTag = plr.SecretFolder.ChatTag.Value;
		ChatTagColor = plr.SecretFolder.ChatTagColor.Value;

	local success, errormessage = pcall(function()
		DataStore:SetAsync(PlayerUserId, data)

	if success then
		print('Data Successfully Saved!')
	if errormessage then
		print('Data UnSuccessfully Saved!')

I copied this script from a tutorial almost a year ago the time when i didn’t have any database knowledge (now i do) but i don’t see to find the issue here

So it saves when you earn coins and leave the game, but not when you spend coins and leave?

Yep, it doesn’t save when you spend coins and leave no matter how long you wait

When you test it in studio, does it say “Data Successfully Saved!” in the output when you leave?

Yep, it does print “Data Successfully Saved!” in the output. But when you rejoin the game you will still have the old/incremented stats

Try replacing that with

local data
local success, errormessage = pcall(function()
	data = DataStore:GetAsync(PlayerUserId)

That won’t work because the player stats database is stored like this (Pretend that this thing works

Database = {
                                            ChatTag = "";
                                            ChatTagColor = "";

Is this a local script? Because of FE any changes made on the client will not replicate (unless you use an event)

What do you mean? GetAsync should only have 1 parameter

The button buy script is a local script
And the database script is a script

Oh then in that case you should be firing a remote to let the server know that the player is buying something and then do the coin subtraction on the server

1 Like

So you would need to use an event to handle the currency change because if you save your data on the server then you would also need to save this on the server

You should be saving your data on the server anyways


I tried your suggestion and i got an error saying attempt to perform arithmetic (sub) on number and Instance
And here is the script

	plr.leaderstats.Coins.Value -= Cost --This line causes the error
	plr.SecretFolder.ChatTag.Value = ChatTag
	plr.SecretFolder.ChatTagColor.Value = ChatTagColor

And this is where it fires the event

local Cost = 1125
local ChatTagColor = "255, 0, 243"
local ChatTag = "ChatTag"
local plr = game.Players.LocalPlayer

You shouldn’t be passing the player argument when using FireServer, it’s automatically included.

1 Like

This is unnecessary as the player is automatically the first parameter when firing to the server

local event = game.ReplicatedStorage:WaitForChild('BuyEvent')

local event = game.ReplicatedStorage:WaitForChild('BuyEvent')

    local stats = player:WaitForChild('leaderstats')
	if stats.Coins.Value >= Cost then
        player.stats.Coins.Value -= Cost
        player.SecretFolder.ChatTag.Value = ChatTag
	    player.SecretFolder.ChatTagColor.Value = ChatTagColor