If you simply use the data store service, your Roblox in-game data may be lost for various reasons. So we use DataStore2 or ProfileService. Here I will talk about ProfileService.
ProfileService is a large module of approximately 2500 lines. If you are using it for the first time, various tasks such as creating data templates, loading, updating, saving, and releasing profiles may seem very difficult. So, I am using another ProfileServiceManager module on top of ProfileService.
(This is ProfileServiceManager module script asset link)
There are a total of 5 functions that users use in the ProfileServiceManager module. There is one profile template dictionary variable and four functions ReleaseProfile, GetProfile, UpdateProfile, and SaveProfile.
1. Setup
First, change the name of the data store before saving the data. Then, write the data to be saved in the profile template as a dictionary.
2. Load data
Now let’s load the data.
local Players = game:GetService("Players")
local ProfileServiceManager = require(game.ServerScriptService.ProfileServiceManager)
workspace.Part.Touched:Connect(function(hit)
local humanoid = hit.Parent:FindFirstChild("Humanoid")
if humanoid then
local player = Players:GetPlayerFromCharacter(hit.Parent)
local profile = ProfileServiceManager:GetProfile(player)
while profile == nil do
profile = ProfileServiceManager:GetProfile(player)
end)
end)
When a player is added, ProfileServiceManager connects directly to the Roblox database to retrieve the player’s data. And save the data in the profiles dictionary. Therefore, when using the GetProfile function, it does not matter if you call it multiple times.
3. Change data
When changing data, just change the values ​​of the keys in the received profile.Data dictionary. Then call the UpdateProfile function to update the profile.
local Players = game:GetService("Players")
local ProfileServiceManager = require(game.ServerScriptService.ProfileServiceManager)
workspace.Part.Touched:Connect(function(hit)
local humanoid = hit.Parent:FindFirstChild("Humanoid")
if humanoid then
local player = Players:GetPlayerFromCharacter(hit.Parent)
local profile = ProfileServiceManager:GetProfile(player)
while profile == nil do
profile = ProfileServiceManager:GetProfile(player)
end)
profile.Data.Coin += 1
ProfileServiceManager:UpdateProfile(player, "Coin", profile.Data.Coin)
end)
end)
If the value of profile.Data is
{
Item = {
Count = 0
}
}
and count has been modified, “Item”, is used as the key.
ProfileServiceManager:UpdateProfile(player, "Item", profile.Data.Item)
Additionally, you can register keys such as exp where the number must not be small by editing the “if” code of the UpdateProfile function in the ProfileServiceManager module.
4. Save data
When saving data, you can use the SaveProfile function.
local Players = game:GetService("Players")
local ProfileServiceManager = require(game.ServerScriptService.ProfileServiceManager)
workspace.Part.Touched:Connect(function(hit)
local humanoid = hit.Parent:FindFirstChild("Humanoid")
if humanoid then
local player = Players:GetPlayerFromCharacter(hit.Parent)
local profile = ProfileServiceManager:GetProfile(player)
while profile == nil do
profile = ProfileServiceManager:GetProfile(player)
end)
profile.Data.Coin += 1
ProfileServiceManager:UpdateProfile(player, "Coin", profile.Data.Coin)
-- save data immediately if the data is import
ProfileServiceManager:SaveProfile(player)
end)
end)
-- every 5 min save data
coroutine.wrap(function()
while wait(300) then
for _, player:Player in ipairs(Players:GetPlayers) do
ProfileServiceManager:SaveProfile(player)
end)
end)
end)
To save data efficiently, you can save it automatically every few seconds, or save it immediately for important data.
5. Save data when player removing
Lastly, you can add code that saves data when the player exits.
local Players = game:GetService("Players")
local ProfileServiceManager = require(game.ServerScriptService.ProfileServiceManager)
workspace.Part.Touched:Connect(function(hit)
local humanoid = hit.Parent:FindFirstChild("Humanoid")
if humanoid then
local player = Players:GetPlayerFromCharacter(hit.Parent)
local profile = ProfileServiceManager:GetProfile(player)
while profile == nil do
profile = ProfileServiceManager:GetProfile(player)
end)
profile.Data.Coin += 1
ProfileServiceManager:UpdateProfile(player, "Coin", profile.Data.Coin)
-- save data immediately if the data is import
ProfileServiceManager:SaveProfile(player)
end)
end)
-- every 5 min save data
coroutine.wrap(function()
while wait(300) then
for _, player:Player in ipairs(Players:GetPlayers) do
ProfileServiceManager:SaveProfile(player)
end)
end)
end)
Players.PlayerRemoving:Connect(function(player)
-- give pannalty
local profile = ProfileServiceManager:GetProfile(player)
while profile == nil do
profile = ProfileServiceManager:GetProfile(player)
end)
profile.Data.Coin -= 100
ProfileServiceManager:UpdateProfile(player, "Coin", profile.Data.Coin)
-- save data
ProfileServiceManager:SaveProfile(player)
ProfileServiceManager:ReleaseProfile(player)
end)
The reason for separating this code from the module is so that we can implement a penalty if the player leaves the game midway.
That’s it. I hope this tutorial helps you safely store the data of players playing your game. Thank you for reading.