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

My datastore wont work for properly and the output does not help, how do i fix this?

Here is the code, it's a regular script!

--// Variables \\--
local DataStoreService = game:GetService("DataStoreService")
local ds1 = DataStoreService:GetDataStore("CashDATA")
local ds2 = DataStoreService:GetDataStore("SoulsDATA")
local ds3 = DataStoreService:GetDataStore("isNewDATA")
local ds4 = DataStoreService:GetDataStore("swordDATA")
local ds5 = DataStoreService:GetDataStore("shurikenDATA")

--// Functions \\--

function giveStats(player)
	local Stats = Instance.new("Folder", player)
	Stats.Name = "Stats"
	
	local isNew = Instance.new("BoolValue", Stats)
	isNew.Name = "isNew"
	isNew.Value = ds3:GetAsync(player.UserId) or true
	
	local Coins = Instance.new("IntValue", Stats)
	Coins.Name = "Coins"
	Coins.Value = ds1:GetAsync(player.UserId) or 0
	
	local Souls = Instance.new("IntValue", Stats)
	Souls.Name = "Souls"
	Souls.Value = ds2:GetAsync(player.UserId) or 0
	
	local streak = Instance.new("IntValue", Stats)
	streak.Name = "currentStreak"
	streak.Value = 0
	
	local currentSword = Instance.new("StringValue", Stats)
	currentSword.Name = "currentSword"
	currentSword.Value = ds4:GetAsync(player.UserId) or "StarterSword"
	
	local currentShuriken = Instance.new("StringValue", Stats)
	currentShuriken.Name = "currentShuriken"
	currentShuriken.Value = ds5:GetAsync(player.UserId) or "StarterShuriken"
	
	if isNew.Value == true then
		currentShuriken.Value = "StarterShuriken"
		currentSword = "StarterKatana"
		isNew.Value = false
	end
	while true do
		wait(30)
			local stats = player:WaitForChild("Stats")
		ds1:SetAsync(player.UserId, stats.Coins.Value)
		ds2:SetAsync(player.UserId, stats.Souls.Value)
		ds3:SetAsync(player.UserId, stats.isNew.Value)
		ds4:SetAsync(player.UserId, stats.currentSword.Value)
		ds5:SetAsync(player.UserId, stats.currentShuriken.Value)
	end
end

game.Players.PlayerAdded:Connect(giveStats)

game.Players.PlayerRemoving:Connect(function(player)
	local stats = player:WaitForChild("Stats")
	ds1:SetAsync(player.UserId, stats.Coins.Value)
	ds2:SetAsync(player.UserId, stats.Souls.Value)
	ds3:SetAsync(player.UserId, stats.isNew.Value)
	ds4:SetAsync(player.UserId, stats.currentSword.Value)
	ds5:SetAsync(player.UserId, stats.currentShuriken.Value)
end)
	

I'm new with datastores just letting you know! :)

2 answers

Datastores

Datastores are a way of accessing data and saving it, so players can continue their progress on a game. Datastores are(in my opinion) the most important thing in a game. Faulty datastores are something that can cause major problems in a game. Avoiding that is very important.

Let me explain some basic things.

• Roblox Datastores can fail at any time. There is nothing we can do about it. But we can try to prevent these to the furthest possibility.

• PCalls(Protected Calls) is a way of handling errors from code. It is recommended to only use these when accessing outside of Roblox.

• Try to save everything in one Datastore. It is a wise decision. There may be certain occasions that you MAY have to use more than one. But that is pretty uncommon.

• Datastores can be accessed anywhere inside of the game including all the places in the game.

I assume that you read those, so we can move on.

Using Tables

Tables are an important and very useful way to organize and store data. Let's start by creating our table to organize data.

local dataTable = {
	Gold = 0;
	Gems = 0;
}

As you can see, I made two different currency. One gold and one gems. I set both of those to "0". Just keep this in your script and we will use it later.

Creating Datastores

To get a Datastore, we need to first get the DataStoreService by using ":GetService()".

local dataTable = {
	Gold = 0;
	Gems = 0;
}

local DataService = game:GetService("DataStoreService") -- Gets the DataStoreService.

Next, let's get a Datastore by using ":GetDataStore()").

local dataTable = {
	Gold = 0;
	Gems = 0;
}

local DataService = game:GetService("DataStoreService")
local myDatastore = DataService:GetDataStore("ThisIsMyData123") --  Gets the Datastore.

As you can see inside of the "()" for ":GetDataStore()", that is the name of your Datastore. You can name it to anything you want.

Now, let's create a simple leaderstats script. I assume you know how to create one.

local dataTable = {
	Gold = 0;
	Gems = 0;
}

local DataService = game:GetService("DataStoreService")
local myDatastore = DataService:GetDataStore("ThisIsMyData123") --  Gets the Datastore.

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

	local stats = Instance.new("Folder") -- Creates a new folder which will be our stats.
	stats.Name = "leaderstats"
	stats.Parent = player

	local gold = Instance.new("IntValue") -- Creates our currency "Gold".
	gold.Name = "Gold"
	gold.Value = 0
	gold.Parent = stats
	
	local gems = Instance.new("IntValue") -- Creates our currency "Gems".
	gems.Name = "Gems"
	gems.Value = 0
	gems.Parent = stats

end)

There we go. We made a simple leaderstats.

Next, we are going to check if the player joined has data. If the player does not, we will make new data for him using the dataTable. We will also use a method called ":GetAsync()". This will check if we have data. It also needs the key to access which is basically a unique code to access a player's data.


local dataTable = {
	Gold = 0;
	Gems = 0;
}

local DataService = game:GetService("DataStoreService")
local myDatastore = DataService:GetDataStore("ThisIsMyData123") --  Gets the Datastore.

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

	local stats = Instance.new("Folder") -- Creates a new folder which will be our stats.
	stats.Name = "leaderstats"
	stats.Parent = player

	local gold = Instance.new("IntValue") -- Creates our currency "Gold".
	gold.Name = "Gold"
	gold.Value = 0
	gold.Parent = stats
	
	local gems = Instance.new("IntValue") -- Creates our currency "Gems".
	gems.Name = "Gems"
	gems.Value = 0
	gems.Parent = stats
	
	local checkData = myDatastore:GetAsync(player.UserId) -- We are using player.UserId as the key because it is unique to each player. It also makes sure that if someone changes their username, their data will be the same.

	if checkData then -- Simple if statement to check if there is data.
		-- We are going to be setting the values for each currency if there is data. This will make sense later on.
		gems.Value = checkData.Gems 
		gold.Value = checkData.Gold
	else
		checkData = dataTable -- setting checkData to our datatable since checkData is nil.
		myDatastore:SetAsync(player.UserId, checkData) -- This is the method for saving ":SetAsync()". It will save a new dataTable to the player. The first parameter is the key that we said was the UserId. The second parameter is the Data we are saving. This is the table.

	end
end)

Now, we have a basic data retriever. Let's work on the saving side now. We will be using the method ":SetASync()". The first parameter is the key that we said was the UserId. The second parameter is the Data we are saving.


local dataTable = {
	Gold = 0;
	Gems = 0;
}

local DataService = game:GetService("DataStoreService")
local myDatastore = DataService:GetDataStore("ThisIsMyData123") --  Gets the Datastore.

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

	local stats = Instance.new("Folder") -- Creates a new folder which will be our stats.
	stats.Name = "leaderstats"
	stats.Parent = player

	local gold = Instance.new("IntValue") -- Creates our currency "Gold".
	gold.Name = "Gold"
	gold.Value = 0
	gold.Parent = stats
	
	local gems = Instance.new("IntValue") -- Creates our currency "Gems".
	gems.Name = "Gems"
	gems.Value = 0
	gems.Parent = stats
	
	local checkData = myDatastore:GetAsync(player.UserId) -- We are using player.UserId as the key because it is unique to each player. It also makes sure that if someone changes their username, their data will be the same.

	if checkData then -- Simple if statement to check if there is data.
		-- We are going to be setting the values for each currency if there is data. This will make sense later on.
		gems.Value = checkData.Gems 
		gold.Value = checkData.Gold
	else
		checkData = dataTable -- setting checkData to our datatable since checkData is nil.
		myDatastore:SetAsync(player.UserId, checkData) -- This is the method for saving ":SetAsync()". It will save a new dataTable to the player. The first parameter is the key that we said was the UserId. The second parameter is the Data we are saving. This is the table.

	end
end)

game.Players.PlayerRemoving:Connect(function(player)
	dataTable.Gold = player.leaderstats.Gold.Value -- We will be setting the "Gold" in the dataTable to the "Gold" IntValue inside our leaderstats.

	dataTable.Gems = player.leaderstats.Gems.Value  -- same thing, but with gold
	
	myDatastore:SetAsync(player.UserId, dataTable) -- We are saving the dataTable after we have set the values.

	
end)

Now, we have a basic working datastore. It saves and retrieves. But this isn't a good datastore. We need to use "PCalls" or Protected Calls like I said at the beginning because Roblox Datastores can fail. If they do, we do not want them to break our script. In the way we are using PCalls, It has two returns. Success and ErrorMessage. If the data was saved succesfully, it returns success. If not, it returns the Error Message.


local dataTable = {
	Gold = 0;
	Gems = 0;
}

local DataService = game:GetService("DataStoreService")
local myDatastore = DataService:GetDataStore("ThisIsMyData123") --  Gets the Datastore.

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

	local stats = Instance.new("Folder") -- Creates a new folder which will be our stats.
	stats.Name = "leaderstats"
	stats.Parent = player

	local gold = Instance.new("IntValue") -- Creates our currency "Gold".
	gold.Name = "Gold"
	gold.Value = 0
	gold.Parent = stats
	
	local gems = Instance.new("IntValue") -- Creates our currency "Gems".
	gems.Name = "Gems"
	gems.Value = 0
	gems.Parent = stats
	
	local checkData 
	 
	local success, errorMessage = pcall(function()
		checkData = myDatastore:GetAsync(player.UserId) -- We are using player.UserId as the key because it is unique to each player. It also makes sure that if someone changes their username, their data will be the same.
		
	end)

	if checkData and success then -- Simple if statement to check if there is data.
		-- We are going to be setting the values for each currency if there is data. This will make sense later on.
		gems.Value = checkData.Gems 
		gold.Value = checkData.Gold
	else
		checkData = dataTable -- setting checkData to our datatable since checkData is nil.
		local success, errorMessage = pcall(function() 					myDatastore:SetAsync(player.UserId, checkData) -- This is the method for saving ":SetAsync()". It will save a new dataTable to the player. The first parameter is the key that we said was the UserId. The second parameter is the Data we are saving. This is the table.
		end)
		
		if success then
			print("Data saved successfully")
		else
			print("Error occurred while saving Data.")
			warn(errorMessage)
		end
	elseif not success then
		print("Data error while loading")
	end
end)

game.Players.PlayerRemoving:Connect(function(player)
	dataTable.Gold = player.leaderstats.Gold.Value -- We will be setting the "Gold" in the dataTable to the "Gold" IntValue inside our leaderstats.

	dataTable.Gems = player.leaderstats.Gems.Value  -- same thing, but with gold
	
	local success, errorMessage = pcall(function() 
		myDatastore:SetAsync(player.UserId, dataTable) -- We are saving the dataTable 	after we have set the values.
	end)

	if success then
		print("Data saved successfully")
	else
		print("Error occurred while saving Data.")
		warn(errorMessage)
	end

end)

Now we have a really good and efficient Datastore. I hope this help anyone that is reading. I am not the best at explaining and writing things, but just try to understand haha. Thanks!

3 comments

0

nice

0

thanks alphexus, your a good friend. When im finished rewriting my code ima answer the question!

0

this is like a guide but a scriptinghelpers answer

For some reason it did not work, please point out my mistakes!

local dataTable = {
	isNew = true;
	Coins = 0;
	Souls = 0;
	currentSword = "StarterSword";
	currentShuriken = "StarterShuriken";
}

local DataService = game:GetService("DataStoreService")
local DS = DataService:GetDataStore("MainDS")

game.Players.PlayerAdded:Connect(function(player)
	local stats = Instance.new("Folder", player)
	stats.Name = "Stats"
	
	local isNew = Instance.new("BoolValue", stats)
	isNew.Name = "isNew"
	
	local Coins = Instance.new("IntValue", stats)
	Coins.Name = "Coins"
	Coins.Value = 0
	
	local Souls = Instance.new("IntValue", stats)
	Souls.Name = "Souls"
	Souls.Value = 0
	
	local currentSword = Instance.new("StringValue", stats)
	currentSword.Name = "currentSword"
	currentSword.Value = "StarterSword"
	
	local currentShuriken = Instance.new("StringValue", stats)
	currentShuriken.Name = "currentShuriken"
	currentShuriken.Value = "StarterShuriken"
	
	local streak = Instance.new("IntValue", stats)
	streak.Name = "streak"
	streak.Value = 0
	
	if isNew.Value == true then
		currentSword.Value = "StarterSword"
		currentShuriken.Value = "StarterShuriken"
		isNew.Value = false
	end
	
    local checkData 

    local success, errorMessage = pcall(function()
        checkData = DS:GetAsync(player.UserId)

    end)
	
	if checkData and success then
		isNew.Value = checkData.isNew
		Coins.Value = checkData.Coins
		Souls.Value = checkData.Souls
		currentSword.Value = checkData.currentSword
		currentShuriken.Value = checkData.currentShuriken
        checkData = dataTable
        local success, errorMessage = pcall(function()  
	   DS:SetAsync(player.UserId, checkData) 
        end)

        if success then
            print("Data saved successfully")
        else
            print("Error occurred while saving Data.")
            warn(errorMessage)
        end
    elseif not success then
        print("Data error while loading")
	end
end)

game.Players.PlayerRemoving:Connect(function(player)
	dataTable.isNew = player.Stats.isNew.Value
	dataTable.Coins = player.Stats.Coins.Value
	dataTable.Souls = player.Stats.Souls.Value
	dataTable.currentSword = player.Stats.currentSword.Value
	dataTable.currentShuriken = player.Stats.currentShuriken.Value

    local success, errorMessage = pcall(function() 
        DS:SetAsync(player.UserId, dataTable) -- We are saving the dataTable   after we have set the values.
    end)

    if success then
        print("Data saved successfully")
    else
        print("Error occurred while saving Data.")
        warn(errorMessage)
    end

end)

1 comment

0

Removes line 58 to 61.

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