Money gui doesn't working

Hello.

I have a problem with my money gui. The problem is that the value is saved and correctly showed in the default leaderboard but the value doesn’t appear in my gui. here’s somes screenshots.
CoinsPROB
CoinsPROBBBBBB

And here’s my scripts :

1. The gui script.

game.Players.LocalPlayer.leaderstats.Coins.Changed:connect(function()

    script.Parent.Text = game.Players.LocalPlayer.leaderstats.Coins.Value .."$"

end)

2. The DataSave and leaderstats script.

local currencyName = "Coins"
local DataStore = game:GetService("DataStoreService"):GetDataStore("TestDataStore")
------------------------------------------------------------------------------------------------------------------------
game.Players.PlayerAdded:Connect(function(player)
	
	local folder = Instance.new("Folder")
	folder.Name = "leaderstats"
	folder.Parent = player
	-------------------------------------------------------------------------------------------------------------
	local currency = Instance.new("IntValue")
	currency.Name = currencyName
	currency.Parent = folder
	
	local ID = currencyName.."-"..player.UserId
	local saveData = nil
	---------------------------------------------------------------------------------------------------------
	pcall(function()
		saveData = DataStore:GetAsync(ID)
	end)
	----------------------------------------------------------------------------------------------------------
	if saveData ~= nil then
		currency.Value = saveData
		print("Data loaded.")
	else
		currency.Value = 1000
		print("New player.")
	end	
end)
game.Players.PlayerRemoving:Connect(function(player)
	local ID = currencyName.."-"..player.UserId
	DataStore:SetAsync(ID,player.leaderstats[currencyName].Value)
end)

game:BindToClose(function()
	
	for i, player in pairs(game.Players:GetPlayers()) do
		if player then
			player:Kick("This game is being Updated !")
		end
	end
	
	wait(5)
end)
3 Likes

Maybe try
script.Parent.Text = (game.Players.LocalPlayer.leaderstats.Coins.Value.. "$")

1 Like

Instead of 3 dots, I’d use 2 dots. Would work the same.
script.Parent.Text = (game.Players.LocalPlayer.leaderstats.Coins.Value..“$”)

1 Like

I did, it changed automatically to 3 dots lol

1 Like

Oh, well.

@ArkolaTV Can you open the developer console and check if there are any errors? Might show us more insight of the problem.

Might want to check that the leaderstats folder exists first as well. If the local script runs before the leaderstats are created it will error.

1 Like

1 Like

It might be that because when i run it one time after publishing it it works but all the others run doesn’t show the value in the gui. How do i make this ?

@ArkolaTV
have you tried this?
(the problem happen beacuse that check when the coins value change to other value example: if the coins value is the same value so by the script that he made the coins no going to display on the ui until the coins value get change. but after the coins value get change so is display the coins amount on the ui. however he can also do that with “while wait() do” and then is going to display always.)

while wait() do
    script.Parent.Text = game.Players.LocalPlayer.leaderstats.Coins.Value .."$"
end)

also he can stay use with the same code but with one change:

script.Parent.Text = game.Players.LocalPlayer.leaderstats.Coins.Value .."$"
game.Players.LocalPlayer.leaderstats.Coins.Changed:connect(function()
    script.Parent.Text = game.Players.LocalPlayer.leaderstats.Coins.Value .."$"
end)
1 Like

actually he can do that beacuse i am doing that with same way and this is works.

There’s no evidence of debugging or if the console is throwing anything so actually knowing what your problem is here is impossible. Please do some debugging here and make sure your Guis are set up properly, otherwise we can’t really discern any causes of error.

From the client’s end, use some variables to avoid redundancy and don’t let your code assume that instances exist. It would also be more preferable to have your LocalScript directly descend the PlayerGui rather than a nested element because it becomes worse off to work with.

In either case, assuming you’re still working with your current setup:

**Note: Changed this code sample. It now fires with initial state.

local LocalPlayer = game:GetService("Players").LocalPlayer

-- Because you don't parent Coins before leaderstats, Coins is not guaranteed to
-- be replicated with the folder, so now you have to unnecessarily use two waits.
local leaderstats = LocalPlayer:WaitForChild("leaderstats")
local coins = leaderstats:WaitForChild("Coins")

-- Create a function so we can avoid redundancy later
local function updateCurrencyUI(newValue)
    script.Parent.Text = tostring(newValue) .. "$"
end

-- Changed on ValueObjects will fire with the new value, which will be
-- newValue in the function.
coins.Changed:Connect(updateCurrencyUI)

-- Run it for the first time so we can fire with initial state.
updateCurrencyUI()

From the server’s end, there are various improvements to be made.

There’s a thread you may or may not be aware of, to not use the parent argument of Instance.new. While you don’t do that here, you are still setting the properties of objects after parenting them, which still invites that performance loss. You ideally only want to parent when everything is set up.

With the way you’re using the pcall, you aren’t utilising the full benefits of it. A pcall is meant to run a function in protected mode and catch any errors thrown by it. It returns two values: whether the function successfully ran or not and any returned values. You should make good use of those values as if there is a problem (e.g. DataStore outage), not only can you handle that case but report on it as well so you’re actually aware there is a problem.

Continuing on with the above, if the pcall throws an error, it will return an error message. As you do not check for the success value, the code below will throw an error because you’ll be attempting to set the value of a ValueObject to a string when it is expecting a number. You need to handle that case. Just because they don’t return anything, doesn’t mean they’re new players.

Incorporating all this feedback together, here’s what you can expect your code to look like:

local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")

local DataStore = DataStoreService:GetDataStore("TestDataStore")

local CURRENCY_NAME = "Coins"

-- It would be good to incorporate retrying as well, or a failure redundancy
-- method that calls UpdateAsync over SetAsync for failed saves.
local dataErrorFor = table.create(Players.MaxPlayers)

local function playerAdded(player)
    local playerKey = CURRENCY_NAME .. player.UserId

    local folder = Instance.new("Folder")
    folder.Name = "leaderstats"
    local currency = Instance.new("IntValue")
    currency.Name = CURRENCY_NAME

    local success, ret = pcall(function ()
        return DataStore:GetAsync(playerKey)
    end)

    if success then
        print("DataStore fetched successfully")
        if ret then
            print("Data found, setting to value")
            currency.Value = ret
        else
            warn("No data in successful fetch, new data created")
            currency.Value = 1000
        end
    else
        warn("Unsuccessful fetch for userId=" .. player.UserId)
        dataErrorFor[player.UserId] = true
        currency.Value = 1000
    end

    currency.Parent = folder
    folder.Parent = player
end

local function playerRemoving(player)
    if not dataErrorFor[player.UserId] then
        local playerKey = CURRENCY_NAME .. "-" .. player.UserId
        local currency = player.leaderstats[CURRENCY_NAME]

        DataStore:SetAsync(playerKey, currency.Value)
    else
        -- To avoid data loss and overwriting with false data, we do not save
        -- for players who had a fetch error. Look to incorporating a
        -- retry or rebounding system.
        warn("Data not saved for userId=" .. player.UserId)
    end
    -- Ensure player key gets removed from our tracker table
    dataErrorFor[player.UserId] = nil
end

-- Consider writing a saving function to call on all players instead, kicking
-- them doesn't guarantee PlayerRemoving will fire. I'll leave this unchanged.
local function onClose()
    for _, player in ipairs(Players:GetPlayers()) do
        player:Kick("Game update")
    end

    -- IIRC wait will not stall server closure because at this point, there are
    -- no other scheduled tasks, meaning the server can now close.
    wait(5)
end

Players.PlayerAdded:Connect(playerAdded)
Players.PlayerRemoving:Connect(playerRemoving)
game:BindToClose(onClose)

for _, player in ipairs(Players:GetPlayers()) do
    playerAdded(player)
end
2 Likes

didnt he just can do like i said here? @colbert2677

My fixes are independent of yours, I’m not quite sure what kind of response you’re looking for by raising yours to me. If you want me to review it though, I can: and it’s not a good fix. Your second one is though, but it could use some improvements.

Please don’t ever suggest to someone, without strong basis, that they should change from an event-driven system to loops. If there’s already an event provided to you to connect to in order to trigger an event, you shouldn’t use a loop. While wait is also bad practice.

The issue isn’t that the coins value is changing ahead of time. Changed internally will only fire after a property is set. For ValueObjects, their Changed event is specially designed to fire with the new value since their only special property is Value, the rest hailing from the root instance.

Having an initial state is probably the issue here, but again, I have a lot of other feedback than just this one LocalScript. That could very well be the problem though, but in that case you might want to use an actual function to avoid code redundancy, like so:

local LocalPlayer = game:GetService("Players").LocalPlayer

local leaderstats = LocalPlayer:WaitForChild("leaderstats")
local coins = leaderstats:WaitForChild("Coins")

local function updateCurrencyUI(newValue)
    script.Parent.Text = tostring(newValue) .. "$"
end

coins.Changed:Connect(updateCurrencyUI)

updateCurrencyUI()
5 Likes

I don’t find what’s wrong, i’m gonna make again the whole script.

I’m not quite sure but when creating your leaderstats, you used an IntValue, which has a property named “Value”. When detecting the change, you should be detecting it in the value.

So, your code would look a bit like this:

game.Players.LocalPlayer.leaderstats.Coins.Value.Changed:connect(function()
    script.Parent.Text = game.Players.LocalPlayer.leaderstats.Coins.Value .."$"
end)

Maybe make sure your text is visible (there is a Visible property) and also make sure the textColor3 is not the same as the background color 3. Also, Z Index is a property that determines the z index of a GUI object, so try increasing that to see if it is hidden behind the other GUI. There is also a text transparency property, make sure that is set to 1

I might be going insane but in between the Value and the “…” is there a space?
But try the something like this \ /

local player = game.Players.LocalPlayer
local cash = player:WaitForChild("leaderstats").Cash
local TextBox = script.Parent.TextBox

TextBox.Text = cash.Value..$


silver.Changed:Connect(function()
	TextBox.Text = cash.Value.."$"
end)

What is “silver” ?

30characters

Oops. That is part of my currency, I forget to edit that to cash. Lol

1 Like

So in order the leaderboard have to start before the cash value gui ? Am i correct ??