Currency Conversion Not Saving To Leaderstats

Hello Developers,

I have not been active with trying to make games as I have been busy, but this time I have found a new creation I have been working on and for once it is going fairly well.

A bit of background on how this script is supposed to work, you convert gems to coins (this script works perfect). That’s all there is to it really. The issue that I am finding is happening is that when the player leaves the game, it does not save this change. I have a normal leaderstats with datastore in it as well. I tried making a little script in hopes that it would solve this problem but it did not. I will insert it below

local Player = game.Players.LocalPlayer
local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("MoneyStats")
local Gems = Player.leaderstats.Gems
local Coins = Player.leaderstats.Coins

game.StarterGui.ConvertGUI.ConvertingShop.Conformation.Yes.MouseButton1Click:Connect(function()
	local Data = DataStore:GetAsync(Player.UserId)
	if Data then
		Gems.Value = Data.Gems
		Coins.Value = Data.Coins 

	else
		print("There Was An Error Saving"..Player.UserId " 's Data :(")
	end


	game.Players.PlayerRemoving:Connect(function(Player)
		DataStore:SetAsync(Player.UserId, {
			["Gems"] = Player.leaderstats.Gems.Value;
			["Coins"] = Player.leaderstats.Coins.Value;

		})


	end)
end)

I kinda knew it wouldn’t work as it seems very dumb, but if anyone could help me fix this that would be great :slight_smile:
Thanks!

2 Likes

That is not a bug, you need to test your datastore in a game. Try publishing your game as a test site to test out the datastore.

BTW is that script a server script

2 Likes

Yes its a server script. I honestly don’t know anything on doing datastores. I know you can do like tables for them but I don’t know how to do those either :confused:. I’ve done lots of research too regarding them.
Learning things is just difficult for me which is why I come here.

Edit: Also will try that thank you!

Edit 2: I tried local script then I also tried a normal server one. It is in SSS

Tried it in game still did not save!

You can only work with DataStores in server scripts. I can see by your code that its a localscript. Which is why it doesn’t work. Make a script in ServerScriptStorage, and enter this code:

game.Players.PlayerAdded:Connect(function()
        local Data
        pcall(function()
                Data = DataStore:GetAsync(Player.UserId)
        end)

	if Data then
		Gems.Value = Data["Gems"]
		Coins.Value = Data["Coins"]
	else -- there is no data, which means the player joined for the first time
                Gems.Value = 0 -- Any default value you want
		Coins.Value = 0 -- Any default value you want
	end
end)
game.Players.PlayerRemoving:Connect(function(Player)
	DataStore:SetAsync(Player.UserId, {
		["Gems"] = Player.leaderstats.Gems.Value;
		["Coins"] = Player.leaderstats.Coins.Value;
	})
end)

This script will load and save leaderstats every time the player leaves/joins. In order to change a leaderstat value from a localscript, you will have to use a remote event to pass on the signal from the localscript to the server script.

Alright. Using the same local’s in the script I showed? Also is this replacing the leaderstats that I have?
(the script I put was a separate script not the leaderstats)

I don’t understand, can you clarify?

Anything that you do that has to do with the DataStore service in the localscript will NOT work. It all has to be done in a server script

The locals,

local Player = game.Players.LocalPlayer
local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("MoneyStats")
local Gems = Player.leaderstats.Gems
local Coins = Player.leaderstats.Coins

I pasted in your code and there wasn’t and lines defining what codes like Gems and Coins mean.

And yes I see, the script I made to try and fix the saving was in a normal script, so is my leaderstats.

Ah, those are called Variables btw.

Yeah sorry I am not in studio and I figured you would put the variables yourself but here I’ll do it for you:

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

game.Players.PlayerAdded:Connect(function()
    -- These variables need to be defined when the player joins, because each player has their own unique leaderstats
    local Gems = Player.leaderstats.Gems
    local Coins = Player.leaderstats.Coins

    local Data
    pcall(function()
        Data = DataStore:GetAsync(Player.UserId)
    end)

    if Data then
        Gems.Value = Data["Gems"]
	    Coins.Value = Data["Coins"]
    else -- there is no data, which means the player joined for the first time
        Gems.Value = 0 -- Any default value you want
		Coins.Value = 0 -- Any default value you want
	end
end)
game.Players.PlayerRemoving:Connect(function(Player)
	DataStore:SetAsync(Player.UserId, {
		["Gems"] = Player.leaderstats.Gems.Value;
		["Coins"] = Player.leaderstats.Coins.Value;
	})
end)

Lol, my bad that flew over my head. It still seems to be not working. The normal start value is correct but it never saves the currencies after gems is converted to coins, so maybe it is something with that script?

Isn’t is supposed to be DataStore:GetAsync(Player.UserId, {...})?

No, you only need to provide the data when setting it, not getting it. When you GET data you only need to provide the data KEY, which in this case is the UserId

1 Like

What do you mean by “gems getting converted to coins”. In the script all it does is load the player’s leaderstats when they join and save the leaderstats when the player leaves. It doesn’t add or change any leaderstats values while the player is playing. In order to actually change the values, you need to do it in a server script too.

example:

player.leaderstats.Gems += 5

Sorry, I guess I was not clear enough about the whole topic. There is another script in a GUI (which is a local script) that does all of that, which works fine, it just for some reason does not save. I will put it below, I used it off of a post on here.

local player = game.Players.LocalPlayer
local coins = player.leaderstats.Coins
local gems = player.leaderstats.Gems
local Amount = script.Parent.Parent.Parent.TypeBar.NumberHere.Text
local confirm = script.Parent.Parent.Yes

script.Parent:GetPropertyChangedSignal("Text"):Connect(function()
	script.Parent.Parent.Parent.TypeBar.NumberHere.Text = script.Parent.Parent.Parent.TypeBar.NumberHere.Text:gsub('%D+', '');  -- Forces only numerical value input
end)

function Click(mouse)	--Conversion system
	Amount = script.Parent.Parent.Parent.TypeBar.NumberHere.Text
	print(Amount)
	if tonumber(Amount) then
		if gems.Value >= tonumber(Amount) then
			coins.Value = coins.Value + Amount * 20
			gems.Value = gems.Value - Amount
			
			script.Parent.Parent.Visible = false
			script.Parent.Parent.Parent.Visible = false
			wait(3)
		end
	end
end
confirm.MouseButton1Down:connect(Click)

Whatever is typed into the TextBox will be multiplied by 20 and added to the players coins balance, subtracting the original number from the players gem balance

As I’ve said before, anything related to the DataStoreService will NOT WORK in a LOCALscript.
I’ll make a step by step guide on doing this:

  1. Create a RemoteEvent and put it in ReplicatedStorage. Call it “ChangeLeaderstat”.

  2. Create a variable at the start of your localscript:
    local ChangeLeaderstat = game.ReplicatedStorage.ChangeLeaderstat

  3. In the localscript replace everything in the Click() function to this:

Amount = script.Parent.Parent.Parent.TypeBar.NumberHere.Text
   	
if tonumber(Amount) then
	if gems.Value >= tonumber(Amount) then
		ChangeLeaderstat:FireServer("Coins", coins.Value + Amount * 20)
		ChangeLeaderstat:FireServer("Gems",	gems.Value = gems.Value - Amount)
			
		script.Parent.Parent.Visible = false
		script.Parent.Parent.Parent.Visible = false
		wait(3)
	end
end
  1. In the same serverscript, add the same variable at the start of the script:
    local ChangeLeaderstat = game.ReplicatedStorage.ChangeLeaderstat

  2. Add this to the end of the script:

ChangeLeaderstat.OnClientEvent:Connect(function(plr, stat, value)
    plr.leaderstats[stat].Value = value
end)

I have to warn you to be careful with how much control you give players over datastores/currency in your game. With this remote event, anyone could just set any amount of coins they would like using a lua executor/hack

Which serverscript? or am i just changing the (converting script) localscript to a normal? Again, sorry for all the trouble.

There is only one server script, and that is the one I mentioned before, with the PlayerAdded/PlayerRemoved events. And no you are not chang the localscript, they are 2 separate scripts

1 Like
		ChangeLeaderstat:FireServer("Gems",	gems.Value = gems.Value - Amount)

In this the “=” is underlined red, so I am assuming you need another???

As for the Click part of the function, that is the part of the code that allowed the whole code to be played. Now, when I play the game and hit “Confirm” (to convert the currency), nothing happens.

confirm.MouseButton1Down:connect(Click)

Hey, sorry for replying late.

Sorry, I haven’t tested this code so I am doing it in my browser.

replace it with this:
ChangeLeaderstat:FireServer("Coins", coins.Value + Amount * 20)
ChangeLeaderstat:FireServer("Gems", gems.Value - Amount)

If it doesn’t work show me ur scripts