Save your player data with ProfileService! (DataStore Module)

After a recent update you can access the live DataStore keys if you enable Roblox API access - see ProfileService wiki troubleshooting section. This functionality might change a bit in the near future.

2 Likes

You’ve made a mistake somewhere. Familiarize with ModuleScript documentation and fix your code.

1 Like

I might sound a bit oblivious in this post, but I just want to double check to make sure I have all the details down before I make a choice to switch.

Does ProfileService do fully automatic saving assuming I’m using the module as intended with the methods in the examples?

What’s the ideal data replication setup for ProfileService? I’ve been trying to brainstorm the lightest, most network efficient solution, but I’m having trouble coming up with something conclusive.

  • Ideally, there would be some way of the client to request/read their data without having to call any RemoteFunctions? (the server would update something they can read when their data changes?)

Thanks.

Not any that I know of, ProfileService is a module that handles Data Saving not Data Replication, you can make a system for that however you’d like to. It’s really not that hard nor that many options to choose from, you either use ValueBase or Remotes for it.

This is probably due to preference and different games have different ways of dealing with Replication, the Author doesn’t want to interfere with that freedom.

You can read more about which way to do it on the Forum, there are many Posts available

maybe in the future we’ll have an add on for the Module :wink:

1 Like

I’m aware the ProfileService is for data saving, I was just wondering if there was any suggested best way to go about it (similar to the data handler example posted). I’ll get to looking around even more.

How would i get data from the same datastore from another script?
for example a main script loads the data first to give daily rewards and to process gifts, then another script that is suppose to read the same Profile for if they own a weapon to display, doing this is throwing an error saying that [[ProfileService]: Profile of ProfileStore “PlayerData” with key “Player_248033263” is already loaded in this session], am i doing smthing wrong? or do i have to get the data in another way

2 Likes

You can use ModuleScripts as they return the same Data (cache) to all Scripts within the same context.

In general you do not what to load a profile twice in the same game server (JobId)

You can learn more here:

2 Likes

Hello, I have a question on my mind, after doing the Profile: Relase () operation, will the Profile = nil?

The profile itself shouldn’t be nil, but I believe all operations will fail since the session lock isn’t active for that server instance anymore. You should typically refrain from using the profile after you’re done with it anyway. If you have it in a cache, remove it from the cache when you Release it.

1 Like

This was really helpful thank you.

1 Like

image

local DataManager = require(ModuleFolder:WaitForChild('DataManager'))

It fails to load in I’m using the code That Loleris provided
ModuleFolder is just ReplicatedStorage – > Folder called Modules – > Then the module

You should always make sure your own code is completely error-free, especially if the error stack trace does not start from the ProfileService module itself.

Start with solving this error:
image
You can find resources how to fix errors like this by googling this specific message, OR checking the documentation related to what you’re doing.

3 Likes

I am interested in this plugin after I had a duplication occur on one of my projects that used regular datastores. The method was:
You have two players on the same server, player A and player B
Both players have 5 gold coins.
Player A gives player B 5 gold coins.
Player A now has 0 gold coins, Player B now has 10 gold coins
Player B leaves the server, saving his account’s 10 gold coins on logout
The server crashes before the autosave tick
Player A, due to failure to autosave, now has those 5 gold coins back. Player B, since the server saved his logout, has 10 coins.
Now there is a total of 15 coins in circulation because of a crash-dupe

Does this type of duplication occur natively with this plugin? I haven’t gotten around to fully testing it out yet.

I don’t believe it’s possible to make a fix for this, as apparently BindToClose doesn’t fire on server crash. The best way would be to improve your code so that the server won’t crash unless it is actually Roblox’s fault.

You said you wait at least 80 seconds before stealing a session. Is there a reason why you wait such a long time?

1 Like

Your server could be lagging / DataStore API might have problems saving / Server might’ve crashed. Until a Profile is properly released on the remote server, ProfileService does not know which of those scenarios are true and won’t rush to steal the Profile when a remote session lock is still present.

You can alter this behaviour with the new ”Steal” argument if you have a way to find out whether the remote server that owns the profile is alive or not. If Roblox servers don’t crash constantly and profiles always save successfuly on release, then the 80 second wait will occur rarely.

1 Like

[08/23/2020] ProfileStore:WipeProfileAsync(), ProfileStore.Mock and HeartbeatWait


It is now possible to use ProfileService in mock DataStore mode while having Roblox API services enabled in studio - see ProfileStore.Mock.

local ProfileTemplate = {}
local GameProfileStore = ProfileService.GetProfileStore(
  "PlayerData",
  ProfileTemplate
)

local LiveProfile = GameProfileStore:LoadProfileAsync(
  "profile_key",
  "ForceLoad"
)
local MockProfile = GameProfileStore.Mock:LoadProfileAsync(
  "profile_key",
  "ForceLoad"
)
print(LiveProfile ~= MockProfile) --> true

-- When done using mock profile on live servers: (Prevent memory leak)
MockProfile:Release()
GameProfileStore.Mock:WipeProfile("profile_key")
-- You don't really have to wipe mock profiles in studio testing

ProfileService now has ProfileStore:WipeProfileAsync() functionality for easier erasure of user data.


All wait() occurences have been replaced with a Heartbeat-based waiting function.

11 Likes

@oniich_n There you go :smiley:

This is the code part in the documentation that is relevant to you:

local RunService = game:GetService("RunService")
local GameProfileStore = ProfileService.GetProfileStore("PlayerData", ProfileTemplate)
if RunService:IsStudio() == true then
  GameProfileStore = GameProfileStore.Mock
end
4 Likes

Awesome! Thank you so much :smiley:

How difficult would it be to convert my game’s current datastore setup into this without losing existing player data?