Why does my Cash leaderstat refund?

In Roblox Studio I made an emote system and when I buy an emote and leave after and join again I still have the emote but my Cash that I payed is getting refunded which means I get it back altho I shouldn’t

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

local gui = script.Parent
local emoteFrame = gui:WaitForChild("EmotesFrame"):WaitForChild("EmoteFrame")
local template = emoteFrame:WaitForChild("EmoteButtonTemplate")
local playButton = gui:WaitForChild("PlayButton")

local purchased = {}
local selectedAnimationId = nil
playButton.Visible = false

-- Emotes setup (add more by just adding lines like below)
local emotes = {
	{Name = "Dance", Color = Color3.fromRGB(255, 200, 0), Price = 100, AnimationId = "rbxassetid://12345678", Image = "rbxassetid://11223344"},
	{Name = "Danc", Color = Color3.fromRGB(255, 200, 0), Price = 100, AnimationId = "rbxassetid://12345678", Image = "rbxassetid://11223344"},
	{Name = "Dan", Color = Color3.fromRGB(255, 200, 0), Price = 100, AnimationId = "rbxassetid://12345678", Image = "rbxassetid://11223344"},
	{Name = "Da", Color = Color3.fromRGB(255, 200, 0), Price = 100, AnimationId = "rbxassetid://12345678", Image = "rbxassetid://11223344"},
	{Name = "D", Color = Color3.fromRGB(255, 200, 0), Price = 100, AnimationId = "rbxassetid://12345678", Image = "rbxassetid://11223344"},
	{Name = "Brade", Color = Color3.fromRGB(255, 200, 0), Price = 100, AnimationId = "rbxassetid://12345678", Image = "rbxassetid://11223344"},
	{Name = "Brad", Color = Color3.fromRGB(255, 200, 0), Price = 100, AnimationId = "rbxassetid://12345678", Image = "rbxassetid://11223344"},
	{Name = "Bra", Color = Color3.fromRGB(255, 200, 0), Price = 100, AnimationId = "rbxassetid://12345678", Image = "rbxassetid://11223344"},
	{Name = "Br", Color = Color3.fromRGB(255, 200, 0), Price = 100, AnimationId = "rbxassetid://12345678", Image = "rbxassetid://11223344"},
	{Name = "B", Color = Color3.fromRGB(255, 200, 0), Price = 100, AnimationId = "rbxassetid://12345678", Image = "rbxassetid://11223344"},
}

-- Request owned emotes from the server
local success, result = pcall(function()
	return player:WaitForChild("GetEmotes"):InvokeServer()
end)

if success and type(result) == "table" then
	for _, emoteName in ipairs(result) do
		purchased[emoteName] = true
	end
end

-- Create emote buttons
for _, emoteData in ipairs(emotes) do
	local newButton = template:Clone()
	newButton.Name = emoteData.Name
	newButton.Visible = true
	newButton.BackgroundColor3 = emoteData.Color

	-- Set the Text of EmoteButtonTemplate to the emote name directly
	newButton.Text = emoteData.Name  -- This directly sets the name of the emote as text of the button

	-- Set image for the emote (if ImageLabel is present in template)
	if newButton:FindFirstChild("ImageLabel") then
		newButton.ImageLabel.Image = emoteData.Image
	end

	-- Set price text or "Use"
	local priceButton = newButton:FindFirstChild("PriceButton")
	if priceButton then
		if purchased[emoteData.Name] then
			priceButton.Text = "Use"  -- If already purchased, show "Use"
		else
			priceButton.Text = "Buy: " .. emoteData.Price  -- Otherwise, show the price
		end
	else
		print("❌ Missing PriceButton in template for", emoteData.Name)
	end

	-- Price button click handler
	if priceButton then
		priceButton.MouseButton1Click:Connect(function()
			if purchased[emoteData.Name] then
				selectedAnimationId = emoteData.AnimationId
				playButton.Text = "Play " .. emoteData.Name
				playButton.Visible = true
			else
				if cash.Value >= emoteData.Price then
					cash.Value = cash.Value - emoteData.Price
					purchased[emoteData.Name] = true
					priceButton.Text = "Use"

					-- Tell the server to save this purchase and deduct cash
					game.ReplicatedStorage.EmotePurchaseEvent:FireServer(emoteData.Name, emoteData.Price)

					print("Purchased:", emoteData.Name)
				else
					warn("Not enough cash for", emoteData.Name)
				end
			end
		end)
	end

	-- Add the button to the frame
	newButton.Parent = emoteFrame
end

-- Play button logic
playButton.MouseButton1Click:Connect(function()
	if selectedAnimationId then
		local character = player.Character or player.CharacterAdded:Wait()
		local humanoid = character:WaitForChild("Humanoid")

		-- Stop all other animations (optional)
		for _, track in ipairs(humanoid:GetPlayingAnimationTracks()) do
			track:Stop()
		end

		-- Load and play the selected animation
		local anim = Instance.new("Animation")
		anim.AnimationId = selectedAnimationId

		local track = humanoid:LoadAnimation(anim)
		track:Play()
		print("Animation played:", selectedAnimationId)
	else
		warn("No emote selected.")
	end
end)










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

local cashStore = DataStoreService:GetDataStore("PlayerCash")
local emoteStore = DataStoreService:GetDataStore("PlayerEmotes")
local Remote = ReplicatedStorage:WaitForChild("EmotePurchaseEvent")
Remote.OnServerEvent:Connect(function(player, emoteName, emotePrice)
	local key = "Emotes_" .. player.UserId
	local cashKey = "Cash_" .. player.UserId

	local success, errorMessage = pcall(function()
		-- Retrieve saved emotes
		local emoteData = emoteStore:GetAsync(key) or {}

		-- If emote is not already owned, purchase it
		if not table.find(emoteData, emoteName) then
			table.insert(emoteData, emoteName)
			-- Save the updated emotes immediately
			emoteStore:SetAsync(key, emoteData)
		end

		-- Retrieve current cash
		local currentCash = cashStore:GetAsync(cashKey) or 0

		-- Deduct the emote price from cash if enough money is available
		if currentCash >= emotePrice then
			currentCash = currentCash - emotePrice
			-- Save updated cash value immediately
			cashStore:SetAsync(cashKey, currentCash)

			-- Also update the player's leaderstats to reflect the new cash
			local leaderstats = player:FindFirstChild("leaderstats")
			if leaderstats then
				local cashStat = leaderstats:FindFirstChild("Cash")
				if cashStat then
					cashStat.Value = currentCash  -- Update the player's cash value
				end
			end

		else
			warn(player.Name .. " does not have enough cash to buy " .. emoteName)
		end
	end)

	if not success then
		warn("Error purchasing emote for player " .. player.Name .. ": " .. errorMessage)
	end
end)

-- Load emotes + cash on player join
Players.PlayerAdded:Connect(function(player)
	local leaderstats = player:WaitForChild("leaderstats")
	local cash = leaderstats:WaitForChild("Cash")

	-- RemoteFunction for loading owned emotes
	local remoteFunc = Instance.new("RemoteFunction")
	remoteFunc.Name = "GetEmotes"
	remoteFunc.Parent = player

	remoteFunc.OnServerInvoke = function()
		local emotesKey = "Emotes_" .. player.UserId
		local emoteSuccess, emoteData = pcall(function()
			return emoteStore:GetAsync(emotesKey)
		end)

		if emoteSuccess then
			return emoteData or {}
		else
			warn("Failed to load emotes for player: " .. player.Name)
			return {} -- Return empty table if emote data loading fails
		end
	end
end)
possible re-write.. (test)
Players.PlayerAdded:Connect(function(player)
	local leaderstats = player:WaitForChild("leaderstats")
	local cash = leaderstats:WaitForChild("Cash")

	local cashKey = "Cash_" .. player.UserId
	local emotesKey = "Emotes_" .. player.UserId

	local success, errorMessage = pcall(function()
		local savedCash = cashStore:GetAsync(cashKey) or 0
		local emoteData = emoteStore:GetAsync(emotesKey) or {}

		cash.Value = savedCash

		local remoteFunc = Instance.new("RemoteFunction")
		remoteFunc.Name = "GetEmotes"
		remoteFunc.Parent = player

		remoteFunc.OnServerInvoke = function()
			return emoteData
		end
	end)

	if not success then
		warn("Error loading data for player " .. player.Name .. ": " .. errorMessage)
	end
end)

Remote.OnServerEvent:Connect(function(player, emoteName, emotePrice)
	local key = "Emotes_" .. player.UserId
	local cashKey = "Cash_" .. player.UserId

	local success, errorMessage = pcall(function()
		local emoteData = emoteStore:GetAsync(key) or {}

		local currentCash = cashStore:GetAsync(cashKey) or 0

		if not table.find(emoteData, emoteName) and currentCash >= emotePrice then
			table.insert(emoteData, emoteName)
			emoteStore:SetAsync(key, emoteData)

			currentCash = currentCash - emotePrice
			cashStore:SetAsync(cashKey, currentCash)

			local leaderstats = player:FindFirstChild("leaderstats")
			if leaderstats then
				local cashStat = leaderstats:FindFirstChild("Cash")
				if cashStat then
					cashStat.Value = currentCash
				end
			end
		else
			warn(player.Name .. " does not have enough cash to buy " .. emoteName)
		end
	end)

	if not success then
		warn("Error purchasing emote for player " .. player.Name .. ": " .. errorMessage)
	end
end)

Maybe because you are using a local script to remove the cash

Yeah since your doing it in a local script no cash is losed since your saving it on the server.

Also dont be offended if this was written by you but this is script is very AI like.

well I showed two scripts local and server script one and ye I used chat gpt but I mean everything works exept money saving

just ask chat gpt again if it isnt working, then

litarilly did 100 times that’s why I’m asking here I only ask if ChatGPT doesn’t make it but nvm

Yeah, but also compare ChatGPT with Microsoft’s Copilot that somehow Runs on Microsoft’s Edge Browser. I can’t see if it Works.

You’ll surely keep running into these kind of problems if you just rely on AI, learn what stuff actually does and how, regardless of using AI or not

Guys I fixed the issue yesterday can we close this category?

ok so cash come bak when u rejoin cuz u not loadin the saved cash into stats u just lettin it reset

when u buy emote it save cash and everythin good

but when u join again it dont load the saved cash so it look like u got the cash bak

u gotta load the saved cash when player join

and also save the cash again when player leave

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

local cashStore = DataStoreService:GetDataStore("PlayerCash")
local emoteStore = DataStoreService:GetDataStore("PlayerEmotes")
local Remote = ReplicatedStorage:WaitForChild("EmotePurchaseEvent")

Remote.OnServerEvent:Connect(function(player, emoteName, emotePrice)
    local key = "Emotes_" .. player.UserId
    local cashKey = "Cash_" .. player.UserId

    pcall(function()
        local emoteData = emoteStore:GetAsync(key) or {}
        if not table.find(emoteData, emoteName) then
            table.insert(emoteData, emoteName)
            emoteStore:SetAsync(key, emoteData)
        end

        local currentCash = cashStore:GetAsync(cashKey) or 0
        if currentCash >= emotePrice then
            currentCash = currentCash - emotePrice
            cashStore:SetAsync(cashKey, currentCash)

            local leaderstats = player:FindFirstChild("leaderstats")
            if leaderstats then
                local cashStat = leaderstats:FindFirstChild("Cash")
                if cashStat then
                    cashStat.Value = currentCash
                end
            end
        else
            warn(player.Name .. " does not have enough cash to buy " .. emoteName)
        end
    end)
end)

Players.PlayerAdded:Connect(function(player)
    local leaderstats = Instance.new("Folder")
    leaderstats.Name = "leaderstats"
    leaderstats.Parent = player

    local cash = Instance.new("IntValue")
    cash.Name = "Cash"
    cash.Parent = leaderstats

    local cashKey = "Cash_" .. player.UserId
    local success, savedCash = pcall(function()
        return cashStore:GetAsync(cashKey)
    end)
    if success and savedCash then
        cash.Value = savedCash
    else
        cash.Value = 0
    end

    local remoteFunc = Instance.new("RemoteFunction")
    remoteFunc.Name = "GetEmotes"
    remoteFunc.Parent = player
    remoteFunc.OnServerInvoke = function()
        local emotesKey = "Emotes_" .. player.UserId
        local ok, emoteData = pcall(function()
            return emoteStore:GetAsync(emotesKey)
        end)
        return (ok and emoteData) or {}
    end
end)

Players.PlayerRemoving:Connect(function(player)
    local leaderstats = player:FindFirstChild("leaderstats")
    if leaderstats then
        local cashStat = leaderstats:FindFirstChild("Cash")
        if cashStat then
            local cashKey = "Cash_" .. player.UserId
            pcall(function()
                cashStore:SetAsync(cashKey, cashStat.Value)
            end)
        end
    end
end)

he fixed it mate.

chararestriction

Oh i sort the topics as new how that was yesterday

1 Like