Datastores saving issues

Hello! I’m currently making a game that saves heavy amounts of data. How I have it set up, is that when the player leaves save the load of data. Currently i have 3 seperate player removing scripts that detect when the player leaves then saves data. For 2 of the 3 saving data events. one saves a table of 34 values whilst the other saves a dictionary of 34 values.

on the remaining data saving script it saves a large string of data pertaining 14 different Int values.

I’m having issues, as sometimes the data doesn’t save. Should i try to make data saving scripts that contain large amounts of information but less requests, or should I make many requests with small amounts of info?

I wish I could save more data but Roblox is unable to provide this as a feature. Even with their billions…

What should i do as an alternative?
Is 3 removing player events too many or do those 3 removing player event contain too much information?


image

Getting many data errors when i try to run the game (NOT WHEN I TRY TO LEAVE)

2 Likes

This has nothing to do with the script. Its a Roblox issue…

1 Like

Even when it works, It still sometimes doesn’t save certain information (It doesn’t save coins/gems if you join, buy something, then leave but saves the information you own the item which lets players get free items from the shop)

1 Like

are you using bindtoclose?
char limit-----

1 Like

Also please note there are 3 scripts all getting information from datastores

1 Like

If you’re going to create a post under scripting support you should probably post the code, just a thought.

2 Likes

I don’t know what bindtoclose is or anything about datastores. I read the article on datastores and i followed it.

1 Like
local screen = nil
local Datastores = game:GetService("DataStoreService")
local ExperienceStorage = Datastores:GetDataStore("PlayerExperience")


local function setdata(name, plr, value)
	ExperienceStorage:SetAsync(plr.Name .. name, value)
end

local function getdata(name, plr)
	local HI = ExperienceStorage:GetAsync(plr.Name .. name)
	if HI == nil then
		HI = "0,0,0,0,0,0,0,0,0,0,0,1,0,0"
	end
	return HI
end

game.Players.PlayerAdded:Connect(function(plr)
	repeat wait(0.1) until plr.PlayerGui:FindFirstChild("ScreenGui") 
	repeat wait(0.1) until plr.PlayerGui.ScreenGui:FindFirstChild("Small") and plr.PlayerGui.ScreenGui:FindFirstChild("Mid") and plr.PlayerGui.ScreenGui:FindFirstChild("Long") and plr.PlayerGui.ScreenGui:FindFirstChild("Coins") and plr.PlayerGui.ScreenGui:FindFirstChild("Gems") and plr.PlayerGui.ScreenGui:FindFirstChild("Progress") and plr.PlayerGui.ScreenGui:FindFirstChild("Lv")

	screen = plr.PlayerGui.ScreenGui
	
	
	ShortValue = screen.Small
	MidValue = screen.Mid
	LongValue = screen.Long
	WallpaperValue = screen.Wallpaper
	CrosshairValue = screen.Crosshair
	ShortMovingValue = screen.SmallMoving
	MidMovingValue = screen.MidMoving
	LongMovingValue = screen.LongMoving
	CoinsValue = screen.Coins
	GemsValue = screen.Gems
	LVValue = screen.Lv
	Lv_Boost = screen.Lv_Boost
	Coin_Boost = screen.Coin_Boost
	ProgressValue = screen.Progress
	
	local Data = getdata("Data", plr)
	local Decifered = string.split(Data,",")
	
	
	screen.Small.Value = Decifered[1]
	
	screen.Mid.Value = Decifered[2]
	
	screen.Long.Value = Decifered[3]
	
	screen.SmallMoving.Value = Decifered[4]
	
	screen.MidMoving.Value = Decifered[5]
	
	screen.LongMoving.Value = Decifered[6]
	
	screen.Wallpaper.Value = Decifered[7]
	
	screen.Crosshair.Value = Decifered[8]
	
	screen.Coins.Value = Decifered[9]
	
	screen.Gems.Value = Decifered[10]
	
	screen.Progress.Value = Decifered[11]
	
	screen.Lv.Value = Decifered[12]
	
	screen.Lv_Boost.Value = Decifered[13]
	
	screen.Coin_Boost.Value = Decifered[14]
	
end)

game.Players.PlayerRemoving:Connect(function(plr)
	setdata("Data",plr,ShortValue.Value..","..MidValue.Value..","..LongValue.Value..","..ShortMovingValue.Value..","..MidMovingValue.Value..","..LongMovingValue.Value..","..WallpaperValue.Value..","..CrosshairValue.Value..","..CoinsValue.Value..","..GemsValue.Value..","..ProgressValue.Value..","..LVValue.Value..","..Lv_Boost.Value..","..Coin_Boost.Value)
end)

This is the code to my most bulky datasaving script
(i have 2 other scripts that saves a table/dictonary)

1 Like

So when in studio and closing the server you were on you cant use a simple player removing because the server is removing before the player scripts can run so you have to use bind to close to bind a save all data function but all players data is deleted by then so you have to simutaniously store all their data in tables inside the script so that when a player leaves and the server closes it still has the data to set

i can explain better if needed

image
shutdown server is a function

1 Like

also i would not suggest storing players data by their name because a name can change a userid cannot

1 Like

Is the way I’m doing it good? do you suggest a different way? if so what should i do>?

1 Like

I am restructuring you code rn but in the meantime i would also suggest dont store all data in a string store it in a table or dictionary

1 Like

ok this should work and fix all your problems, if something dosent work tell me

local Datastores = game:GetService("DataStoreService")

local ExperienceStorage = Datastores:GetDataStore("PlayerExperience")

local ServerActive = true

local PlayerData = {}

local function setdata(Player, DataName, Val)

PlayerData[Player.UserId..DataName] = Val

ExperienceStorage:SetAsync(Player.UserId..DataName, Val)

end

local function getdata(Player, DataName)

local HI = ExperienceStorage:GetAsync(Player.UserId..DataName)

if not HI then HI = {0,0,0,0,0,0,0,0,0,0,0,1,0,0} end

return HI

end

game.Players.PlayerAdded:Connect(function(Player)

repeat wait() until Player.PlayerGui:FindFirstChild("ScreenGui")

local ScreenGui = Player.PlayerGui:FindFirstChild("ScreenGui")

repeat wait() until ScreenGui:FindFirstChild("Small") and ScreenGui:FindFirstChild("Mid") and ScreenGui:FindFirstChild("Long") and ScreenGui:FindFirstChild("Coins") and ScreenGui:FindFirstChild("Gems") and ScreenGui:FindFirstChild("Progress") and ScreenGui:FindFirstChild("Lv")

local Data = getdata(Player, 'Data')

ScreenGui.Small.Value = Data[1]

ScreenGui.Mid.Value = Data[2]

ScreenGui.Long.Value = Data[3]

ScreenGui.SmallMoving.Value = Data[4]

ScreenGui.MidMoving.Value = Data[5]

ScreenGui.LongMoving.Value = Data[6]

ScreenGui.Wallpaper.Value = Data[7]

ScreenGui.Crosshair.Value = Data[8]

ScreenGui.Coins.Value = Data[9]

ScreenGui.Gems.Value = Data[10]

ScreenGui.Progress.Value = Data[11]

ScreenGui.Lv.Value = Data[12]

ScreenGui.Lv_Boost.Value = Data[13]

ScreenGui.Coin_Boost.Value = Data[14]

end)

game.Players.PlayerRemoving:Connect(function(Player)

wait(0.1)

if ServerActive then setdata(Player, 'Data', PlayerData[Player.UserId]) end

end)

game:BindToClose(function()

ServerActive = false

for Key, PlayerData in pairs(PlayerData) do

ExperienceStorage:SetAsync(Key, PlayerData)

end

end)

Sorry for all the weird formmating roblox did it

1 Like

i have 2 other datastore scripts that save a table and a dictionary. Since that information is accessible even after the player leaves to the server, is that fine?

1 Like

yep all you gotta do is get the data and it comes out in a table automatically and just use that

you can use the same method of saving as i did to save other things aswell

1 Like

Hey i just tested the code and it doesnt appear to have saved the information. I changed the coins value on the server then rejoined the game and the coins value went to 0. I tested this multiple times and results did not vary.

1 Like

Do you know why your code did not work?

edit: after some debugging i found out when the player joins the game it doesn’t find the players data with your method and goes to the nil check which resets all the stats

image

1 Like

no thats not how it works it will print that no matter what
Look how that line is structured the whole if statement is on 1 line

1 Like

i fixed the code to be inside the if statment and it still prints

1 Like

also the script works for me just set it up, try making sure all of the values that are set on playeradded are there bc if even 1 of them is missing or not named correctly it will stop itself

1 Like