Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

How to save that stats of player??

It doens't save, I don't know how to fix, there is a major problem with this...

local datastore = game:GetService("DataStoreService")
local CashData = datastore:GetDataStore("CashSavingSystem")
local InBucketData = datastore:GetDataStore("InBucketSavingSystem")

game.Players.PlayerAdded:Connect(function(plr)
	local folder = Instance.new("Folder", plr)
	folder.Name = "leaderstats"
	local cd = Instance.new("IntValue", folder)
	cd.Name = "Cash"
	cd.Value = CashData:GetAsync(plr.userId) or 0
	local ib = Instance.new("IntValue", folder)
	ib.Name = "InBucket"
	ib.Value = InBucketData:GetAsync(plr.userId) or 0
	CashData:SetAsync(plr.userId, cd.Value)
	InBucketData:SetAsync(plr.userId, ib.Value)
	
	cd.Changed:connect(function()
		CashData:SetAsync(plr.userId, cd.Value)
	end)
	ib.Changed:connect(function()
		InBucketData:SetAsync(plr.userId, ib.Value)
	end)
end)

3 comments

0

Is API on?

0

Yes, API is on.

0

Don't save to the DataStore every time 'cd' or 'ib' changes. You will exceed data store limits this way. Instead, save at important points like when the player leaves: https://developer.roblox.com/articles/Datastore-Errors

2 answers

✓ Accepted answer

Most developers have troubles saving player stats to DataStore. To properly save data, you must know that there are limits to how much data the server can store per n number of minutes. Visit this link to view more about DataStore limits.

To start off, here's a simple example of saving and loading player stats.

local DataStoreService = game:GetService('DataStoreService')
local DataStore = DataStoreService:GetDataStore('TestDataStore')

local function onPlayerAdded(player)
	local leaderstats = Instance.new('Folder', player)
	leaderstats.Name = 'leaderstats'

	local cash = Instance.new('IntValue', leaderstats)
	cash.Name = 'Cash'

	local playerData = DataStore:GetAsync(player.UserId) --getting players' data; nil if no data
	if not playerData then
		cash.Value = 50 --initial player cash
	else
		cash.Value = playerData
	end
end

local function onPlayerRemoving(player)
	DataStore:SetAsync(player.UserId, player.leaderstats['Cash'].Value)
end

game.Players.PlayerAdded:Connect(onPlayerAdded)
game.Players.PlayerRemoving:Connect(onPlayerRemoving)

Data should be saved when the player leaves, constantly storing data could result in data loss or error. DataStore functions should also be wrapped inside pcall. View this link for more information on pcall.

1 comment

0

To ensure data is saved put an BindToClose evnt

The problem is that player.userId contains a read only integer while data store requires strings for its arguments. Try replacing replacing it with tostring(plr.userId)

So like this

local datastore = game:GetService("DataStoreService")
local CashData = datastore:GetDataStore("CashSavingSystem")
local InBucketData = datastore:GetDataStore("InBucketSavingSystem")

game.Players.PlayerAdded:Connect(function(plr)
    local folder = Instance.new("Folder", plr)
    folder.Name = "leaderstats"
    local cd = Instance.new("IntValue", folder)
    cd.Name = "Cash"
    cd.Value = CashData:GetAsync(tostring(plr.userId)) or 0
    local ib = Instance.new("IntValue", folder)
    ib.Name = "InBucket"
    ib.Value = InBucketData:GetAsync(tostring(plr.userId)) or 0
    CashData:SetAsync(tostring(plr.userId), cd.Value)
    InBucketData:SetAsync(tostring(plr.userId), ib.Value)

    cd.Changed:connect(function()
        CashData:SetAsync(tostring(plr.userId), cd.Value)
    end)
    ib.Changed:connect(function()
        InBucketData:SetAsync(tostring(plr.userId), ib.Value)
    end)
end)

A little side note to, you shouldn't save every time the players money changes but instead save when the player leaves as its much more efficient. So something like this:


local datastore = game:GetService("DataStoreService")
local CashData = datastore:GetDataStore("CashSavingSystem")
local InBucketData = datastore:GetDataStore("InBucketSavingSystem")

game.Players.PlayerAdded:Connect(function(plr)
    local folder = Instance.new("Folder", plr)
    folder.Name = "leaderstats"
    local cd = Instance.new("IntValue", folder)
    cd.Name = "Cash"
    cd.Value = CashData:GetAsync(tostring(plr.userId)) or 0
    local ib = Instance.new("IntValue", folder)
    ib.Name = "InBucket"
    ib.Value = InBucketData:GetAsync(tostring(plr.userId)) or 0
    CashData:SetAsync(tostring(plr.userId), cd.Value)
    InBucketData:SetAsync(tostring(plr.userId), ib.Value)

    game.Players.PlayerRemoving:Connect(function()
	CashData:SetAsync(tostring(plr.userId), cd.Value)
	InBucketData:SetAsync(tostring(plr.userId), ib.Value)
    end)
end)

2 comments

1

You should always use the UserId of the player and never the name. This is because Names of players are able to change.

0

Noted and fixed

This discussion is preserved as it was. New answers, comments, and votes are closed.