Help me make datasave script

help me create a datasave script or tag the tutorial that worked for you recently

  1. What do you want to achieve?
    i wanted to make a datasave script that is compatible with my script :
local datastore = game:GetService("DataStoreService")
local mainDSC = datastore:GetDataStore("CoinsData")
local mainDSM = datastore:GetDataStore("MeteoriteData")
local replicatedstorage = game:GetService("ReplicatedStorage")
local events = replicatedstorage:FindFirstChild("DSEvents")

game.Players.PlayerAdded:connect(function(player)
   
   local folder1 = Instance.new("Folder", player)
   folder1.Name = "leaderstats"

   local folder2 = Instance.new("Folder", player)
   folder2.Name = "stats"

   local money1 = Instance.new("NumberValue", folder2)
   money1.Name = "Coins"

   local money2 = Instance.new("NumberValue", folder2)
   money2.Name = "Gems"
   
   local CData = mainDSC:GetAsync(player.UserId)
   local MData = mainDSM:GetAsync(player.UserId)
   
   if CData then
   	if CData[1] then
   		money1.Value = CData[1]
   	end
   end
   
   if MData then
   	if MData[1] then
   		money2.Value = MData[1]
   	end
   end
end)
  1. What is the issue?
    i seems to cant figure out how to use datasave script

  2. What solutions have you tried so far?
    i have followed 3 tutorials and a lot of other posts, and i came out empty handed, nothing seems to work.

  3. Additional Information
    i have enabled HTTp requests and API services
    Screenshot 2024-01-10 173326

if i didn’t respond within 1-2 hours, its either im in school, sleeping or just playing games
all help will be appreciated :grin:

1 Like

Try this:

local datastore = game:GetService("DataStoreService")
local mainDSC = datastore:GetDataStore("CoinsData")
local mainDSM = datastore:GetDataStore("MeteoriteData")
local replicatedstorage = game:GetService("ReplicatedStorage")
local events = replicatedstorage:FindFirstChild("DSEvents")

game.Players.PlayerAdded:connect(function(player)
	local folder1 = Instance.new("Folder", player)
	folder1.Name = "leaderstats"

	local folder2 = Instance.new("Folder", player)
	folder2.Name = "stats"

	local money1 = Instance.new("NumberValue", folder2)
	money1.Name = "Coins"

	local money2 = Instance.new("NumberValue", folder2)
	money2.Name = "Gems"

	local succ1, CData = pcall(function() --PCall if Error happens
		return mainDSC:GetAsync(player.UserId) --Returning CData with provided UserID as key
	end)
	
	local succ2, MData = pcall(function() --PCall if Error happens
		return mainDSM:GetAsync(player.UserId) --Returning MData with provided UserID as key
	end)

	if succ1 and CData ~= nil then --succ1 = success so if GetAsync worked fine. CData will be nil if no data for the player is saved
		if CData[1] then
			money1.Value = CData[1]
		end
	end

	if succ2 and MData ~= nil then --succ2 = success so if GetAsync worked fine. MData will be nil if no data for the player is saved
		if MData[1] then
			money2.Value = MData[1]
		end
	end
end)
1 Like

Okay

Sjhdhsisgayajnabwldidhabsvrhnrndmd.dndksudhr

1 Like

sorry for the late reply, i was pretty busy with school assignments today.

it doesent seem to work, and it doesent show any error massages.
can you explain a bit more about this script? or maybe, it only works in roblox and not studio?

thanks :grin:

So it should work in studio as also ingame. Try these things:

  1. Add a task.wait(1) directly after the game.PlayersAdded function.
  2. Add some print statements and look until where the script runs or if it even runs.
  3. Where is your script located and are there anymore events and functions above the playeradded function?
1 Like

my script is located in a folder called other scripts in server script service. it is a server script. and no, there is no more events and functions in this script.

1 Like

I’ll show you a working example that you can use if you want, and also learn from it on how to change your script if you prefer:

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

local dataStore = DataStoreService:GetDataStore("PlayerData") -- You can rename this if you want

Players.PlayerAdded:Connect(function(player)
	local success, values = pcall(dataStore.GetAsync, dataStore, player.UserId)

	if success then
		local leaderstats = Instance.new("Folder")
		leaderstats.Name = "leaderstats"
		leaderstats.Parent = player

		local Coins = Instance.new("IntValue")
		Coins.Name = "Coins"
		Coins.Value = values and values.Coins
		Coins.Parent = leaderstats

		local Gems = Instance.new("IntValue")
		Gems.Name = "Gems"
		Gems.Value = values and values.Gems
		Gems.Parent = leaderstats
	else
		warn(values)
	end
end)

local function saveData(player)
	local leaderstats = player:FindFirstChild("leaderstats")

	if leaderstats then
		local success, result = pcall(dataStore.SetAsync, dataStore, player.UserId, {
			Coins = leaderstats.Coins.Value,
			Gems = leaderstats.Gems.Value
		})

		if not success then warn(result) end
	end
end

Players.PlayerRemoving:Connect(saveData)

if RunService:IsStudio() then
	game:BindToClose(function()
		task.wait(4)
	end)
else
	game:BindToClose(function()
		local x, y = 0, 0

		for _, player in Players:GetPlayers() do
			x += 1

			coroutine.wrap(function()
				saveData(player)

				y += 1
			end)()
		end

		repeat task.wait() until y == x
	end)
end

I also would like to mention, please don’t do:

It’s bad for performance setting using the parent argument of Instance.new unless you’re not changing any properties of the instance at all. It’s much better to do this instead:

local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player

Edit: I accidentally wrote UserID instead of UserId, capitalization is important :sweat_smile:

1 Like

alright, i will try to use the code next day(in my country its night). and also thanks for the suggestion!
i will probably not post until tommorow afternoon in my country.

2 Likes

i have 2 questions.

  1. what if i wanted to move the gems and coins to not show in the leaderboard? do i need to change something?
  2. how do i add more values? for example, killcount?
1 Like
  1. You can either store the values inside of a table for each different player, or in a module, or in an object value for each player which I don’t recommend for performance reasons (unless you want to access them from different scripts)

  2. The same would apply for any new values you’d like to add to your game, but remember to add them to this table else they won’t be saved:

local success, result = pcall(dataStore.SetAsync, dataStore, player.UserId, {
	Coins = leaderstats.Coins.Value,
	Gems = leaderstats.Gems.Value
})

Edit: @Xxmaster_farterxX I added more info :smile:

1 Like

wait, it doesent work. what do i do? i changed the coins numvalue to 100 and when i rejoin its still 0. does this code only works ingame?

1 Like

How does your script currently look like?

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

local dataStore = DataStoreService:GetDataStore("PlayerData") -- You can rename this if you want

Players.PlayerAdded:Connect(function(player)
	local success, values = pcall(dataStore.GetAsync, dataStore, player.UserId)

	if success then
		local leaderstats = Instance.new("Folder")
		leaderstats.Name = "leaderstats"
		leaderstats.Parent = player

		local Coins = Instance.new("IntValue")
		Coins.Name = "Coins"
		Coins.Value = values and values.Coins
		Coins.Parent = leaderstats

		local Gems = Instance.new("IntValue")
		Gems.Name = "Gems"
		Gems.Value = values and values.Gems
		Gems.Parent = leaderstats
	else
		warn(values)
	end
end)

local function saveData(player)
	local leaderstats = player:FindFirstChild("leaderstats")

	if leaderstats then
		local success, result = pcall(dataStore.SetAsync, dataStore, player.UserId, {
			Coins = leaderstats.Coins.Value,
			Gems = leaderstats.Gems.Value
		})

		if not success then warn(result) end
	end
end

Players.PlayerRemoving:Connect(saveData)

if RunService:IsStudio() then
	game:BindToClose(function()
		task.wait(4)
	end)
else
	game:BindToClose(function()
		local x, y = 0, 0

		for _, player in Players:GetPlayers() do
			x += 1

			coroutine.wrap(function()
				saveData(player)

				y += 1
			end)()
		end

		repeat task.wait() until y == x
	end)
end

How did you change the coin’s value?

i just changed it manually by retyping the numvalue inside my character, it shows 100 in the leaderboard
before i left

I don’t recommend storing num values inside of the character, so store them inside the player instead and do this:

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

local dataStore = DataStoreService:GetDataStore("PlayerData") -- You can rename this if you want

local canSave = {}

Players.PlayerAdded:Connect(function(player)
	local success, values = pcall(dataStore.GetAsync, dataStore, player.UserId)

	if success then
		local Coins = Instance.new("IntValue")
		Coins.Name = "Coins"
		Coins.Value = values and values.Coins
		Coins.Parent = player

		local Gems = Instance.new("IntValue")
		Gems.Name = "Gems"
		Gems.Value = values and values.Gems
		Gems.Parent = player

		canSave[player] = true
	else
		warn(values)
	end
end)

local function saveData(player)
	if canSave[player] then
		local success, result = pcall(dataStore.SetAsync, dataStore, player.UserId, {
			Coins = player.Coins.Value,
			Gems = player.Gems.Value
		})

		canSave[player] = nil

		if not success then warn(result) end
	end
end

Players.PlayerRemoving:Connect(saveData)

if RunService:IsStudio() then
	game:BindToClose(function()
		task.wait(4)
	end)
else
	game:BindToClose(function()
		local x, y = 0, 0

		for _, player in Players:GetPlayers() do
			x += 1

			coroutine.wrap(function()
				saveData(player)

				y += 1
			end)()
		end

		repeat task.wait() until y == x
	end)
end		coroutine.wrap(function()
				saveData(player)

				y += 1
			end)()
		end

		repeat task.wait() until y == x
	end)
end

Edit: @Xxmaster_farterxX I added an important line to the code now that can prevent an issue from showing up in the future

it still doesent work. let me check all of my scripts that is maybe setting it to 0

Do note that when changing values manually during play-testing, you’ll need to switch to the server side by clicking this button in the TEST tab:


It needs to say Current: Server before you change the value, else the server won’t see it change

1 Like

wait, there is a error that says unkown global: player
Screenshot 2024-01-11 171538

At what line is the error occuring?

Edit: Change it to:

coroutine.wrap(function(player)
	saveData(player)

	y += 1
end)(player)
1 Like