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.
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:
Create a RemoteEvent and put it in ReplicatedStorage. Call it “ChangeLeaderstat”.
Create a variable at the start of your localscript: local ChangeLeaderstat = game.ReplicatedStorage.ChangeLeaderstat
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
In the same serverscript, add the same variable at the start of the script: local ChangeLeaderstat = game.ReplicatedStorage.ChangeLeaderstat
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
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
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.
local ChangeLeaderstat = game.ReplicatedStorage.ChangeLeaderstat
local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("MoneyStats")
game.Players.PlayerAdded:Connect(function(Player)
local leaderstats = Instance.new("Folder") --Added this part because it gave an error that leaderstats isnt apart of player
leaderstats.Name = "leaderstats"
leaderstats.Parent = Player
local Gems = Instance.new("IntValue")
Gems.Name = "Gems"
Gems.Value = 250
Gems.Parent = leaderstats
local Coins = Instance.new("IntValue")
Coins.Name = "Coins"
Coins.Value = 0
Coins.Parent = leaderstats
-- 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;
})
ChangeLeaderstat.OnClientEvent:Connect(function(plr, stat, value)
plr.leaderstats[stat].Value = value
end)
end)
local ChangeLeaderstat = game.ReplicatedStorage.ChangeLeaderstat
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)
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 - Amount)
script.Parent.Parent.Visible = false
script.Parent.Parent.Parent.Visible = false
wait(3)
end
end
I believe it would work, there is just nothing that fires the second script once the button gui is clicked.
Basically the first script is the normal leaderstat script i have
Haha. You haven’t read my instructions correctly XD
in step 3 I mentioned to replace everything in the Click() function with that code. So this would be the whole script:
local ChangeLeaderstat = game.ReplicatedStorage.ChangeLeaderstat
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
if tonumber(Amount) then
if gems.Value >= tonumber(Amount) then
ChangeLeaderstat:FireServer("Coins", coins.Value + Amount * 20)
ChangeLeaderstat:FireServer("Gems", gems.Value - Amount)
script.Parent.Parent.Visible = false
script.Parent.Parent.Parent.Visible = false
wait(3)
end
end
end
confirm.MouseButton1Down:connect(Click)
Did my peanut brain do this correct? If so theres an error.
20:37:57.713 OnClientEvent can only be used on the client - Server - OtherLeaderstats:42
20:37:57.714 Stack Begin - Studio
20:37:57.714 Script 'ServerScriptService.OtherLeaderstats', Line 42 - Studio - OtherLeaderstats:42
20:37:57.714 Stack End - Studio
Haha, I like to help people, are u sure its all working now? If so, you can mark one of my posts as a solution so people don’t have to keep finding it and trying to help further
The user basically injects a local script into the game and runs any possible code they want on the client. So they could run something like this:
local value = 9999999999999999999
game.ReplicatedStorage.ChangeLeaderstat:FireServer("Coins", value)
game.ReplicatedStorage.ChangeLeaderstat:FireServer("Gems", value)
-- ez free money
The best way to counter this is by doing the math and checking if the value is valid on the SERVER. This is a rather hard thing to learn and hard to explain so I would recommend this post that explains it well. You could also do some research on how to secure your game better.
As I’ve just mentioned have to warn you though, it’s pretty complicated seeing your current level of scripting knowledge, but see what u can do. It’s fine if you don’t understand it yet as currently its not the most important thing since you are still learning. But it is important to address security of your future serious projects/games in the future.