[Tutorial] How to use Profile Service easily

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.

1 Like

As a person who uses Profile Service on nearly all my games, this is not a bad way to use and set it up, however there are more versatile ways for easier customisation but there are many methods to do this so I give it my approval.

1 Like