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

Why does this data saving script not work at all?

This script is supposed to create and save a subset of player stats that is supposed to be saved and loaded upon the player joining and leaving respectively.

When I increase/change one of the data points and leave and rejoin, the data does not load. This script is currently being tested on a private game, if that matters at all.

What is the issue with it? Output gave me nothing to work with.

local DataStores = game:GetService("DataStoreService")
local PlayersDataStore = DataStores:GetDataStore("Players")
local FindValues = {
"Rank","XP","Prestige","Heists";
--Add any new variable!
}
local TypeValues = {
	Rank = "IntValue"; --Or int whatever is fine...
	XP = "IntValue";
	Prestige = "IntValue";
	Heists = "IntValue";
}

function SetupPlayer(Player)
local LeaderStats = Instance.new("Folder",Player)
LeaderStats.Name = "perm"
local ValueObjects = {}
for i,v in pairs(FindValues)do
	local VALUE = Instance.new(TypeValues[v] or "StringValue",LeaderStats)
	VALUE.Name = v
	ValueObjects[i] = VALUE
end

local LeaderTable = {}
local PlayerDS = PlayersDataStore:GetAsync(Player.UserId)

if not PlayerDS then --For new players!
	local SetTable = {}
	for i,v in pairs(ValueObjects)do
		SetTable[FindValues[i]] = v.Value
	end
	PlayersDataStore:SetAsync(Player.UserId,SetTable)
	PlayerDS = PlayersDataStore:GetAsync(Player.UserId)
end

for i,v in pairs(ValueObjects)do
	v.Value = LeaderTable[FindValues[i]]
end

PlayersDataStore:SetAsync(Player.UserId,PlayerDS)

spawn(function()
	while wait(10)do --Autosave
		for i,v in pairs(ValueObjects)do
		PlayerDS[FindValues[i]] = v.Value
	end
	PlayersDataStore:SetAsync(Player.UserId,PlayerDS)
	end
	end)
end

game.Players.PlayerAdded:connect(SetupPlayer)

1 answer

✓ Accepted answer

There are a few issues with your script:

1) It is difficult to read, create separate functions for each task so it can be more organized (save and load data function).

2) The tables are unnecessary and it was hard to understand it. I suggest to create a variable for each value. It'll be more organized and efficient.

3) 'connect' is deprecated, use 'Connect' instead.

4) DO NOT set the parent in the Instance.new parameters. It's a faster way but it was proved that it can slow down the script.

local Players = game:GetService("Players")
local DataStores = game:GetService("DataStoreService")
local PlayersDataStore = DataStores:GetDataStore("Players")

local function SavePlayerData(Player)
	if Player then 
		local Leaderstats = Player:FindFirstChild("perm")
		if Leaderstats then 
			local XPValue, RankValue, HeistsValue, PrestigeValue
			XPValue = Leaderstats:FindFirstChild("XP")
			RankValue = Leaderstats:FindFirstChild("Rank")
			HeistsValue = Leaderstats:FindFirstChild("Heists")
			PrestigeValue = Leaderstats:FindFirstChild("Prestige")
			if XPValue and RankValue and HeistsValue and PrestigeValue then 
				local PlayerDS = PlayersDataStore:GetAsync(Player.UserId)
				if PlayerDS then 
					local SavingTable = {
						["XP"] = XPValue.Value,
						["Rank"] = RankValue.Value,
						["Heists"] = HeistsValue.Value,
						["Prestige"] = PrestigeValue.Value
					}
					print("saved " .. Player.Name .. "'s leaderstats")
					PlayerDataStore:SetAsync(Player.UserId, SavingTable)
				end
			end
		end
	end
end

local function LoadPlayerData(Player, XPValue, RankValue, HeistsValue, PrestigeValue)
	if Player then 
		local PlayerDS = PlayersDataStore:GetAsync(Player.UserId) -- this will return the 'SavingTable'
		if PlayerDS then 
			XPValue.Value = PlayerDS.XP
			RankValue.Value = PlayerDS.Rank
			HeistsValue.Value = PlayerDS.Heists
			PrestigeValue.Value = PlayerDS.Prestige
			print("loaded " .. Player.Name .. "'s leaderstats")
		else
			print("new player")
			PlayerDataStore:SetAsync(Player.UserId, nil)
		end
	end
end

local function SetupPlayer(Player)
	--create leaderstats folder
	local Leaderstats = Instance.new("Folder")
	Leaderstats.Name = "perm"
	Leaderstats.Parent = Player

	--create value function
	local function createNewValue(valueName)
		local newValue = Instance.new("IntValue")
		newValue.Name = valueName
		newValue.Parent = Leaderstats
		return newValue
	end

	--create values
	local XPValue, RankValue, HeistsValue, PrestigeValue

	XPValue = createNewValue("XP")
	RankValue = createNewValue("Rank")
	HeistsValue = createNewValue("Heists")
	PrestigeValue = createNewValue("Prestige")
	
	--load data
	LoadPlayerData(Player, XPValue, RankValue, HeistsValue, PrestigeValue)

	--autosaving
	spawn(function()
		while Player do 
			wait(10)
			if Player then 
				SavePlayerData(Player)
			end
		end
	end)
end

Players.PlayerAdded:Connect(SetupPlayer)

6 comments

0

Don't forget to add a PlayerRemoving event so you can save players data when they leave the game.

0

Make sure studio access to API services is enabled as well

0

PlayerDataStore:SetAsync(Player.UserId, SavingTable) is undefined in the script?

0

They're in lines 24 42

0

Instead of SetAsync to update a player's data who already has data and isn't new, shouldn't you use UpdateAsync?

0

Yes but they both have the same function

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