Easy to Set-up Datastore Tutorial

Hello, I am here today to show u how to make a simple datastore I learned from Kitrank

Firstly, insert a Script inside ServerScriptService. Then insert the following line:

local DSS = game:GetService("DataStoreService")

We have to get the DataStoreService before we can call it. So we created a variable called DSS, short for DataStoreService, which is what we want, something short to reference, instead of having to say game:GetService(“DataStoreService”) every single time.
Next, we insert this block of code, which runs when the Player and Player’s Character are added. Basically when someone first joins the game, it will run whatever code we put inside it and it will happen for every player.

local DSS = game:GetService("DataStoreService")

game.Players.PlayerAdded:Connect(function(Player)
Player.CharacterAdded:Connect(function(Character)
  	local Folder = Instance.new("Folder")
  	Folder.Name = "Data"
  	Folder.Parent = Player
end)
end)

We are creating a new Folder object, naming it Data (where we will store our data values), and placing it inside the Player.

Now we will instance/create an IntValue , call it Cash , set the default value to 0, and place it inside the Data folder.

local DSS = game:GetService("DataStoreService")

game.Players.PlayerAdded:Connect(function(Player)
Player.CharacterAdded:Connect(function(Character)
  	local Folder = Instance.new("Folder")
  	Folder.Name = "Data"
  	Folder.Parent = Player
  	local Cash = Instance.new("IntValue")
  	Cash.Name = "Cash"
  	Cash.Parent = Player.Data
  	Cash.Value = 0
end)
end)

Now we’re going to go back near the top of the script under where we made the DSS variable and create the Data Store for our Cash:

local DSS = game:GetService("DataStoreService")

local PlayerCash = DSS:GetDataStore("Cash")

game.Players.PlayerAdded:Connect(function(Player)
Player.CharacterAdded:Connect(function(Character)
	local Folder = Instance.new("Folder")
	Folder.Name = "Data"
	Folder.Parent = Player
	local Cash = Instance.new("IntValue")
	Cash.Name = "Cash"
	Cash.Parent = Player.Data
	Cash.Value = 0
end)
end)

We just created a Data Store, but we still need to make it load and save. You can change the variable PlayerCash and the “Cash” text inside the quotation marks. Now on to loading the Data Store whenever the Player joins the game:

local DSS = game:GetService("DataStoreService")

local PlayerCash = DSS:GetDataStore("Cash")

game.Players.PlayerAdded:Connect(function(Player)
Player.CharacterAdded:Connect(function(Character)
	local Folder = Instance.new("Folder")
	Folder.Name = "Data"
	Folder.Parent = Player
	local Cash = Instance.new("IntValue")
	Cash.Name = "Cash"
	Cash.Parent = Player.Data
  	Cash.Value = PlayerCash:GetAsync(Player.userId) or 0
end)
end)

Now where it sets our Cash value to 0 by default, we will make it load our Cash OR set it to 0 by default. If the player has no save, it will load what they had before, otherwise start at 0 (or whatever you prefer). Now on to saving:

local DSS = game:GetService("DataStoreService")

local PlayerCash = DSS:GetDataStore("Cash")

game.Players.PlayerAdded:Connect(function(Player)
Player.CharacterAdded:Connect(function(Character)
  	local Folder = Instance.new("Folder")
  	Folder.Name = "Data"
  	Folder.Parent = Player
  	local Cash = Instance.new("IntValue")
  	Cash.Name = "Cash"
  	Cash.Parent = Player.Data
  	Cash.Value = PlayerCash:GetAsync(Player.userId) or 0

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

  	end)

First, we’re going to add another function at the bottom (inside the player/character added function) which will automatically run right before the Player leaves the game and save our Cash . Then:

local DSS = game:GetService("DataStoreService")

local PlayerCash = DSS:GetDataStore("Cash")

game.Players.PlayerAdded:Connect(function(Player)
Player.CharacterAdded:Connect(function(Character)
	local Folder = Instance.new("Folder")
	Folder.Name = "Data"
	Folder.Parent = Player
	local Cash = Instance.new("IntValue")
	Cash.Name = "Cash"
	Cash.Parent = Player.Data
	Cash.Value = PlayerCash:GetAsync(Player.userId) or 0

	game.Players.PlayerRemoving:connect(function(Player)
		PlayerCash:SetAsync(Player.userId, Cash.Value)
	end)
end)
end)

You successfully created a value to save, and made it save/load whenever the player joins/leaves. Congratulations! Additionally, if you want your data to save automatically every set interval, you can do this:

local DSS = game:GetService("DataStoreService")

local PlayerCash = DSS:GetDataStore("Cash")

game.Players.PlayerAdded:Connect(function(Player)
Player.CharacterAdded:Connect(function(Character)
	local Folder = Instance.new("Folder")
	Folder.Name = "Data"
	Folder.Parent = Player
	local Cash = Instance.new("IntValue")
	Cash.Name = "Cash"
	Cash.Parent = Player.Data
	Cash.Value = PlayerCash:GetAsync(Player.userId) or 0

	game.Players.PlayerRemoving:connect(function(Player)
		PlayerCash:SetAsync(Player.userId, Cash.Value)
	end)

	while true do
		wait(300)
		PlayerCash:SetAsync(Player.userId, Cash.Value)
	end
end)
end)

Replace the number inside the wait() with the time you want (in seconds) in-between each auto save. Note: There are limits to how frequently you can make data store requests (link here for specific limitations), so do not auto save too fast.

To test the Data Store, test run the game in Stuido, then manually change the value of your Cash in your Player. Stop the test run after changing the value yourself, then test run again to see that it saved what you changed it to. That’s it for this tutorial, hope it helped! :smile:

15 Likes

This is a nice, well-written tutorial, and does work nicely.

However, I don’t understand why you made the event Player.CharacterAdded:Connect(function(Character) handle the datastores.
If the player were to die, their stats would be re-created.

EDIT: oops wrong event, meant the CharacterAdded event

1 Like

A great tutorial. The only thing you did wrong is not using protective call functions while GetAsync and SetAsync. This is to make sure that DSS doesn’t get any stupid errors.

1 Like

I’m sorry to say but that is a giant memory leak.

game.Players.PlayerAdded:Connect(function(Player)
Player.CharacterAdded:Connect(function(Character)
	local Folder = Instance.new("Folder")
	Folder.Name = "Data"
	Folder.Parent = Player
	local Cash = Instance.new("IntValue")
	Cash.Name = "Cash"
	Cash.Parent = Player.Data
	Cash.Value = PlayerCash:GetAsync(Player.userId) or 0

	game.Players.PlayerRemoving:connect(function(Player)
		PlayerCash:SetAsync(Player.userId, Cash.Value)
	end)
end)

Look at how many connections you’re making :eyes:.

You should also wrap SetAsync and GetAsync in a pcall.

PS: This shouldn’t be used for game production, consider looking into a few more resources or looking at already existing open sourced datastores before making another one.

5 Likes

Well that’s completely not true, game.Players.PlayerAdded:Connect(function(player) only fires when a player joins and not when a player respawns but here the wrapping of code is wrong therefore what you have said is somewhat Correct

1 Like

Your tutorial is good, but your explanation is pretty opaque.

You kept on saying “we will now get/load/save the data” without saying what method or what you have added. Explanation is key to a good tutorial.

I suggest you say what you have added in the code and explain what you added (like what GetAsync does, what SetAsync does, etc.)

That was a mistake on my end, I typed out the PlayerAdded event instead of the CharacterAdded event.

3 Likes

Great tutorial, but what I would change is instead of using SetAsync to save the player’s data I would use an alternative to that because using it myself there are many problems with it, and the user can lose data.

Other than that amazing tutorial very well explained.

1 Like

Thanks :grin: I will update the tutorial accordingly

I would also recommend you to add BindToClose and proper error handling with pcalls :slight_smile:

1 Like

isn’t this on the roblox fandom???

1 Like

I don’t know, I just researched data-store tutorials and basically put it together in my best words/explanation :stuck_out_tongue: