Need help with saving with datastore

Hi so while back i was trying to make a shop for my game, and it works perfectly, but the data saving dose not work. The game wont save how much money i have after i purchase something, or if i even purcchase anything.I think i need to use an event but i dont know how-- if anyone knew how to do it and could try to help. I have 2 scripts currently–

This is my data store in server script service

local datastore = game:GetService("DataStoreService")
local ds1 = datastore:GetDataStore("MoneySaveSystem")

game.Players.PlayerAdded:connect(function(plr)
	local folder = Instance.new("Folder", plr)
	folder.Name = "leaderstats"
	local money = Instance.new("IntValue", folder)
	money.Name = "Money"

	money.Value = ds1:GetAsync(plr.UserId) or 0
	ds1:SetAsync(plr.UserId, money.Value)

	money.Changed:connect(function()
		ds1:SetAsync(plr.UserId, money.Value)
	end)

end)

This is the script in the button you click to buy

local item = script.Parent
local Shoes = script.Parent.Parent.Parent.Frame1.Shoes  
local value = 40000 

item.MouseButton1Click:Connect(function()
	if game.Players.LocalPlayer.leaderstats.Money.Value >= value then
		game.Players.LocalPlayer.leaderstats.Money.Value = game.Players.LocalPlayer.leaderstats.Money.Value - value
		item.Text = "purchased"
		Shoes.Visible = true
		value = 0
		
	else
		item.Text = "not purchased"
		wait(1)
		item.Text = "Purchase"
	
			value = 0
			Shoes.Visible = true
		end
		
	
end)

(i posted something similar to this a while back)

2 Likes

You need to send an event to the server to check if the player has enough coins and how much you want to take of them.

So to do this you would create a RemoteEvent in ReplicatedStorage and call it Purchase or something along those lines next you need to define where the event is located in both scripts like this:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local PurchaseEvent = ReplicatedStorage:WaitForChild("Purchase") -- Event name

Once that is in both scripts we will first work on the client script which is checks whether the Item has been pressed:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local PurchaseEvent = ReplicatedStorage:WaitForChild("Purchase") 

item.MouseButton1Click:Connect(function()
   PurchaseEvent:Fire(itemName) -- Send the items name
end)

That should be it for the client, now for the server.

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local PurchaseEvent = ReplicatedStorage:WaitForChild("Purchase") 

local ShopItems = {
   [itemName] = 100, -- Store the item name here and the cost
}


PurchaseEvent.OnServerEvent:Connect(function(player : Player, itemName: String) 
   local PlayersMoney = player.leaderstats.Money
   if PlayersMoney Value >= ShopItems[itemName] then
      PlayersMoney.Value -= ShopItems[itemName]
      -- You can then fire a remote back to update Gui
   else
      print(player.Name.." doesn't have enough money!")
   end
end

It may look a bit confusing but you should always update a players data on the server since a client can manipulate their data and give themselves money, etc. Hope this helps.

Is there any way to make the local script do the remote event then just do somehting in a server script service? idk but im pretty sure that would work better with how my stuff is set up

(idk if that makes sense)
Like i would just put what currently my local script dose in the serve

Dose that make sense becasue i now what like with the event thingy

If you want it to all be handled in server it wouldn’t be good, just use the server to run checks and make sure everything is running alright. Any gameplay like UI interactions etc should be run on client.

--LOCAL SCRIPT--
local storage = game:GetService("ReplicatedStorage")
local re = storage.RemoteEvent
local players = game:GetService("Players")
local player = players.LocalPlayer or players.PlayerAdded:Wait()
local item = script.Parent
local shoes = script.Parent.Parent.Parent.Frame1.Shoes  
local value = 40000

item.MouseButton1Click:Connect(function()
	if player.leaderstats.Money.Value >= value then
		re:FireServer(value)
		item.Text = "Successfully purchased!"
		shoes.Visible = true
		value = 0
	else
		item.Text = "Unsuccessful purchase!"
		task.wait(2)
		item.Text = "Purchase!"
	end
end)
--SERVER SCRIPT--
local storage = game:GetService("ReplicatedStorage")
local re = storage.RemoteEvent
local datastore = game:GetService("DataStoreService")
local ds1 = datastore:GetDataStore("MoneySaveSystem")
local players = game:GetService("Players")

re.OnServerEvent:Connect(function(player, value)
	if player.leaderstats.Money.Value >= value then
		player.leaderstats.Money.Value -= value
	else
		player:Kick("Do not exploit.")
	end
end)

players.PlayerAdded:Connect(function(plr)
	local folder = Instance.new("Folder")
	folder.Name = "leaderstats"
	folder.Parent = plr
	
	local money = Instance.new("IntValue")
	money.Name = "Money"
	money.Value = 0
	money.Parent = plr

	money.Value = ds1:GetAsync(plr.UserId) or 0
	ds1:SetAsync(plr.UserId, money.Value)

	money.Changed:Connect(function()
		ds1:SetAsync(plr.UserId, money.Value)
	end)
end)

I’ve made a few slight changes and introduced the use of a “RemoteEvent” instance that way the stats are handled on the server (if you change the “Money” stat from a local script then that change won’t replicate across the entire server).

This is the organisation:

image

Place the local script named “LocalScript” inside the Gui where it was before.

What do i name the Event? in replicated

just RemoteEvent? -------------

Exactly as I have in the screenshot, yes.

I put the local script inside of my button not just inside the screen gui ,correct? or

Wherever you had it placed before.

If I want the script to be inside of the button, could i change this line of code

local shoes = script.Parent.Parent.Parent.Frame1.Shoes  

to this?

local shoes = script.Parent
WAIT thats something else
nvm

local shoes = script.Parent.Shoes
If the script and the shoes are inside the button.

for some reasons when i press my button it dose nothing.
Is this set up right
image–shoes is the buy button

The shoes are supposed to go inside the purchase button with the script.

image

Like this.

local item = script.Parent
local shoes = script.Parent.Parent.Parent.Frame1.Shoes

“Item” is the purchase button (the parent the script is placed inside of).
“Shoes” place this inside the purchase button with the script.

For some reason it dosent take away my money or save anyhting still. the output says nothing which isnt very helpful

I see the issue, you forgot to parent “Cash” to the leaderstats folder.

--SERVER SCRIPT--
local storage = game:GetService("ReplicatedStorage")
local re = storage.RemoteEvent
local datastore = game:GetService("DataStoreService")
local ds1 = datastore:GetDataStore("MoneySaveSystem")
local players = game:GetService("Players")

re.OnServerEvent:Connect(function(player, value)
	if player.leaderstats.Money.Value >= value then
		player.leaderstats.Money.Value -= value
	else
		player:Kick("Do not exploit.")
	end
end)

players.PlayerAdded:Connect(function(plr)
	local folder = Instance.new("Folder")
	folder.Name = "leaderstats"
	folder.Parent = plr

	local money = Instance.new("IntValue")
	money.Name = "Money"
	money.Value = 0
	money.Parent = folder

	money.Value = ds1:GetAsync(plr.UserId) or 0
	ds1:SetAsync(plr.UserId, money.Value)

	money.Changed:Connect(function()
		ds1:SetAsync(plr.UserId, money.Value)
	end)
end)

Here, this should fix everything.